Skip to content
Snippets Groups Projects
Verified Commit 318fd135 authored by Ernesto Rico Schmidt's avatar Ernesto Rico Schmidt
Browse files

feat: update serializers to use permissions

parent 1a8c0aca
No related branches found
No related tags found
No related merge requests found
......@@ -134,7 +134,6 @@ class UserSerializer(serializers.ModelSerializer):
@staticmethod
def get_is_privileged(obj: User) -> bool:
# return obj.groups.filter(name=settings.PRIVILEGED_GROUP).exists()
return obj.is_superuser
def create(self, validated_data):
......@@ -387,37 +386,27 @@ class HostSerializer(serializers.ModelSerializer):
return host
def update(self, instance, validated_data):
"""
Update and return an existing Host instance, given the validated data.
A `PermissionDenied` exception will be raised if the user is not privileged or the owner of
the host and has the permissions to edit the fields.
"""
"""Update and return an existing Host instance, given the validated data."""
user = self.context.get("request").user
# user_is_privileged = user.groups.filter(name=settings.PRIVILEGED_GROUP).exists()
user_is_owner = user in instance.owners.all()
user_edit_permissions = [
user_permissions = set(
permission.split("__")[-1]
for permission in user.get_all_permissions()
if permission.startswith("program.edit__host")
]
)
update_fields = set(validated_data.keys())
# Only superusers and owners of a host with edit permissions are allowed to update it
# Being a superuser overrides the ownership
if not (user.is_superuser or (user_is_owner and len(user_edit_permissions) > 0)):
# having the update_host permission overrides the ownership
if not (user.has_perm("program.update_host") or (user_is_owner and user_permissions)):
raise exceptions.PermissionDenied(detail="You are not allowed to update this host.")
# Only users with edit permissions are allowed to edit these fields
if "biography" in validated_data and "biography" not in user_edit_permissions:
raise exceptions.PermissionDenied(
detail="You are not allowed to edit the host’s biography."
)
if "name" in validated_data and "name" not in user_edit_permissions:
raise exceptions.PermissionDenied(
detail="You are not allowed to edit the host’s name."
)
# without the update_host permission, fields without edit permission are not allowed
if not user.has_perm("program.update_host") and (
not_allowed := update_fields.difference(user_permissions)
):
detail = {field: "You are not allowed to edit this field" for field in not_allowed}
raise exceptions.PermissionDenied(detail=detail)
if "biography" in validated_data:
instance.biography = validated_data.get("biography")
......@@ -425,27 +414,25 @@ class HostSerializer(serializers.ModelSerializer):
if "name" in validated_data:
instance.name = validated_data.get("name")
# Only update these fields if the user superuser, ignore otherwise
if user.is_superuser:
if "email" in validated_data:
instance.email = validated_data.get("email")
if "email" in validated_data:
instance.email = validated_data.get("email")
if "image" in validated_data:
instance.image = validated_data.get("image")
if "image" in validated_data:
instance.image = validated_data.get("image")
if "is_active" in validated_data:
instance.is_active = validated_data.get("is_active")
if "is_active" in validated_data:
instance.is_active = validated_data.get("is_active")
# optional nested objects
if links_data := validated_data.get("links"):
instance = delete_links(instance)
# optional many-to-many
if "owners" in validated_data:
instance.owners.set(validated_data.get("owners"))
for link_data in links_data:
HostLink.objects.create(host=instance, **link_data)
# optional nested objects
if "links" in validated_data:
instance = delete_links(instance)
# optional many-to-many
if "owners" in validated_data.get("owners"):
instance.owners.set(validated_data.get("owners", []))
for link_data in validated_data.get("links"):
HostLink.objects.create(host=instance, **link_data)
instance.updated_by = self.context.get("request").user.username
......@@ -610,45 +597,27 @@ class ShowSerializer(serializers.HyperlinkedModelSerializer):
return show
def update(self, instance, validated_data):
"""
Update and return an existing Show instance, given the validated data.
A `PermissionDenied` exception will be raised if the user is not privileged or the owner of
a show and has the permissions to edit the fields.
"""
"""Update and return an existing Show instance, given the validated data."""
user = self.context.get("request").user
# user_is_privileged = user.groups.filter(name=settings.PRIVILEGED_GROUP).exists()
user_is_owner = instance in user.shows.all()
user_edit_permissions = [
user_is_owner = user in instance.owners.all()
user_permissions = set(
permission.split("__")[-1]
for permission in user.get_all_permissions()
if permission.startswith("program.edit__show")
]
)
update_fields = set(validated_data.keys())
# Only superusers and owners of a show with edit permissions are allowed to update it
# Being a superuser overrides the ownership
if not (user.is_superuser or (user_is_owner and len(user_edit_permissions) > 0)):
# having update_show permission overrides the ownership
if not (user.has_perm("program.update_show") or (user_is_owner and user_permissions)):
raise exceptions.PermissionDenied(detail="You are not allowed to update this show.")
# Only users with edit permissions are allowed to update these fields
if "description" in validated_data and "description" not in user_edit_permissions:
raise exceptions.PermissionDenied(
detail="You are not allowed to edit the show’s description."
)
if "name" in validated_data and "name" not in user_edit_permissions:
raise exceptions.PermissionDenied(
detail="You are not allowed to edit the show’s name."
)
if (
"short_description" in validated_data
and "short_description" not in user_edit_permissions
# without the update_show permission, fields without edit permission are not allowed
if not user.has_perm("update_show") and (
not_allowed := update_fields.difference(user_permissions)
):
raise exceptions.PermissionDenied(
detail="You are not allowed to edit the show’s short description."
)
detail = {field: "You are not allowed to edit this field" for field in not_allowed}
raise exceptions.PermissionDenied(detail=detail)
if "description" in validated_data:
instance.description = validated_data.get("description")
......@@ -659,69 +628,67 @@ class ShowSerializer(serializers.HyperlinkedModelSerializer):
if "short_description" in validated_data:
instance.short_description = validated_data.get("short_description")
# Only update these fields if the user is superuser, ignore otherwise
if user.is_superuser:
if "cba_series_id" in validated_data:
instance.cba_series_id = validated_data.get("cba_series_id")
if "cba_series_id" in validated_data:
instance.cba_series_id = validated_data.get("cba_series_id")
if "default_playlist_id" in validated_data:
instance.default_playlist_id = validated_data.get("default_playlist_id")
if "default_playlist_id" in validated_data:
instance.default_playlist_id = validated_data.get("default_playlist_id")
if "email" in validated_data:
instance.email = validated_data.get("email")
if "email" in validated_data:
instance.email = validated_data.get("email")
if "funding_category" in validated_data:
instance.funding_category = validated_data.get("funding_category")
if "funding_category" in validated_data:
instance.funding_category = validated_data.get("funding_category")
if "image" in validated_data:
instance.image = validated_data.get("image")
if "image" in validated_data:
instance.image = validated_data.get("image")
if "internal_note" in validated_data:
instance.internal_note = validated_data.get("internal_note")
if "internal_note" in validated_data:
instance.internal_note = validated_data.get("internal_note")
if "is_active" in validated_data:
instance.is_active = validated_data.get("is_active")
if "is_active" in validated_data:
instance.is_active = validated_data.get("is_active")
if "is_public" in validated_data:
instance.is_public = validated_data.get("is_public")
if "is_public" in validated_data:
instance.is_public = validated_data.get("is_public")
if "logo" in validated_data:
instance.logo = validated_data.get("logo")
if "logo" in validated_data:
instance.logo = validated_data.get("logo")
if "predecessor" in validated_data:
instance.predecessor = validated_data.get("predecessor")
if "predecessor" in validated_data:
instance.predecessor = validated_data.get("predecessor")
if "slug" in validated_data:
instance.slug = validated_data.get("slug")
if "slug" in validated_data:
instance.slug = validated_data.get("slug")
if "type" in validated_data:
instance.type = validated_data.get("type")
if "type" in validated_data:
instance.type = validated_data.get("type")
# optional many-to-many
if "category" in validated_data:
instance.category.set(validated_data.get("category", []))
# optional many-to-many
if "category" in validated_data:
instance.category.set(validated_data.get("category", []))
if "hosts" in validated_data:
instance.hosts.set(validated_data.get("hosts", []))
if "hosts" in validated_data:
instance.hosts.set(validated_data.get("hosts", []))
if "language" in validated_data:
instance.language.set(validated_data.get("language", []))
if "language" in validated_data:
instance.language.set(validated_data.get("language", []))
if "music_focus" in validated_data:
instance.music_focus.set(validated_data.get("music_focus", []))
if "music_focus" in validated_data:
instance.music_focus.set(validated_data.get("music_focus", []))
if "owners" in validated_data:
instance.owners.set(validated_data.get("owners", []))
if "owners" in validated_data:
instance.owners.set(validated_data.get("owners", []))
if "topic" in validated_data:
instance.topic.set(validated_data.get("topic", []))
if "topic" in validated_data:
instance.topic.set(validated_data.get("topic", []))
# optional nested objects
if links_data := validated_data.get("links"):
instance = delete_links(instance)
# optional nested objects
if "links" in validated_data:
instance = delete_links(instance)
for link_data in links_data:
ShowLink.objects.create(show=instance, **link_data)
for link_data in validated_data.get("links"):
ShowLink.objects.create(host=instance, **link_data)
instance.updated_by = self.context.get("request").user.username
......@@ -1006,11 +973,7 @@ class NoteSerializer(serializers.ModelSerializer):
) + read_only_fields
def create(self, validated_data):
"""Create and return a new Note instance, given the validated data.
A `PermissionDenied` exception will be raised if the user is not privileged or the owner of
the show.
"""
"""Create and return a new Note instance, given the validated data."""
links_data = validated_data.pop("links", [])
......@@ -1022,15 +985,11 @@ class NoteSerializer(serializers.ModelSerializer):
show = validated_data["timeslot"].schedule.show
user = self.context.get("request").user
# user_is_privileged = user.groups.filter(name=settings.PRIVILEGED_GROUP).exists()
user_is_owner = user in show.owners.all()
# Only superusers and owners of a show are allowed to create a note
# Being a superuser overrides the ownership
if not (user.is_superuser or user_is_owner):
raise exceptions.PermissionDenied(
detail="You are not allowed to create a note for this show."
)
# Having the create_note permission overrides the ownership
if not (user.has_perm("program.create_note") or user_is_owner):
raise exceptions.PermissionDenied(detail="You are not allowed to create this note.")
# we derive `contributors`, `language` and `topic` from the Show's values if not set
contributors = validated_data.pop("contributors", show.hosts.values_list("id", flat=True))
......@@ -1058,19 +1017,13 @@ class NoteSerializer(serializers.ModelSerializer):
return note
def update(self, instance, validated_data):
"""Update and return an existing Note instance, given the validated data.
A `PermissionDenied` exception will be raised if the user is not privileged or the owner of
a show.
"""
"""Update and return an existing Note instance, given the validated data."""
user = self.context.get("request").user
# user_is_privileged = user.groups.filter(name=settings.PRIVILEGED_GROUP).exists()
user_is_owner = user in instance.timeslot.schedule.show.owners.all()
# Only superusers and owners of a show are allowed to update a note
# Being a superuser overrides the ownership
if not (user.is_superuser or user_is_owner):
# Having the update_note permission overrides the ownership
if not (user.has_perm("program.update_note") or user_is_owner):
raise exceptions.PermissionDenied(detail="You are not allowed to update this note.")
if "cba_id" in validated_data:
......@@ -1101,15 +1054,15 @@ class NoteSerializer(serializers.ModelSerializer):
if "language" in validated_data:
instance.language.set(validated_data.get("language", []))
# Only update this field if the user is superuser, ignore otherwise
if "topic" in validated_data and user.is_superuser:
# Only update this field if the user has the update_note permission, ignore otherwise
if "topic" in validated_data and user.has_perm("program.update_note"):
instance.topic.set(validated_data.get("topic", []))
# optional nested objects
if links_data := validated_data.get("links"):
if "links" in validated_data:
instance = delete_links(instance)
for link_data in links_data:
for link_data in validated_data.get("links"):
NoteLink.objects.create(note=instance, **link_data)
instance.updated_by = self.context.get("request").user.username
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment