1
Fork 0
mirror of https://github.com/Steffo99/sophon.git synced 2024-12-23 07:14:21 +00:00

🔧 Abstract permissions, add ResearchTag and ResearchGroup viewsets

This commit is contained in:
Steffo 2021-08-07 17:26:38 +02:00
parent 584a248d10
commit 09d2452080
Signed by: steffo
GPG key ID: 6965406171929D01
5 changed files with 145 additions and 29 deletions

View file

@ -381,6 +381,24 @@ class ResearchGroup(models.Model):
max_length=16, max_length=16,
) )
def can_be_edited_by(self, user) -> bool:
if user.is_superuser:
return True
elif user in self.members:
return True
return False
def can_be_administrated_by(self, user) -> bool:
if user.is_superuser:
return True
elif user in self.owner:
return True
return False
def __str__(self): def __str__(self):
return f"{self.slug}" return f"{self.slug}"
@ -420,6 +438,15 @@ class ResearchTag(models.Model):
on_delete=models.CASCADE, on_delete=models.CASCADE,
) )
def can_be_administrated_by(self, user) -> bool:
if user.is_superuser:
return True
elif user == self.owner:
return True
return False
def __str__(self): def __str__(self):
return f"[{self.name}]" return f"[{self.name}]"
@ -482,13 +509,6 @@ class ResearchProject(models.Model):
) )
def can_be_viewed_by(self, user) -> bool: def can_be_viewed_by(self, user) -> bool:
"""
Check whether an user should be allowed to **view** the project contents.
:param user: The user to check permissions for.
:return: :data:`True` if the user can view the details, or :data:`False` if they cannot.
"""
if user.is_superuser: if user.is_superuser:
return True return True
@ -503,13 +523,6 @@ class ResearchProject(models.Model):
raise ValueError(f"Unknown visibility value: {self.visibility}") raise ValueError(f"Unknown visibility value: {self.visibility}")
def can_be_edited_by(self, user) -> bool: def can_be_edited_by(self, user) -> bool:
"""
Check whether an user should be allowed to **edit** the project details.
:param user: The user to check permissions for.
:return: :data:`True` if the user can edit the details, or :data:`False` if they cannot.
"""
if user.is_superuser: if user.is_superuser:
return True return True
@ -519,13 +532,6 @@ class ResearchProject(models.Model):
return False return False
def can_be_administrated_by(self, user) -> bool: def can_be_administrated_by(self, user) -> bool:
"""
Check whether an user should be allowed to **administrate** the project.
:param user: The user to check permissions for.
:return: :data:`True` if the user can administrate the project, or :data:`False` if they cannot.
"""
if user.is_superuser: if user.is_superuser:
return True return True

View file

@ -120,6 +120,53 @@ class ResearchProjectPublicSerializer(serializers.ModelSerializer):
) )
class ResearchTagPublicSerializer(serializers.ModelSerializer):
"""
Serializer for users who are not owners of a :class:`.models.ResearchTag`.
"""
# TODO: Add a list of projects with the tag
class Meta:
model = models.ResearchTag
fields = (
"slug",
"name",
"description",
"color",
"owner",
)
read_only_fields = (
"slug",
"name",
"description",
"color",
"owner",
)
class ResearchTagAdminSerializer(serializers.ModelSerializer):
"""
Serializer for users who are owners of a :class:`.models.ResearchTag`.
"""
# TODO: Add a list of projects with the tag
class Meta:
model = models.ResearchTag
fields = (
"slug",
"name",
"description",
"color",
"owner",
)
read_only_fields = (
"slug",
"owner",
)
class ResearchProjectViewerSerializer(serializers.ModelSerializer): class ResearchProjectViewerSerializer(serializers.ModelSerializer):
""" """
Serializer for users who are not collaborators of a :class:`~.models.ResearchProject`, but have permissions to view it. Serializer for users who are not collaborators of a :class:`~.models.ResearchProject`, but have permissions to view it.

View file

@ -7,6 +7,8 @@ router = DefaultRouter()
router.register("datasources", views.DataSourceViewSet) router.register("datasources", views.DataSourceViewSet)
router.register("dataflows", views.DataFlowViewSet) router.register("dataflows", views.DataFlowViewSet)
router.register("projects", views.ResearchProjectViewSet) router.register("projects", views.ResearchProjectViewSet)
router.register("tags", views.ResearchTagViewSet)
router.register("groups", views.ResearchGroupViewSet)
urlpatterns = [ urlpatterns = [
path("", include(router.urls)), path("", include(router.urls)),

View file

@ -2,7 +2,8 @@ from logging import getLogger
from rest_framework import viewsets, decorators, response, permissions, request as r from rest_framework import viewsets, decorators, response, permissions, request as r
from . import models, serializers, permissions as custom_permissions from . import models, serializers
from .. import permissions as custom_permissions
log = getLogger(__name__) log = getLogger(__name__)
@ -15,10 +16,10 @@ class ResearchProjectViewSet(viewsets.ModelViewSet):
return { return {
"list": [], "list": [],
"create": [permissions.IsAuthenticated], "create": [permissions.IsAuthenticated],
"retrieve": [custom_permissions.CanViewProject], "retrieve": [custom_permissions.CanView],
"update": [custom_permissions.CanEditProject], "update": [custom_permissions.CanEdit],
"partial_update": [custom_permissions.CanEditProject], "partial_update": [custom_permissions.CanEdit],
"destroy": [custom_permissions.CanAdministrateProject], "destroy": [custom_permissions.CanAdministrate],
"metadata": [], "metadata": [],
None: [], None: [],
}[self.action] }[self.action]
@ -41,6 +42,66 @@ class ResearchProjectViewSet(viewsets.ModelViewSet):
return serializers.ResearchProjectPublicSerializer return serializers.ResearchProjectPublicSerializer
class ResearchGroupViewSet(viewsets.ModelViewSet):
queryset = models.ResearchGroup.objects.all()
@property
def permission_classes(self):
return {
"list": [],
"create": [permissions.IsAuthenticated],
"retrieve": [permissions.IsAuthenticated],
"update": [custom_permissions.CanAdministrate],
"partial_update": [custom_permissions.CanAdministrate],
"destroy": [custom_permissions.CanAdministrate],
"metadata": [],
None: [],
}[self.action]
def get_serializer_class(self):
if self.action == "list":
return serializers.ResearchGroupPublicSerializer
elif self.action == "create":
return serializers.ResearchGroupAdminSerializer
else:
group = self.get_object()
user = self.request.user
if group.can_be_administrated_by(user):
return serializers.ResearchGroupAdminSerializer
else:
return serializers.ResearchGroupPublicSerializer
class ResearchTagViewSet(viewsets.ModelViewSet):
queryset = models.ResearchTag.objects.all()
@property
def permission_classes(self):
return {
"list": [],
"create": [permissions.IsAuthenticated],
"retrieve": [permissions.IsAuthenticated],
"update": [custom_permissions.CanAdministrate],
"partial_update": [custom_permissions.CanAdministrate],
"destroy": [custom_permissions.CanAdministrate],
"metadata": [],
None: [],
}[self.action]
def get_serializer_class(self):
if self.action == "list":
return serializers.ResearchTagPublicSerializer
elif self.action == "create":
return serializers.ResearchTagAdminSerializer
else:
group = self.get_object()
user = self.request.user
if group.can_be_administrated_by(user):
return serializers.ResearchTagAdminSerializer
else:
return serializers.ResearchTagPublicSerializer
class DataFlowViewSet(viewsets.ModelViewSet): class DataFlowViewSet(viewsets.ModelViewSet):
""" """
Viewset for :class:`.models.DataFlow` instances. Viewset for :class:`.models.DataFlow` instances.

View file

@ -5,16 +5,16 @@ from rest_framework import permissions
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
class CanAdministrateProject(permissions.BasePermission): class CanAdministrate(permissions.BasePermission):
def has_object_permission(self, request, view, obj): def has_object_permission(self, request, view, obj):
return obj.can_be_administrated_by(request.user) return obj.can_be_administrated_by(request.user)
class CanEditProject(permissions.BasePermission): class CanEdit(permissions.BasePermission):
def has_object_permission(self, request, view, obj): def has_object_permission(self, request, view, obj):
return obj.can_be_edited_by(request.user) return obj.can_be_edited_by(request.user)
class CanViewProject(permissions.BasePermission): class CanView(permissions.BasePermission):
def has_object_permission(self, request, view, obj): def has_object_permission(self, request, view, obj):
return obj.can_be_viewed_by(request.user) return obj.can_be_viewed_by(request.user)