Skip to content

Commit

Permalink
Refactor Project.set_permissions
Browse files Browse the repository at this point in the history
- Explicitly define allowed values
- Use a transaction, to ensure no inconsistent data
- Overwrite permissions, by deleting all existing first
  • Loading branch information
jjnesbitt committed Sep 30, 2024
1 parent 7bb8976 commit 61196f8
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 16 deletions.
35 changes: 22 additions & 13 deletions uvdat/core/models/project.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from django.contrib.auth.models import User
from django.contrib.gis.db import models as geo_models
from django.db import models
from django.db import models, transaction
from guardian.models import UserObjectPermission
from guardian.shortcuts import assign_perm

from .dataset import Dataset
Expand All @@ -12,19 +13,27 @@ class Project(models.Model):
default_map_zoom = models.IntegerField(default=10)
datasets = models.ManyToManyField(Dataset, blank=True)

def update_permissions(self, **kwargs):
for key, value in kwargs.items():
if not isinstance(value, list):
value = [value]
for v in value:
user = None
if isinstance(v, int):
user = User.objects.get(id=v)
elif isinstance(v, User):
user = v
@transaction.atomic()
def set_permissions(
self,
owner: list[User] | None = None,
collaborator: list[User] | None = None,
follower: list[User] | None = None,
):
# Delete all existing first
UserObjectPermission.objects.filter(
content_type__app_label=self._meta.app_label,
content_type__model=self._meta.model_name,
object_pk=self.pk,
).delete()

if key in ['owner', 'collaborator', 'follower']:
assign_perm(key, user, self)
# Assign new perms
for user in owner or []:
assign_perm('owner', user, self)
for user in collaborator or []:
assign_perm('collaborator', user, self)
for user in follower or []:
assign_perm('follower', user, self)

class Meta:
permissions = [
Expand Down
6 changes: 4 additions & 2 deletions uvdat/core/rest/project.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from django.contrib.auth.models import User
from django.http import HttpResponse
from rest_framework.decorators import action
from rest_framework.viewsets import ModelViewSet
Expand All @@ -16,8 +17,9 @@ class ProjectViewSet(ModelViewSet):
lookup_field = 'id'

def perform_create(self, serializer):
project = serializer.save()
project.update_permissions(owner=self.request.user)
project: Project = serializer.save()
user: User = self.request.user
project.set_permissions(owner=[user])

@action(detail=True, methods=['get'])
def regions(self, request, **kwargs):
Expand Down
2 changes: 1 addition & 1 deletion uvdat/core/tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ def viewset_test(

# Update project permissions
if perm is not None:
test_project.update_permissions(**{perm: [user.id]})
test_project.set_permissions(**{perm: [user.id]})
assert get_perms(user, test_project) == [perm]

# Test endpoints
Expand Down

0 comments on commit 61196f8

Please sign in to comment.