From 2577a286281e7aaddaf46de77d78378c4211c25e Mon Sep 17 00:00:00 2001 From: Ivlev Denis Date: Tue, 6 Feb 2018 12:40:37 +0300 Subject: [PATCH] LIL-176, LIL-180. Add permissions --- api/v1/permissions.py | 35 +++++++++++++++++++++++++++++++++++ api/v1/views.py | 42 ++++++++++++++++++++++++++++++++++++++++++ apps/user/models.py | 9 ++++++--- 3 files changed, 83 insertions(+), 3 deletions(-) diff --git a/api/v1/permissions.py b/api/v1/permissions.py index e69de29b..b7f6e693 100644 --- a/api/v1/permissions.py +++ b/api/v1/permissions.py @@ -0,0 +1,35 @@ +from django.contrib.auth import get_user_model + +from rest_framework.permissions import BasePermission + +User = get_user_model() + + +class IsAdmin(BasePermission): + def has_permission(self, request, view): + return request.user.is_authenticated and ( + request.user.role == User.ADMIN_ROLE or request.user.is_staff or request.user.is_superuser + ) + + +class IsAdminOrIsSelf(BasePermission): + def has_object_permission(self, request, view, user): + return request.user.is_authenticated and ( + user == request.user or request.user.is_staff or request.user.is_superuser + ) + + +class IsAuthorOrAdmin(BasePermission): + def has_permission(self, request, view): + return request.user.is_authenticated and ( + request.user.role in [ + User.AUTHOR_ROLE, User.ADMIN_ROLE + ] or request.user.is_staff or request.user.is_superuser + ) + + +class IsAuthorObjectOrAdmin(BasePermission): + def has_object_permission(self, request, view, obj): + return request.user.is_authenticated and ( + request.user.role == User.ADMIN_ROLE or request.user.is_staff or request.user.is_superuser + ) and request.user == obj.author diff --git a/api/v1/views.py b/api/v1/views.py index 420bdc6d..ddebe250 100644 --- a/api/v1/views.py +++ b/api/v1/views.py @@ -11,6 +11,7 @@ from .serializers import ( GallerySerializer, GalleryImageSerializer, UserSerializer, LessonSerializer, ) +from .permissions import IsAdmin, IsAdminOrIsSelf, IsAuthorOrAdmin, IsAuthorObjectOrAdmin from apps.course.models import Category, Course, Material, Lesson, Like from apps.content.models import ( @@ -26,6 +27,7 @@ class MaterialViewSet(ExtendedModelViewSet): serializer_class = MaterialSerializer search_fields = ('title', 'short_description',) ordering_fields = ('title', 'created_at', 'update_at',) + # permission_classes = (IsAdmin,) class LikeViewSet(ExtendedModelViewSet): @@ -33,6 +35,7 @@ class LikeViewSet(ExtendedModelViewSet): serializer_class = LikeSerializer search_fields = ('user__email', 'user__firstname', 'user__lastname',) ordering_fields = ('created_at', 'update_at',) + # permission_classes = (IsAdmin,) class CategoryViewSet(ExtendedModelViewSet): @@ -40,6 +43,7 @@ class CategoryViewSet(ExtendedModelViewSet): serializer_class = CategorySerializer search_fields = ('title',) ordering_fields = ('title',) + # permission_classes = (IsAdmin,) class CourseViewSet(ExtendedModelViewSet): @@ -52,6 +56,11 @@ class CourseViewSet(ExtendedModelViewSet): filter_fields = ('category', 'status', 'is_infinite', 'is_featured',) search_fields = ('author__email', 'title', 'category__title',) ordering_fields = ('title', 'created_at', 'update_at',) + # permission_classes = (IsAuthorObjectOrAdmin,) + # permission_map = { + # 'create': IsAuthorOrAdmin, + # 'delete': IsAdmin, + # } class LessonViewSet(ExtendedModelViewSet): @@ -60,6 +69,11 @@ class LessonViewSet(ExtendedModelViewSet): filter_fields = ('course',) search_fields = ('title', 'short_description',) ordering_fields = ('title', 'created_at', 'update_at',) + # permission_classes = (IsAuthorObjectOrAdmin,) + # permission_map = { + # 'create': IsAuthorOrAdmin, + # 'delete': IsAdmin, + # } class ImageViewSet(ExtendedModelViewSet): @@ -69,6 +83,10 @@ class ImageViewSet(ExtendedModelViewSet): serializer_class = ImageSerializer search_fields = ('title',) ordering_fields = ('title', 'created_at', 'update_at', 'position',) + # permission_classes = (IsAuthorOrAdmin,) + # permission_map = { + # 'delete': IsAdmin, + # } class TextViewSet(ExtendedModelViewSet): @@ -78,6 +96,10 @@ class TextViewSet(ExtendedModelViewSet): serializer_class = TextSerializer search_fields = ('title',) ordering_fields = ('title', 'created_at', 'update_at', 'position',) + # permission_classes = (IsAuthorOrAdmin,) + # permission_map = { + # 'delete': IsAdmin, + # } class ImageTextViewSet(ExtendedModelViewSet): @@ -87,6 +109,10 @@ class ImageTextViewSet(ExtendedModelViewSet): serializer_class = ImageTextSerializer search_fields = ('title',) ordering_fields = ('title', 'created_at', 'update_at', 'position',) + # permission_classes = (IsAuthorOrAdmin,) + # permission_map = { + # 'delete': IsAdmin, + # } class VideoViewSet(ExtendedModelViewSet): @@ -96,6 +122,10 @@ class VideoViewSet(ExtendedModelViewSet): serializer_class = VideoSerializer search_fields = ('title',) ordering_fields = ('title', 'created_at', 'update_at', 'position',) + # permission_classes = (IsAuthorOrAdmin,) + # permission_map = { + # 'delete': IsAdmin, + # } class GalleryViewSet(ExtendedModelViewSet): @@ -103,12 +133,20 @@ class GalleryViewSet(ExtendedModelViewSet): serializer_class = GallerySerializer search_fields = ('title',) ordering_fields = ('title', 'created_at', 'update_at',) + # permission_classes = (IsAuthorOrAdmin,) + # permission_map = { + # 'delete': IsAdmin, + # } class GalleryImageViewSet(ExtendedModelViewSet): queryset = GalleryImage.objects.select_related('gallery').all() serializer_class = GalleryImageSerializer search_fields = ('gallery__title',) + # permission_classes = (IsAuthorOrAdmin,) + # permission_map = { + # 'delete': IsAdmin, + # } class UserViewSet(ExtendedModelViewSet): @@ -120,3 +158,7 @@ class UserViewSet(ExtendedModelViewSet): 'country', 'city', 'fb_id',) ordering_fields = ('email', 'first_name', 'last_name', 'country', 'city', 'date_joined',) + # permission_classes = (IsAdminOrIsSelf,) + # permission_map = { + # 'delete': IsAdmin, + # } diff --git a/apps/user/models.py b/apps/user/models.py index d5633f8c..7a59786c 100644 --- a/apps/user/models.py +++ b/apps/user/models.py @@ -5,10 +5,13 @@ from django.utils.translation import gettext_lazy as _ class User(AbstractUser): + USER_ROLE = 0 + AUTHOR_ROLE = 1 + ADMIN_ROLE = 2 ROLE_CHOICES = ( - (0, 'пользователь'), - (1, 'автор'), - (2, 'администратор'), + (USER_ROLE, 'пользователь'), + (AUTHOR_ROLE, 'автор'), + (ADMIN_ROLE, 'администратор'), ) GENDER_CHOICES = ( ('n', 'не указан'),