diff --git a/apps/account/models.py b/apps/account/models.py index 2e22d24d..a1a5ede4 100644 --- a/apps/account/models.py +++ b/apps/account/models.py @@ -1,8 +1,10 @@ """Account models""" +from collections import Counter from datetime import datetime -from django.contrib.postgres.search import TrigramSimilarity + from django.conf import settings from django.contrib.auth.models import AbstractUser, UserManager as BaseUserManager +from django.contrib.postgres.search import TrigramSimilarity from django.core.mail import send_mail from django.db import models from django.template.loader import render_to_string, get_template @@ -11,8 +13,8 @@ from django.utils.encoding import force_bytes from django.utils.html import mark_safe from django.utils.http import urlsafe_base64_encode from django.utils.translation import ugettext_lazy as _ +from phonenumber_field.modelfields import PhoneNumberField from rest_framework.authtoken.models import Token -from collections import Counter from authorization.models import Application from establishment.models import Establishment, EstablishmentSubType @@ -21,7 +23,6 @@ from main.models import SiteSettings from utils.models import GMTokenGenerator from utils.models import ImageMixin, ProjectBaseMixin, PlatformMixin from utils.tokens import GMRefreshToken -from phonenumber_field.modelfields import PhoneNumberField class RoleQuerySet(models.QuerySet): @@ -449,6 +450,31 @@ class User(AbstractUser): result.append(item.id) return set(result) + @property + def is_country_admin(self): + if self.userrole_set: + return self.userrole_set.country_admin().exists() + + @property + def is_establishment_manager(self): + if self.userrole_set: + return self.userrole_set.establishment_manager().exists() + + @property + def is_establishment_administrator(self): + if self.userrole_set: + return self.userrole_set.establishment_administrator().exists() + + @property + def administrated_country_codes(self) -> list: + if self.userrole_set: + return list( + self.userrole_set + .exclude(role__site__isnull=True) + .values_list('role__site__country__code', flat=True) + .distinct() + ) + class UserRoleQueryset(models.QuerySet): """QuerySet for model UserRole.""" @@ -498,17 +524,26 @@ class UserRoleQueryset(models.QuerySet): """Filter QuerySet by state.""" return self.filter(state=self.model.VALIDATED) - def has_access_to_establishments(self): - """Return QuerySet filtered by role and state.""" - return self.filter(role__role__in=Role.ESTABLISHMENT_EDITORS).validated() + def country_admin(self): + """Return status by role and state""" + return ( + self.filter(role__role=Role.COUNTRY_ADMIN) + .validated() + ) - def has_access_to_products(self): - """Return QuerySet filtered by role and state.""" - return self.filter(role__role__in=Role.PRODUCT_EDITORS).validated() + def establishment_manager(self): + """Return status by role and state""" + return ( + self.filter(role__role=Role.ESTABLISHMENT_MANAGER) + .validated() + ) - def has_access_to_content_pages(self): - """Return QuerySet filtered by role and state.""" - return self.filter(role__role__in=Role.CONTENT_PAGE_MANAGER).validated() + def establishment_administrator(self): + """Return status by role and state""" + return ( + self.filter(role__role=Role.ESTABLISHMENT_ADMINISTRATOR) + .validated() + ) class UserRole(ProjectBaseMixin): diff --git a/apps/account/views/back.py b/apps/account/views/back.py index 5433245c..c7afc083 100644 --- a/apps/account/views/back.py +++ b/apps/account/views/back.py @@ -1,32 +1,29 @@ -from django_filters.rest_framework import DjangoFilterBackend -from rest_framework import generics, permissions, status -from rest_framework.response import Response -from rest_framework.filters import OrderingFilter import csv + from django.http import HttpResponse, HttpResponseNotFound +from django_filters.rest_framework import DjangoFilterBackend +from rest_framework import generics, status from rest_framework.authtoken.models import Token +from rest_framework.filters import OrderingFilter +from rest_framework.response import Response from account import models, filters from account.models import User from account.serializers import back as serializers from account.serializers.common import RoleBaseSerializer -from utils.permissions import * +from utils.methods import get_permission_classes +from utils.permissions import IsReviewManager class RoleListView(generics.ListCreateAPIView): serializer_class = RoleBaseSerializer queryset = models.Role.objects.all() filter_class = filters.RoleListFilter - permission_classes = [ - IsCountryAdmin - ] + permission_classes = get_permission_classes() class RoleTypeRetrieveView(generics.GenericAPIView): - permission_classes = [ - permissions.IsAdminUser | - IsCountryAdmin - ] + permission_classes = get_permission_classes() def get(self, request, *args, **kwargs): """Implement GET-method""" @@ -43,21 +40,15 @@ class RoleTypeRetrieveView(generics.GenericAPIView): class UserRoleListView(generics.ListCreateAPIView): serializer_class = serializers.UserRoleSerializer queryset = models.UserRole.objects.all() - permission_classes = [ - IsCountryAdmin - ] + permission_classes = get_permission_classes() class UserListView(generics.ListCreateAPIView): """User list create view.""" serializer_class = serializers.BackUserSerializer - permission_classes = [ - permissions.IsAdminUser | - IsReviewManager | - IsCountryAdmin - ] filter_class = filters.AccountBackOfficeFilter filter_backends = (OrderingFilter, DjangoFilterBackend) + permission_classes = get_permission_classes(IsReviewManager) ordering_fields = ( 'email_confirmed', @@ -77,8 +68,8 @@ class UserRUDView(generics.RetrieveUpdateDestroyAPIView): """User RUD view.""" queryset = User.objects.all() serializer_class = serializers.BackDetailUserSerializer - permission_classes = (permissions.IsAdminUser,) lookup_field = 'id' + permission_classes = get_permission_classes() def get_user_csv(request, id): diff --git a/apps/advertisement/views/back.py b/apps/advertisement/views/back.py index 27a016a2..3590c9b4 100644 --- a/apps/advertisement/views/back.py +++ b/apps/advertisement/views/back.py @@ -1,20 +1,21 @@ """Back office views for app advertisement""" +from django.shortcuts import get_object_or_404 from rest_framework import generics, status from rest_framework.response import Response -from rest_framework import permissions -from django.shortcuts import get_object_or_404 -from main.serializers import PageExtendedSerializer from advertisement.models import Advertisement -from advertisement.serializers import (AdvertisementBaseSerializer, - AdvertisementDetailSerializer) +from advertisement.serializers import ( + AdvertisementBaseSerializer, + AdvertisementDetailSerializer) +from main.serializers import PageExtendedSerializer +from utils.methods import get_permission_classes class AdvertisementBackOfficeViewMixin(generics.GenericAPIView): """Base back office advertisement view.""" pagination_class = None - permission_classes = (permissions.IsAuthenticated, ) + permission_classes = get_permission_classes() def get_queryset(self): """Overridden get queryset method.""" diff --git a/apps/collection/views/back.py b/apps/collection/views/back.py index 481f70da..cc44c22d 100644 --- a/apps/collection/views/back.py +++ b/apps/collection/views/back.py @@ -9,6 +9,7 @@ from rest_framework.response import Response from collection import models, serializers from collection import tasks +from utils.methods import get_permission_classes from utils.views import BindObjectMixin @@ -16,8 +17,8 @@ class CollectionViewSet(mixins.ListModelMixin, viewsets.GenericViewSet): """ViewSet for Collection model.""" # pagination_class = None - permission_classes = (permissions.AllowAny,) serializer_class = serializers.CollectionBackOfficeSerializer + permission_classes = get_permission_classes() def get_queryset(self): """Overridden method 'get_queryset'.""" @@ -30,7 +31,7 @@ class CollectionViewSet(mixins.ListModelMixin, viewsets.GenericViewSet): class GuideBaseView(generics.GenericAPIView): """ViewSet for Guide model.""" serializer_class = serializers.GuideBaseSerializer - permission_classes = (permissions.IsAuthenticatedOrReadOnly,) + permission_classes = get_permission_classes() def get_queryset(self): """Overridden get_queryset method.""" @@ -47,7 +48,7 @@ class GuideFilterBaseView(generics.GenericAPIView): pagination_class = None queryset = models.GuideFilter.objects.all() serializer_class = serializers.GuideFilterBaseSerializer - permission_classes = (permissions.IsAuthenticatedOrReadOnly,) + permission_classes = get_permission_classes() class GuideElementBaseView(generics.GenericAPIView): @@ -55,7 +56,7 @@ class GuideElementBaseView(generics.GenericAPIView): pagination_class = None queryset = models.GuideElement.objects.all() serializer_class = serializers.GuideElementBaseSerializer - permission_classes = (permissions.IsAuthenticatedOrReadOnly,) + permission_classes = get_permission_classes() class AdvertorialBaseView(generics.GenericAPIView): @@ -63,7 +64,7 @@ class AdvertorialBaseView(generics.GenericAPIView): pagination_class = None queryset = models.Advertorial.objects.all() serializer_class = serializers.AdvertorialBaseSerializer - permission_classes = (permissions.IsAuthenticatedOrReadOnly,) + permission_classes = get_permission_classes() class CollectionBackOfficeViewSet(mixins.CreateModelMixin, @@ -74,11 +75,11 @@ class CollectionBackOfficeViewSet(mixins.CreateModelMixin, CollectionViewSet): """ViewSet for Collection model for BackOffice users.""" - permission_classes = (permissions.IsAuthenticated,) queryset = models.Collection.objects.all() filter_backends = [DjangoFilterBackend, OrderingFilter] serializer_class = serializers.CollectionBackOfficeSerializer bind_object_serializer_class = serializers.CollectionBindObjectSerializer + permission_classes = get_permission_classes() ordering_fields = ('rank', 'start') ordering = ('-start', ) @@ -183,7 +184,7 @@ class GuideElementExportXMLView(generics.ListAPIView): pagination_class = None queryset = models.GuideElement.objects.all() serializer_class = serializers.GuideElementBaseSerializer - permission_classes = (permissions.IsAuthenticatedOrReadOnly,) + permission_classes = get_permission_classes() def get(self, request, *args, **kwargs): """Overridden get_queryset method.""" @@ -199,7 +200,7 @@ class GuideElementExportDOCView(generics.ListAPIView): pagination_class = None queryset = models.GuideElement.objects.all() serializer_class = serializers.GuideElementBaseSerializer - permission_classes = (permissions.IsAuthenticatedOrReadOnly,) + permission_classes = get_permission_classes() def get(self, request, *args, **kwargs): """Overridden get_queryset method.""" diff --git a/apps/comment/views/back.py b/apps/comment/views/back.py index b998e4ed..090186be 100644 --- a/apps/comment/views/back.py +++ b/apps/comment/views/back.py @@ -2,22 +2,20 @@ from rest_framework import generics from comment import models from comment.serializers import CommentBaseSerializer -from utils.permissions import IsModerator, IsCountryAdmin +from utils.methods import get_permission_classes +from utils.permissions import IsModerator class CommentLstView(generics.ListCreateAPIView): """Comment list create view.""" serializer_class = CommentBaseSerializer queryset = models.Comment.objects.all() - permission_classes = [ - IsModerator | - IsCountryAdmin - ] + permission_classes = get_permission_classes(IsModerator) class CommentRUDView(generics.RetrieveUpdateDestroyAPIView): """Comment RUD view.""" serializer_class = CommentBaseSerializer queryset = models.Comment.objects.all() - permission_classes = [IsModerator] + permission_classes = get_permission_classes(IsModerator) lookup_field = 'id' diff --git a/apps/establishment/models.py b/apps/establishment/models.py index 93fd9760..21ffed5f 100644 --- a/apps/establishment/models.py +++ b/apps/establishment/models.py @@ -2,33 +2,33 @@ from datetime import datetime from functools import reduce from operator import or_ -from typing import List +from typing import List, Union import elasticsearch_dsl from django.conf import settings -from django.shortcuts import get_object_or_404 from django.contrib.contenttypes import fields as generic from django.contrib.gis.db.models.functions import Distance from django.contrib.gis.geos import Point from django.contrib.gis.measure import Distance as DistanceMeasure from django.contrib.postgres.fields import ArrayField -from django.contrib.postgres.search import TrigramDistance, TrigramSimilarity from django.contrib.postgres.indexes import GinIndex +from django.contrib.postgres.search import TrigramSimilarity from django.core.exceptions import ValidationError from django.core.validators import MinValueValidator, MaxValueValidator, FileExtensionValidator from django.db import models -from django.db.models import When, Case, F, ExpressionWrapper, Subquery, Q, Prefetch, Sum +from django.db.models import When, Case, F, ExpressionWrapper, Subquery, Q, Prefetch +from django.shortcuts import get_object_or_404 from django.utils import timezone from django.utils.translation import gettext_lazy as _ from phonenumber_field.modelfields import PhoneNumberField from timezone_field import TimeZoneField from location.models import Address -from timetable.models import Timetable from location.models import WineOriginAddressMixin from main.models import Award, Currency from review.models import Review from tag.models import Tag +from timetable.models import Timetable from utils.methods import transform_into_readable_str from utils.models import (ProjectBaseMixin, TJSONField, URLImageMixin, TranslatedFieldsMixin, BaseAttributes, GalleryMixin, @@ -184,9 +184,10 @@ class EstablishmentQuerySet(models.QuerySet): """Return establishments by country code""" return self.filter(address__city__country=country) - def by_country_code(self, code): + def by_country_code(self, codes: Union[iter, str]): """Return establishments by country code""" - return self.filter(address__city__country__code=code) + codes = codes if hasattr(codes, '__iter__') else [codes] + return self.filter(address__city__country__code__in=codes) def published(self): """ @@ -518,31 +519,27 @@ class EstablishmentQuerySet(models.QuerySet): to_attr='main_image') ) - def user_role_establishments(self, user, country_code: str = None): - """Return QuerySet with establishment that is available for editing.""" + def available_establishments(self, user): + """Return QuerySet with establishment that user has an access.""" from account.models import UserRole - available_ids = Subquery( - UserRole.objects.filter(user=user) - .distinct('user', 'establishment') - .values_list('establishment', flat=True) - ) - + administrator_establishment_ids = [] filters = {} - if country_code: - filters.update({'address__city__country__code': country_code, - 'id__in': available_ids}) - return self.filter(**filters) + # put in array administrated establishment ids + if user.is_establishment_administrator: + administrator_establishment_ids.extend( + UserRole.objects.filter(user=user) + .distinct('user', 'establishment') + .values_list('establishment', flat=True) + ) + # check if user is_staff + if not user.is_staff: + filters.update({'address__city__country__code__in': user.administrated_country_codes}) - def available_objects(self, user, country_code: str = None): - # role without establishment - - # role that has establishment - access_roles = user.userrole_set.has_access_to_establishments() - if access_roles.exists(): - return self.user_role_establishments(user, country_code) - return self.none() + return self.filter(**filters).union( + self.filter(id__in=administrator_establishment_ids) + ) class Establishment(GalleryMixin, ProjectBaseMixin, URLImageMixin, diff --git a/apps/establishment/views/back.py b/apps/establishment/views/back.py index 80f0b0ce..ee17fc94 100644 --- a/apps/establishment/views/back.py +++ b/apps/establishment/views/back.py @@ -1,7 +1,7 @@ """Establishment app views.""" from django.shortcuts import get_object_or_404 from django_filters.rest_framework import DjangoFilterBackend -from rest_framework import generics, permissions, status +from rest_framework import generics, status from rest_framework.response import Response from account.models import User @@ -9,10 +9,9 @@ from establishment import filters, models, serializers from establishment.models import EstablishmentEmployee from timetable.models import Timetable from timetable.serialziers import ScheduleCreateSerializer, ScheduleRUDSerializer +from utils.methods import get_permission_classes from utils.permissions import ( - IsCountryAdmin, IsEstablishmentManager, - IsWineryWineInspector, IsEstablishmentAdministrator, - IsReviewManager, IsRestaurantInspector + IsEstablishmentManager, IsEstablishmentAdministrator, IsReviewManager, ) from utils.views import CreateDestroyGalleryViewMixin @@ -22,40 +21,32 @@ class EstablishmentMixinViews: def get_queryset(self): """Overridden method 'get_queryset'.""" - return models.Establishment.objects.with_base_related() + queryset = models.Establishment.objects.with_base_related + if hasattr(self, 'request') and \ + (hasattr(self.request, 'user') and hasattr(self.request, 'country_code')): + return queryset().available_establishments(self.request.user) + return queryset().none() class EstablishmentListCreateView(EstablishmentMixinViews, generics.ListCreateAPIView): """Establishment list/create view.""" filter_class = filters.EstablishmentFilter - - permission_classes = [ - IsReviewManager | - IsWineryWineInspector | - IsCountryAdmin | - IsEstablishmentManager | - IsEstablishmentAdministrator - ] - queryset = models.Establishment.objects.all() serializer_class = serializers.EstablishmentListCreateSerializer - - def get_queryset(self): - """Overridden get_queryset method.""" - qs = super(EstablishmentListCreateView, self).get_queryset() - return qs.available_objects(self.request.user, self.request.country_code) + permission_classes = get_permission_classes( + IsReviewManager, + IsEstablishmentManager, + IsEstablishmentAdministrator, + ) class EmployeeEstablishmentsListView(generics.ListAPIView): """Establishment by employee list view.""" - - permission_classes = [ - IsWineryWineInspector | - IsCountryAdmin | - IsEstablishmentManager - ] - queryset = models.Establishment.objects.all() serializer_class = serializers.EstablishmentListCreateSerializer + permission_classes = get_permission_classes( + IsEstablishmentManager, + IsEstablishmentAdministrator, + ) def get_queryset(self): pk = self.kwargs.get('pk') @@ -63,30 +54,31 @@ class EmployeeEstablishmentsListView(generics.ListAPIView): return employee.establishments.with_extended_related() -class EstablishmentRUDView(generics.RetrieveUpdateDestroyAPIView): +class EstablishmentRUDView(EstablishmentMixinViews, generics.RetrieveUpdateDestroyAPIView): lookup_field = 'slug' - queryset = models.Establishment.objects.all().prefetch_related( - 'establishmentemployee_set', - 'establishmentemployee_set__establishment', - ) serializer_class = serializers.EstablishmentRUDSerializer - permission_classes = [ - # IsWineryWineInspector | - # IsCountryAdmin | - # IsEstablishmentManager | - IsEstablishmentAdministrator - # IsRestaurantInspector - ] + permission_classes = get_permission_classes( + IsEstablishmentManager, + IsEstablishmentAdministrator, + ) + + def get_queryset(self): + """Overridden get_queryset method.""" + qs = super(EstablishmentRUDView, self).get_queryset() + return qs.prefetch_related( + 'establishmentemployee_set', + 'establishmentemployee_set__establishment', + ) -class EstablishmentScheduleRUDView(generics.RetrieveUpdateDestroyAPIView): +class EstablishmentScheduleRUDView(EstablishmentMixinViews, generics.RetrieveUpdateDestroyAPIView): """Establishment schedule RUD view""" lookup_field = 'slug' serializer_class = ScheduleRUDSerializer - permission_classes = [ - IsWineryWineInspector | - IsEstablishmentManager - ] + permission_classes = get_permission_classes( + IsEstablishmentManager, + IsEstablishmentAdministrator, + ) def get_object(self): """ @@ -95,7 +87,7 @@ class EstablishmentScheduleRUDView(generics.RetrieveUpdateDestroyAPIView): establishment_slug = self.kwargs['slug'] schedule_id = self.kwargs['schedule_id'] - establishment = get_object_or_404(klass=models.Establishment.objects.all(), + establishment = get_object_or_404(klass=super(EstablishmentScheduleRUDView, self).get_queryset(), slug=establishment_slug) schedule = get_object_or_404(klass=establishment.schedule, id=schedule_id) @@ -112,21 +104,21 @@ class EstablishmentScheduleCreateView(generics.CreateAPIView): lookup_field = 'slug' serializer_class = ScheduleCreateSerializer queryset = Timetable.objects.all() - permission_classes = [ - IsWineryWineInspector | - IsEstablishmentManager - ] + permission_classes = get_permission_classes( + IsEstablishmentManager, + IsEstablishmentAdministrator, + ) class MenuListCreateView(generics.ListCreateAPIView): """Menu list create view.""" serializer_class = serializers.MenuSerializers queryset = models.Menu.objects.all() - permission_classes = [ - IsWineryWineInspector | - IsEstablishmentManager - ] filter_backends = (DjangoFilterBackend,) + permission_classes = get_permission_classes( + IsEstablishmentManager, + IsEstablishmentAdministrator, + ) filterset_fields = ( 'establishment', 'establishment__slug', @@ -137,10 +129,10 @@ class MenuRUDView(generics.RetrieveUpdateDestroyAPIView): """Menu RUD view.""" serializer_class = serializers.MenuRUDSerializers queryset = models.Menu.objects.all() - permission_classes = [ - IsWineryWineInspector | - IsEstablishmentManager - ] + permission_classes = get_permission_classes( + IsEstablishmentManager, + IsEstablishmentAdministrator, + ) class SocialChoiceListCreateView(generics.ListCreateAPIView): @@ -148,14 +140,20 @@ class SocialChoiceListCreateView(generics.ListCreateAPIView): serializer_class = serializers.SocialChoiceSerializers queryset = models.SocialChoice.objects.all() pagination_class = None - permission_classes = [permissions.IsAdminUser] + permission_classes = get_permission_classes( + IsEstablishmentManager, + IsEstablishmentAdministrator, + ) class SocialChoiceRUDView(generics.RetrieveUpdateDestroyAPIView): """SocialChoice RUD view.""" serializer_class = serializers.SocialChoiceSerializers queryset = models.SocialChoice.objects.all() - permission_classes = [permissions.IsAdminUser] + permission_classes = get_permission_classes( + IsEstablishmentManager, + IsEstablishmentAdministrator, + ) class SocialListCreateView(generics.ListCreateAPIView): @@ -163,14 +161,20 @@ class SocialListCreateView(generics.ListCreateAPIView): serializer_class = serializers.SocialNetworkSerializers queryset = models.SocialNetwork.objects.all() pagination_class = None - permission_classes = [permissions.IsAdminUser] + permission_classes = get_permission_classes( + IsEstablishmentManager, + IsEstablishmentAdministrator, + ) class SocialRUDView(generics.RetrieveUpdateDestroyAPIView): """Social RUD view.""" serializer_class = serializers.SocialNetworkSerializers queryset = models.SocialNetwork.objects.all() - permission_classes = [IsEstablishmentManager] + permission_classes = get_permission_classes( + IsEstablishmentManager, + IsEstablishmentAdministrator, + ) class PlateListCreateView(generics.ListCreateAPIView): @@ -178,14 +182,20 @@ class PlateListCreateView(generics.ListCreateAPIView): serializer_class = serializers.PlatesSerializers queryset = models.Plate.objects.all() pagination_class = None - permission_classes = [IsWineryWineInspector | IsEstablishmentManager] + permission_classes = get_permission_classes( + IsEstablishmentAdministrator, + IsEstablishmentManager, + ) class PlateRUDView(generics.RetrieveUpdateDestroyAPIView): """Plate RUD view.""" serializer_class = serializers.PlatesSerializers queryset = models.Plate.objects.all() - permission_classes = [IsWineryWineInspector | IsEstablishmentManager] + permission_classes = get_permission_classes( + IsEstablishmentAdministrator, + IsEstablishmentManager, + ) class PhonesListCreateView(generics.ListCreateAPIView): @@ -193,14 +203,20 @@ class PhonesListCreateView(generics.ListCreateAPIView): serializer_class = serializers.ContactPhoneBackSerializers queryset = models.ContactPhone.objects.all() pagination_class = None - permission_classes = [IsWineryWineInspector | IsEstablishmentManager] + permission_classes = get_permission_classes( + IsEstablishmentAdministrator, + IsEstablishmentManager, + ) class PhonesRUDView(generics.RetrieveUpdateDestroyAPIView): """Phones RUD view.""" serializer_class = serializers.ContactPhoneBackSerializers queryset = models.ContactPhone.objects.all() - permission_classes = [IsWineryWineInspector | IsEstablishmentManager] + permission_classes = get_permission_classes( + IsEstablishmentAdministrator, + IsEstablishmentManager, + ) class EmailListCreateView(generics.ListCreateAPIView): @@ -208,38 +224,53 @@ class EmailListCreateView(generics.ListCreateAPIView): serializer_class = serializers.ContactEmailBackSerializers queryset = models.ContactEmail.objects.all() pagination_class = None - permission_classes = [IsWineryWineInspector | IsEstablishmentManager] + permission_classes = get_permission_classes( + IsEstablishmentAdministrator, + IsEstablishmentManager, + ) class EmailRUDView(generics.RetrieveUpdateDestroyAPIView): """Email RUD view.""" serializer_class = serializers.ContactEmailBackSerializers queryset = models.ContactEmail.objects.all() - permission_classes = [IsWineryWineInspector | IsEstablishmentManager] + permission_classes = get_permission_classes( + IsEstablishmentAdministrator, + IsEstablishmentManager, + ) class EmployeeListCreateView(generics.ListCreateAPIView): """Employee list create view.""" - permission_classes = (permissions.AllowAny,) filter_class = filters.EmployeeBackFilter serializer_class = serializers.EmployeeBackSerializers queryset = models.Employee.objects.all().distinct().with_back_office_related() + permission_classes = get_permission_classes( + IsEstablishmentManager, + IsEstablishmentAdministrator, + ) class EmployeesListSearchViews(generics.ListAPIView): """Employee search view""" pagination_class = None - permission_classes = (permissions.AllowAny,) queryset = models.Employee.objects.all().with_back_office_related().select_related('photo') filter_class = filters.EmployeeBackSearchFilter serializer_class = serializers.EmployeeBackSerializers + permission_classes = get_permission_classes( + IsEstablishmentManager, + IsEstablishmentAdministrator, + ) class EstablishmentEmployeeListView(generics.ListCreateAPIView): """Establishment emplyoees list view.""" - permission_classes = (permissions.AllowAny,) serializer_class = serializers.EstEmployeeBackSerializer pagination_class = None + permission_classes = get_permission_classes( + IsEstablishmentManager, + IsEstablishmentAdministrator, + ) def get_queryset(self): establishment_id = self.kwargs['establishment_id'] @@ -251,13 +282,18 @@ class EstablishmentEmployeeListView(generics.ListCreateAPIView): class EmployeeRUDView(generics.RetrieveUpdateDestroyAPIView): """Employee RUD view.""" serializer_class = serializers.EmployeeBackSerializers - queryset = models.Employee.objects.all().with_back_office_related() + queryset = models.Employee.objects.with_back_office_related() + permission_classes = get_permission_classes( + IsEstablishmentManager, + IsEstablishmentAdministrator, + ) class RemoveAwardView(generics.DestroyAPIView): lookup_field = 'pk' serializer_class = serializers.EmployeeBackSerializers - queryset = models.Employee.objects.all().with_back_office_related() + queryset = models.Employee.objects.with_back_office_related() + permission_classes = get_permission_classes() def get_object(self): employee = super().get_object() @@ -272,27 +308,31 @@ class RemoveAwardView(generics.DestroyAPIView): class EstablishmentTypeListCreateView(generics.ListCreateAPIView): """Establishment type list/create view.""" serializer_class = serializers.EstablishmentTypeBaseSerializer - queryset = models.EstablishmentType.objects.all().select_related('default_image') + queryset = models.EstablishmentType.objects.select_related('default_image') pagination_class = None + permission_classes = get_permission_classes() class EstablishmentTypeRUDView(generics.RetrieveUpdateDestroyAPIView): """Establishment type retrieve/update/destroy view.""" serializer_class = serializers.EstablishmentTypeBaseSerializer - queryset = models.EstablishmentType.objects.all().select_related('default_image') + queryset = models.EstablishmentType.objects.select_related('default_image') + permission_classes = get_permission_classes() class EstablishmentSubtypeListCreateView(generics.ListCreateAPIView): """Establishment subtype list/create view.""" serializer_class = serializers.EstablishmentSubTypeBaseSerializer - queryset = models.EstablishmentSubType.objects.all().select_related('default_image') + queryset = models.EstablishmentSubType.objects.select_related('default_image') pagination_class = None + permission_classes = get_permission_classes() class EstablishmentSubtypeRUDView(generics.RetrieveUpdateDestroyAPIView): """Establishment subtype retrieve/update/destroy view.""" serializer_class = serializers.EstablishmentSubTypeBaseSerializer - queryset = models.EstablishmentSubType.objects.all().select_related('default_image') + queryset = models.EstablishmentSubType.objects.select_related('default_image') + permission_classes = get_permission_classes() class EstablishmentGalleryCreateDestroyView(EstablishmentMixinViews, @@ -300,6 +340,7 @@ class EstablishmentGalleryCreateDestroyView(EstablishmentMixinViews, """Resource for a create|destroy gallery for establishment for back-office users.""" lookup_field = 'slug' serializer_class = serializers.EstablishmentBackOfficeGallerySerializer + permission_classes = get_permission_classes() def get_object(self): """ @@ -322,6 +363,7 @@ class EstablishmentGalleryListView(EstablishmentMixinViews, """Resource for returning gallery for establishment for back-office users.""" lookup_field = 'slug' serializer_class = serializers.ImageBaseSerializer + permission_classes = get_permission_classes() def get_object(self): """Override get_object method.""" @@ -344,13 +386,14 @@ class EstablishmentCompanyListCreateView(EstablishmentMixinViews, lookup_field = 'slug' serializer_class = serializers.EstablishmentCompanyListCreateSerializer + permission_classes = get_permission_classes() def get_object(self): """Returns the object the view is displaying.""" - establishment_qs = models.Establishment.objects.all() - filtered_ad_qs = self.filter_queryset(establishment_qs) + establishment_qs = super(EstablishmentCompanyListCreateView, self).get_queryset() + filtered_qs = self.filter_queryset(establishment_qs) - establishment = get_object_or_404(filtered_ad_qs, slug=self.kwargs.get('slug')) + establishment = get_object_or_404(filtered_qs, slug=self.kwargs.get('slug')) # May raise a permission denied self.check_object_permissions(self.request, establishment) @@ -368,10 +411,11 @@ class EstablishmentCompanyRUDView(EstablishmentMixinViews, lookup_field = 'slug' serializer_class = serializers.CompanyBaseSerializer + permission_classes = get_permission_classes() def get_object(self): """Returns the object the view is displaying.""" - establishment_qs = models.Establishment.objects.all() + establishment_qs = super(EstablishmentCompanyRUDView, self).get_queryset() filtered_ad_qs = self.filter_queryset(establishment_qs) establishment = get_object_or_404(filtered_ad_qs, slug=self.kwargs.get('slug')) @@ -389,10 +433,14 @@ class EstablishmentNoteListCreateView(EstablishmentMixinViews, lookup_field = 'slug' serializer_class = serializers.EstablishmentNoteListCreateSerializer + permission_classes = get_permission_classes( + IsEstablishmentAdministrator, + IsEstablishmentManager, + ) def get_object(self): """Returns the object the view is displaying.""" - establishment_qs = models.Establishment.objects.all() + establishment_qs = super(EstablishmentNoteListCreateView, self).get_queryset() filtered_establishment_qs = self.filter_queryset(establishment_qs) establishment = get_object_or_404(filtered_establishment_qs, slug=self.kwargs.get('slug')) @@ -413,10 +461,14 @@ class EstablishmentNoteRUDView(EstablishmentMixinViews, lookup_field = 'slug' serializer_class = serializers.EstablishmentNoteBaseSerializer + permission_classes = get_permission_classes( + IsEstablishmentAdministrator, + IsEstablishmentManager, + ) def get_object(self): """Returns the object the view is displaying.""" - establishment_qs = models.Establishment.objects.all() + establishment_qs = super(EstablishmentNoteRUDView, self).get_queryset() filtered_establishment_qs = self.filter_queryset(establishment_qs) establishment = get_object_or_404(filtered_establishment_qs, slug=self.kwargs.get('slug')) @@ -431,27 +483,39 @@ class EstablishmentNoteRUDView(EstablishmentMixinViews, class EstablishmentEmployeeCreateView(generics.CreateAPIView): serializer_class = serializers.EstablishmentEmployeeCreateSerializer queryset = models.EstablishmentEmployee.objects.all() - # TODO send email to all admins and add endpoint for changing status + permission_classes = get_permission_classes( + IsEstablishmentManager, + IsEstablishmentAdministrator + ) class EstablishmentEmployeeDeleteView(generics.DestroyAPIView): queryset = EstablishmentEmployee.objects.all() - permission_classes = [IsEstablishmentManager | permissions.IsAdminUser] + permission_classes = get_permission_classes( + IsEstablishmentManager, + IsEstablishmentAdministrator + ) class EstablishmentPositionListView(generics.ListAPIView): """Establishment positions list view.""" pagination_class = None - permission_classes = (permissions.AllowAny,) queryset = models.Position.objects.all() serializer_class = serializers.PositionBackSerializer + permission_classes = get_permission_classes( + IsEstablishmentManager, + IsEstablishmentAdministrator + ) class EstablishmentAdminView(generics.ListAPIView): """Establishment admin list view.""" serializer_class = serializers.EstablishmentAdminListSerializer - permission_classes = (permissions.IsAuthenticatedOrReadOnly,) + permission_classes = get_permission_classes( + IsEstablishmentManager, + IsEstablishmentAdministrator + ) def get_queryset(self): establishment = get_object_or_404( @@ -463,12 +527,18 @@ class MenuDishesListCreateView(generics.ListCreateAPIView): """Menu (dessert, main_course, starter) list create view.""" serializer_class = serializers.MenuDishesSerializer queryset = models.Menu.objects.with_schedule_plates_establishment().dishes().distinct() - permission_classes = [IsWineryWineInspector | IsEstablishmentManager] filter_class = filters.MenuDishesBackFilter + permission_classes = get_permission_classes( + IsEstablishmentManager, + IsEstablishmentAdministrator + ) class MenuDishesRUDView(generics.RetrieveUpdateDestroyAPIView): """Menu (dessert, main_course, starter) RUD view.""" serializer_class = serializers.MenuDishesRUDSerializers queryset = models.Menu.objects.dishes().distinct() - permission_classes = [IsWineryWineInspector | IsEstablishmentManager] + permission_classes = get_permission_classes( + IsEstablishmentManager, + IsEstablishmentAdministrator + ) diff --git a/apps/favorites/views.py b/apps/favorites/views.py index 1e7a12b3..626b8c07 100644 --- a/apps/favorites/views.py +++ b/apps/favorites/views.py @@ -1,30 +1,45 @@ """Views for app favorites.""" from rest_framework import generics -from establishment.models import Establishment + from establishment.filters import EstablishmentFilter -from establishment.serializers import EstablishmentBaseSerializer, EstablishmentSimilarSerializer +from establishment.models import Establishment +from establishment.serializers import EstablishmentSimilarSerializer from news.filters import NewsListFilterSet from news.models import News -from news.serializers import NewsBaseSerializer, NewsListSerializer +from news.serializers import NewsListSerializer +from product.filters import ProductFilterSet from product.models import Product from product.serializers import ProductBaseSerializer -from product.filters import ProductFilterSet -from .models import Favorites +from utils.methods import get_permission_classes +from utils.permissions import ( + IsApprovedUser, IsEstablishmentAdministrator, IsWineryWineInspector, + IsRestaurantInspector, IsContentPageManager, IsEstablishmentManager, + IsReviewManager, IsDistilleryLiquorInspector, IsArtisanInspector, + IsGuest, IsModerator, IsProducerFoodInspector, +) -class FavoritesBaseView(generics.GenericAPIView): - """Base view for Favorites.""" - - def get_queryset(self): - """Override get_queryset method.""" - return Favorites.objects.by_user(self.request.user) +class FavoritesPermissionMixin: + """Permissions for application favorites.""" + permission_classes = get_permission_classes( + IsApprovedUser, IsEstablishmentAdministrator, IsWineryWineInspector, + IsRestaurantInspector, IsContentPageManager, IsEstablishmentManager, + IsReviewManager, IsDistilleryLiquorInspector, IsArtisanInspector, + IsModerator, IsProducerFoodInspector, + ) -class FavoritesEstablishmentListView(generics.ListAPIView): +class FavoritesEstablishmentListView(FavoritesPermissionMixin, generics.ListAPIView): """List views for establishments in favorites.""" serializer_class = EstablishmentSimilarSerializer filter_class = EstablishmentFilter + permission_classes = get_permission_classes( + IsApprovedUser, IsEstablishmentAdministrator, IsWineryWineInspector, + IsRestaurantInspector, IsContentPageManager, IsEstablishmentManager, + IsReviewManager, IsDistilleryLiquorInspector, IsArtisanInspector, + IsGuest, IsModerator, IsProducerFoodInspector, + ) def get_queryset(self): """Override get_queryset method""" @@ -36,7 +51,7 @@ class FavoritesEstablishmentListView(generics.ListAPIView): .with_certain_tag_category_related('distillery_type', 'distillery_type') -class FavoritesProductListView(generics.ListAPIView): +class FavoritesProductListView(FavoritesPermissionMixin, generics.ListAPIView): """List views for products in favorites.""" serializer_class = ProductBaseSerializer @@ -48,7 +63,7 @@ class FavoritesProductListView(generics.ListAPIView): .order_by('-favorites') -class FavoritesNewsListView(generics.ListAPIView): +class FavoritesNewsListView(FavoritesPermissionMixin, generics.ListAPIView): """List views for news in favorites.""" serializer_class = NewsListSerializer diff --git a/apps/gallery/views.py b/apps/gallery/views.py index 1515707f..3b5063ba 100644 --- a/apps/gallery/views.py +++ b/apps/gallery/views.py @@ -3,6 +3,8 @@ from django.db.transaction import on_commit from rest_framework import generics, status from rest_framework.response import Response +from utils.methods import get_permission_classes +from utils.permissions import IsContentPageManager from . import tasks, models, serializers @@ -11,6 +13,9 @@ class ImageBaseView(generics.GenericAPIView): model = models.Image queryset = models.Image.objects.all() serializer_class = serializers.ImageSerializer + permission_classes = get_permission_classes( + IsContentPageManager + ) class ImageListCreateView(ImageBaseView, generics.ListCreateAPIView): diff --git a/apps/location/views/back.py b/apps/location/views/back.py index a0d1bd36..b57c315d 100644 --- a/apps/location/views/back.py +++ b/apps/location/views/back.py @@ -1,45 +1,52 @@ """Location app views.""" -from rest_framework import generics from django.contrib.postgres.fields.jsonb import KeyTextTransform -from utils.models import get_current_locale - -from location import models, serializers -from location.views import common -from utils.permissions import IsCountryAdmin -from utils.views import CreateDestroyGalleryViewMixin -from rest_framework.permissions import IsAuthenticatedOrReadOnly -from django.shortcuts import get_object_or_404 -from django.db import IntegrityError -from utils.serializers import ImageBaseSerializer -from location.filters import RegionFilter +from rest_framework import generics from location import filters +from location import models, serializers +from location.filters import RegionFilter +from location.views import common +from utils.methods import get_permission_classes +from utils.models import get_current_locale +from utils.permissions import ( + IsGuest, IsEstablishmentManager, IsEstablishmentAdministrator +) # Address - - class AddressListCreateView(common.AddressViewMixin, generics.ListCreateAPIView): """Create view for model Address.""" serializer_class = serializers.AddressDetailSerializer queryset = models.Address.objects.all() - permission_classes = [IsAuthenticatedOrReadOnly | IsCountryAdmin] + permission_classes = get_permission_classes( + IsEstablishmentManager, + IsEstablishmentAdministrator, + IsGuest, + ) class AddressRUDView(common.AddressViewMixin, generics.RetrieveUpdateDestroyAPIView): """RUD view for model Address.""" serializer_class = serializers.AddressDetailSerializer queryset = models.Address.objects.all() - permission_classes = [IsAuthenticatedOrReadOnly | IsCountryAdmin] + permission_classes = get_permission_classes( + IsEstablishmentManager, + IsEstablishmentAdministrator, + IsGuest, + ) # City class CityListCreateView(common.CityViewMixin, generics.ListCreateAPIView): """Create view for model City.""" serializer_class = serializers.CityBaseSerializer - permission_classes = [IsAuthenticatedOrReadOnly | IsCountryAdmin] queryset = models.City.objects.all() filter_class = filters.CityBackFilter + permission_classes = get_permission_classes( + IsEstablishmentManager, + IsEstablishmentAdministrator, + IsGuest, + ) def get_queryset(self): """Overridden method 'get_queryset'.""" @@ -53,18 +60,26 @@ class CityListCreateView(common.CityViewMixin, generics.ListCreateAPIView): class CityListSearchView(common.CityViewMixin, generics.ListCreateAPIView): """Create view for model City.""" serializer_class = serializers.CityBaseSerializer - permission_classes = [IsAuthenticatedOrReadOnly | IsCountryAdmin] queryset = models.City.objects.all()\ .annotate(locale_name=KeyTextTransform(get_current_locale(), 'name_translated'))\ .order_by('locale_name') filter_class = filters.CityBackFilter pagination_class = None + permission_classes = get_permission_classes( + IsEstablishmentManager, + IsEstablishmentAdministrator, + IsGuest, + ) class CityRUDView(common.CityViewMixin, generics.RetrieveUpdateDestroyAPIView): """RUD view for model City.""" serializer_class = serializers.CityDetailSerializer - permission_classes = [IsAuthenticatedOrReadOnly | IsCountryAdmin] + permission_classes = get_permission_classes( + IsEstablishmentManager, + IsEstablishmentAdministrator, + IsGuest, + ) # Region @@ -72,15 +87,23 @@ class RegionListCreateView(common.RegionViewMixin, generics.ListCreateAPIView): """Create view for model Region""" pagination_class = None serializer_class = serializers.RegionSerializer - permission_classes = [IsAuthenticatedOrReadOnly | IsCountryAdmin] # ordering_fields = 'name' filter_class = RegionFilter + permission_classes = get_permission_classes( + IsEstablishmentManager, + IsEstablishmentAdministrator, + IsGuest, + ) class RegionRUDView(common.RegionViewMixin, generics.RetrieveUpdateDestroyAPIView): """Retrieve view for model Region""" serializer_class = serializers.RegionSerializer - permission_classes = [IsAuthenticatedOrReadOnly | IsCountryAdmin] + permission_classes = get_permission_classes( + IsEstablishmentManager, + IsEstablishmentAdministrator, + IsGuest, + ) # Country @@ -91,11 +114,19 @@ class CountryListCreateView(generics.ListCreateAPIView): .order_by('locale_name') serializer_class = serializers.CountryBackSerializer pagination_class = None - permission_classes = [IsAuthenticatedOrReadOnly | IsCountryAdmin] + permission_classes = get_permission_classes( + IsEstablishmentManager, + IsEstablishmentAdministrator, + IsGuest, + ) class CountryRUDView(generics.RetrieveUpdateDestroyAPIView): """RUD view for model Country.""" serializer_class = serializers.CountryBackSerializer - permission_classes = [IsAuthenticatedOrReadOnly | IsCountryAdmin] queryset = models.Country.objects.all() + permission_classes = get_permission_classes( + IsEstablishmentManager, + IsEstablishmentAdministrator, + IsGuest, + ) diff --git a/apps/main/views/back.py b/apps/main/views/back.py index 23fdc48a..4bb082cb 100644 --- a/apps/main/views/back.py +++ b/apps/main/views/back.py @@ -1,25 +1,26 @@ from django.contrib.contenttypes.models import ContentType from django.utils.translation import gettext_lazy as _ from django_filters.rest_framework import DjangoFilterBackend -from rest_framework import generics, permissions, status +from rest_framework import generics, status from rest_framework.generics import get_object_or_404 from rest_framework.response import Response -from main import serializers -from main.serializers.back import PanelSerializer -from establishment.serializers.back import EmployeeBackSerializers from establishment.models import Employee +from establishment.serializers.back import EmployeeBackSerializers +from main import serializers from main import tasks from main.filters import AwardFilter from main.models import Award, Footer, PageType, Panel, SiteFeature, Feature, AwardType +from main.serializers.back import PanelSerializer from main.views import SiteSettingsView, SiteListView +from utils.methods import get_permission_classes class AwardLstView(generics.ListCreateAPIView): """Award list create view.""" queryset = Award.objects.all().with_base_related() serializer_class = serializers.BackAwardSerializer - permission_classes = (permissions.IsAdminUser,) + permission_classes = get_permission_classes() filterset_class = AwardFilter @@ -27,10 +28,10 @@ class AwardCreateAndBind(generics.CreateAPIView): """Award create and bind to employee by id""" queryset = Award.objects.all().with_base_related() serializer_class = serializers.BackAwardEmployeeCreateSerializer - permission_classes = (permissions.IsAdminUser, ) + permission_classes = get_permission_classes() def create(self, request, *args, **kwargs): - """!!!Overriden!!!""" + """Overridden create method.""" serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) self.perform_create(serializer) @@ -43,7 +44,7 @@ class AwardRUDView(generics.RetrieveUpdateDestroyAPIView): """Award RUD view.""" queryset = Award.objects.all().with_base_related() serializer_class = serializers.BackAwardSerializer - permission_classes = (permissions.IsAdminUser,) + permission_classes = get_permission_classes() lookup_field = 'id' @@ -52,14 +53,14 @@ class AwardTypesListView(generics.ListAPIView): pagination_class = None queryset = AwardType.objects.all() serializer_class = serializers.AwardTypeBaseSerializer - permission_classes = (permissions.AllowAny, ) + permission_classes = get_permission_classes() class ContentTypeView(generics.ListAPIView): """ContentType list view""" queryset = ContentType.objects.all() serializer_class = serializers.ContentTypeBackSerializer - permission_classes = (permissions.IsAdminUser,) + permission_classes = get_permission_classes() filter_backends = (DjangoFilterBackend, ) ordering_fields = '__all__' lookup_field = 'id' @@ -74,6 +75,7 @@ class FeatureBackView(generics.ListCreateAPIView): """Feature list or create View.""" serializer_class = serializers.FeatureSerializer queryset = Feature.objects.all() + permission_classes = get_permission_classes() class SiteFeatureBackView(generics.ListCreateAPIView): @@ -81,79 +83,75 @@ class SiteFeatureBackView(generics.ListCreateAPIView): serializer_class = serializers.SiteFeatureSerializer queryset = SiteFeature.objects.all() pagination_class = None - permission_classes = [permissions.IsAdminUser] + permission_classes = get_permission_classes() class FeatureRUDBackView(generics.RetrieveUpdateDestroyAPIView): """Feature RUD View.""" serializer_class = serializers.FeatureSerializer queryset = SiteFeature.objects.all() - permission_classes = [permissions.IsAdminUser] + permission_classes = get_permission_classes() class SiteFeatureRUDBackView(generics.RetrieveUpdateDestroyAPIView): """Feature RUD View.""" serializer_class = serializers.SiteFeatureSerializer queryset = SiteFeature.objects.all() - permission_classes = [permissions.IsAdminUser] + permission_classes = get_permission_classes() class SiteSettingsBackOfficeView(SiteSettingsView): """Site settings View.""" serializer_class = serializers.SiteSerializer + permission_classes = get_permission_classes() class SiteListBackOfficeView(SiteListView): """Site settings View.""" serializer_class = serializers.SiteSerializer + permission_classes = get_permission_classes() class FooterBackView(generics.ListCreateAPIView): """Footer back list/create view.""" - permission_classes = (permissions.IsAuthenticatedOrReadOnly,) serializer_class = serializers.FooterBackSerializer queryset = Footer.objects.all() + permission_classes = get_permission_classes() class FooterRUDBackView(generics.RetrieveUpdateDestroyAPIView): """Footer back RUD view.""" - permission_classes = (permissions.IsAuthenticatedOrReadOnly,) serializer_class = serializers.FooterBackSerializer queryset = Footer.objects.all() + permission_classes = get_permission_classes() class PageTypeListCreateView(generics.ListCreateAPIView): """PageType back office view.""" - permission_classes = (permissions.IsAuthenticatedOrReadOnly, ) pagination_class = None serializer_class = serializers.PageTypeBaseSerializer queryset = PageType.objects.all() + permission_classes = get_permission_classes() class PanelsListCreateView(generics.ListCreateAPIView): """Custom panels view.""" - permission_classes = ( - permissions.IsAdminUser, - ) serializer_class = PanelSerializer queryset = Panel.objects.all() + permission_classes = get_permission_classes() class PanelsRUDView(generics.RetrieveUpdateDestroyAPIView): """Custom panels view.""" - permission_classes = ( - permissions.IsAdminUser, - ) serializer_class = PanelSerializer queryset = Panel.objects.all() + permission_classes = get_permission_classes() class PanelsExecuteView(generics.ListAPIView): """Custom panels view.""" - permission_classes = ( - permissions.IsAdminUser, - ) queryset = Panel.objects.all() + permission_classes = get_permission_classes() def list(self, request, *args, **kwargs): panel = get_object_or_404(Panel, id=self.kwargs['pk']) @@ -162,8 +160,8 @@ class PanelsExecuteView(generics.ListAPIView): class PanelsExportCSVView(PanelsExecuteView): """Export panels via csv view.""" - permission_classes = (permissions.IsAdminUser,) queryset = Panel.objects.all() + permission_classes = get_permission_classes() def list(self, request, *args, **kwargs): panel = get_object_or_404(Panel, id=self.kwargs['pk']) @@ -178,8 +176,8 @@ class PanelsExportCSVView(PanelsExecuteView): class PanelsExecuteXLSView(PanelsExecuteView): """Export panels via xlsx view.""" - permission_classes = (permissions.IsAdminUser,) queryset = Panel.objects.all() + permission_classes = get_permission_classes() def list(self, request, *args, **kwargs): panel = get_object_or_404(Panel, id=self.kwargs['pk']) diff --git a/apps/news/views.py b/apps/news/views.py index b0454deb..3fc8284e 100644 --- a/apps/news/views.py +++ b/apps/news/views.py @@ -3,15 +3,17 @@ from django.conf import settings from django.http import Http404 from django.shortcuts import get_object_or_404 from django.utils import translation +from django_filters.rest_framework import DjangoFilterBackend from rest_framework import generics, permissions, response from rest_framework.filters import OrderingFilter -from django_filters.rest_framework import DjangoFilterBackend from news import filters, models, serializers from rating.tasks import add_rating -from utils.permissions import IsCountryAdmin, IsContentPageManager, IsReviewManager -from utils.views import CreateDestroyGalleryViewMixin, FavoritesCreateDestroyMixinView, CarouselCreateDestroyMixinView -from utils.serializers import ImageBaseSerializer, EmptySerializer +from utils.methods import get_permission_classes +from utils.permissions import IsContentPageManager +from utils.serializers import ImageBaseSerializer +from utils.views import CreateDestroyGalleryViewMixin, FavoritesCreateDestroyMixinView, \ + CarouselCreateDestroyMixinView class NewsMixinView: @@ -106,7 +108,7 @@ class NewsTypeListView(generics.ListAPIView): class NewsBackOfficeMixinView: """News back office mixin view.""" - permission_classes = (permissions.IsAuthenticated,) + permission_classes = get_permission_classes(IsContentPageManager, IsContentPageManager) def get_queryset(self): """Override get_queryset method.""" @@ -124,11 +126,6 @@ class NewsBackOfficeLCView(NewsBackOfficeMixinView, filter_class = filters.NewsListFilterSet create_serializers_class = serializers.NewsBackOfficeDetailSerializer filter_backends = (OrderingFilter, DjangoFilterBackend) - permission_classes = [ - IsCountryAdmin | - IsContentPageManager | - IsReviewManager - ] ordering_fields = '__all__' @@ -205,9 +202,7 @@ class NewsBackOfficeGalleryListView(NewsBackOfficeMixinView, class NewsBackOfficeRUDView(NewsBackOfficeMixinView, generics.RetrieveUpdateDestroyAPIView): """Resource for detailed information about news for back-office users.""" - serializer_class = serializers.NewsBackOfficeDetailSerializer - permission_classes = [IsCountryAdmin | IsContentPageManager] def get(self, request, pk, *args, **kwargs): add_rating(remote_addr=request.META.get('REMOTE_ADDR'), diff --git a/apps/notification/views/common.py b/apps/notification/views/common.py index a0534d13..bc935ace 100644 --- a/apps/notification/views/common.py +++ b/apps/notification/views/common.py @@ -6,11 +6,11 @@ from rest_framework.response import Response from notification import models from notification.serializers import common as serializers from utils.methods import get_user_ip +from utils.permissions import IsAuthenticatedAndTokenIsValid class CreateSubscribeView(generics.CreateAPIView): """Create subscribe View.""" - queryset = models.Subscriber.objects.all() permission_classes = (permissions.AllowAny,) serializer_class = serializers.CreateAndUpdateSubscribeSerializer @@ -18,7 +18,6 @@ class CreateSubscribeView(generics.CreateAPIView): class UpdateSubscribeView(generics.UpdateAPIView): """Subscribe info view.""" - lookup_field = 'update_code' lookup_url_kwarg = 'code' permission_classes = (permissions.AllowAny,) @@ -28,7 +27,6 @@ class UpdateSubscribeView(generics.UpdateAPIView): class SubscribeInfoView(generics.RetrieveAPIView): """Subscribe info view.""" - lookup_field = 'update_code' lookup_url_kwarg = 'code' permission_classes = (permissions.AllowAny,) @@ -38,8 +36,7 @@ class SubscribeInfoView(generics.RetrieveAPIView): class SubscribeInfoAuthUserView(generics.RetrieveAPIView): """Subscribe info auth user view.""" - - permission_classes = (permissions.IsAuthenticated,) + permission_classes = (IsAuthenticatedAndTokenIsValid,) serializer_class = serializers.SubscribeSerializer lookup_field = None @@ -62,7 +59,6 @@ class SubscribeInfoAuthUserView(generics.RetrieveAPIView): class UnsubscribeView(generics.UpdateAPIView): """Unsubscribe view.""" - lookup_field = 'update_code' lookup_url_kwarg = 'code' permission_classes = (permissions.AllowAny,) @@ -78,8 +74,7 @@ class UnsubscribeView(generics.UpdateAPIView): class UnsubscribeAuthUserView(generics.GenericAPIView): """Unsubscribe auth user view.""" - - permission_classes = (permissions.IsAuthenticated,) + permission_classes = (IsAuthenticatedAndTokenIsValid,) queryset = models.Subscriber.objects.all() serializer_class = serializers.SubscribeSerializer diff --git a/apps/partner/views/back.py b/apps/partner/views/back.py index 1033d0ee..aba096e6 100644 --- a/apps/partner/views/back.py +++ b/apps/partner/views/back.py @@ -1,9 +1,10 @@ -from django_filters.rest_framework import DjangoFilterBackend, filters -from rest_framework import generics, permissions +from django_filters.rest_framework import DjangoFilterBackend +from rest_framework import generics from partner.models import Partner from partner.serializers import back as serializers -from utils.permissions import IsEstablishmentManager +from utils.methods import get_permission_classes +from utils.permissions import IsEstablishmentManager, IsEstablishmentAdministrator class PartnerLstView(generics.ListCreateAPIView): @@ -11,8 +12,11 @@ class PartnerLstView(generics.ListCreateAPIView): queryset = Partner.objects.all() serializer_class = serializers.BackPartnerSerializer pagination_class = None - permission_classes = [permissions.IsAdminUser | IsEstablishmentManager] filter_backends = (DjangoFilterBackend,) + permission_classes = get_permission_classes( + IsEstablishmentManager, + IsEstablishmentAdministrator + ) filterset_fields = ( 'establishment', 'type', @@ -23,5 +27,8 @@ class PartnerRUDView(generics.RetrieveUpdateDestroyAPIView): """Partner RUD view.""" queryset = Partner.objects.all() serializer_class = serializers.BackPartnerSerializer - permission_classes = [permissions.IsAdminUser | IsEstablishmentManager] lookup_field = 'id' + permission_classes = get_permission_classes( + IsEstablishmentManager, + IsEstablishmentAdministrator + ) diff --git a/apps/product/models.py b/apps/product/models.py index e2584be0..068350e4 100644 --- a/apps/product/models.py +++ b/apps/product/models.py @@ -9,15 +9,14 @@ from django.core.validators import MaxValueValidator, MinValueValidator from django.db import models from django.db.models import Case, When, F from django.utils.translation import gettext_lazy as _ -from django.db.models import Subquery from location.models import WineOriginAddressMixin from review.models import Review +from utils.methods import transform_into_readable_str from utils.models import (BaseAttributes, ProjectBaseMixin, HasTagsMixin, TranslatedFieldsMixin, TJSONField, FavoritesMixin, GalleryMixin, IntermediateGalleryModelMixin, TypeDefaultImageMixin) -from utils.methods import transform_into_readable_str class ProductType(TypeDefaultImageMixin, TranslatedFieldsMixin, ProjectBaseMixin): @@ -229,21 +228,26 @@ class ProductQuerySet(models.QuerySet): 'id') def available_products(self, user): - """Return QuerySet with products that is available for editing.""" + """Return QuerySet with establishment that user has an access.""" from account.models import UserRole - available_ids = Subquery( - UserRole.objects.filter(user=user) - .distinct('user', 'establishment') - .values_list('establishment__products', flat=True) - ) - return self.filter(id__in=available_ids) + administrator_establishment_ids = [] + filters = {} - def available_objects(self, user): - access_roles = user.userrole_set.has_access_to_products() - if access_roles.exists(): - return self.available_products(user) - return self.none() + # put in array administrated establishment ids + if user.is_establishment_administrator: + administrator_establishment_ids.extend( + UserRole.objects.filter(user=user) + .distinct('user', 'establishment') + .values_list('establishment', flat=True) + ) + # check if user is_staff + if not user.is_staff: + filters.update({'establishment__address__city__country__code__in': user.administrated_country_codes}) + + return self.filter(**filters).union( + self.filter(establishment__id__in=administrator_establishment_ids) + ) class Product(GalleryMixin, TranslatedFieldsMixin, BaseAttributes, diff --git a/apps/product/views/back.py b/apps/product/views/back.py index fb0d3f82..639f6bf0 100644 --- a/apps/product/views/back.py +++ b/apps/product/views/back.py @@ -1,12 +1,12 @@ """Product app back-office views.""" from django.shortcuts import get_object_or_404 -from rest_framework import generics, status, permissions, views +from rest_framework import generics, status from rest_framework.response import Response from product import serializers, models from product.views import ProductBaseView +from utils.methods import get_permission_classes from utils.permissions import ( - IsDistilleryLiquorInspector, IsProducerFoodInspector, IsEstablishmentManager, IsEstablishmentAdministrator) from utils.serializers import ImageBaseSerializer from utils.views import CreateDestroyGalleryViewMixin @@ -14,41 +14,36 @@ from utils.views import CreateDestroyGalleryViewMixin class ProductBackOfficeMixinView(ProductBaseView): """Product back-office mixin view.""" - - permission_classes = (permissions.IsAuthenticated, ) + permission_classes = get_permission_classes( + IsEstablishmentAdministrator, + IsEstablishmentManager + ) def get_queryset(self): """Override get_queryset method.""" - qs = models.Product.objects.with_extended_related().annotate_in_favorites(self.request.user) - return qs + queryset = ( + models.Product.objects.with_base_related() + .with_extended_related() + .annotate_in_favorites(self.request.user) + ) + if hasattr(self, 'request') and \ + (hasattr(self.request, 'user') and hasattr(self.request, 'country_code')): + return queryset.available_products(self.request.user) + return queryset.none() class ProductTypeBackOfficeMixinView: """Product type back-office mixin view.""" - - permission_classes = (permissions.IsAuthenticated,) + permission_classes = get_permission_classes() queryset = models.ProductType.objects.all() class ProductSubTypeBackOfficeMixinView: """Product sub type back-office mixin view.""" - - permission_classes = (permissions.IsAuthenticated,) + permission_classes = get_permission_classes() queryset = models.ProductSubType.objects.all() -class BackOfficeListCreateMixin(views.APIView): - """Back-office list-create mixin view.""" - - def check_permissions(self, request): - """ - Check if the request should be permitted. - Raises an appropriate exception if the request is not permitted. - """ - if self.request.method != 'GET': - super().check_permissions(request) - - class ProductBackOfficeGalleryCreateDestroyView(ProductBackOfficeMixinView, CreateDestroyGalleryViewMixin): """Resource for a create gallery for product for back-office users.""" @@ -58,7 +53,7 @@ class ProductBackOfficeGalleryCreateDestroyView(ProductBackOfficeMixinView, """ Returns the object the view is displaying. """ - product_qs = self.filter_queryset(self.get_queryset()) + product_qs = self.get_queryset() product = get_object_or_404(product_qs, pk=self.kwargs.get('pk')) gallery = get_object_or_404(product.product_gallery, image_id=self.kwargs.get('image_id')) @@ -73,7 +68,6 @@ class ProductBackOfficeGalleryListView(ProductBackOfficeMixinView, generics.ListAPIView): """Resource for returning gallery for product for back-office users.""" serializer_class = ImageBaseSerializer - permission_classes = (permissions.IsAuthenticated,) def get_object(self): """Override get_object method.""" @@ -94,40 +88,21 @@ class ProductDetailBackOfficeView(ProductBackOfficeMixinView, generics.RetrieveUpdateDestroyAPIView): """Product back-office R/U/D view.""" serializer_class = serializers.ProductBackOfficeDetailSerializer - permission_classes = [ - # IsLiquorReviewer | - # IsProductReviewer | - IsEstablishmentManager | - IsEstablishmentAdministrator - ] class ProductListCreateBackOfficeView(ProductBackOfficeMixinView, generics.ListCreateAPIView): """Product back-office list-create view.""" serializer_class = serializers.ProductBackOfficeDetailSerializer - permission_classes = [ - IsDistilleryLiquorInspector | - IsProducerFoodInspector | - IsEstablishmentAdministrator | - IsEstablishmentManager - ] - - def get_queryset(self): - """Overridden get_queryset method.""" - qs = super(ProductListCreateBackOfficeView, self).get_queryset() - return qs.available_objects(self.request.user) -class ProductTypeListCreateBackOfficeView(BackOfficeListCreateMixin, - ProductTypeBackOfficeMixinView, +class ProductTypeListCreateBackOfficeView(ProductTypeBackOfficeMixinView, generics.ListCreateAPIView): """Product type back-office list-create view.""" serializer_class = serializers.ProductTypeBackOfficeDetailSerializer -class ProductTypeRUDBackOfficeView(BackOfficeListCreateMixin, - ProductTypeBackOfficeMixinView, +class ProductTypeRUDBackOfficeView(ProductTypeBackOfficeMixinView, generics.RetrieveUpdateDestroyAPIView): """Product type back-office retrieve-update-destroy view.""" serializer_class = serializers.ProductTypeBackOfficeDetailSerializer @@ -143,22 +118,19 @@ class ProductTypeTagCategoryCreateBackOfficeView(ProductTypeBackOfficeMixinView, return Response(status=status.HTTP_201_CREATED) -class ProductSubTypeListCreateBackOfficeView(BackOfficeListCreateMixin, - ProductSubTypeBackOfficeMixinView, +class ProductSubTypeListCreateBackOfficeView(ProductSubTypeBackOfficeMixinView, generics.ListCreateAPIView): """Product sub type back-office list-create view.""" serializer_class = serializers.ProductSubTypeBackOfficeDetailSerializer -class ProductSubTypeRUDBackOfficeView(BackOfficeListCreateMixin, - ProductSubTypeBackOfficeMixinView, +class ProductSubTypeRUDBackOfficeView(ProductSubTypeBackOfficeMixinView, generics.RetrieveUpdateDestroyAPIView): """Product sub type back-office retrieve-update-destroy view.""" serializer_class = serializers.ProductSubTypeBackOfficeDetailSerializer class ProductNoteListCreateView(ProductBackOfficeMixinView, - BackOfficeListCreateMixin, generics.ListCreateAPIView): """Retrieve|Update|Destroy product note view.""" @@ -166,7 +138,7 @@ class ProductNoteListCreateView(ProductBackOfficeMixinView, def get_object(self): """Returns the object the view is displaying.""" - product_qs = models.Product.objects.all() + product_qs = super(ProductNoteListCreateView, self).get_queryset() filtered_product_qs = self.filter_queryset(product_qs) product = get_object_or_404(filtered_product_qs, pk=self.kwargs.get('pk')) @@ -182,7 +154,6 @@ class ProductNoteListCreateView(ProductBackOfficeMixinView, class ProductNoteRUDView(ProductBackOfficeMixinView, - BackOfficeListCreateMixin, generics.RetrieveUpdateDestroyAPIView): """Create|Retrieve|Update|Destroy product note view.""" @@ -190,7 +161,7 @@ class ProductNoteRUDView(ProductBackOfficeMixinView, def get_object(self): """Returns the object the view is displaying.""" - product_qs = models.Product.objects.all() + product_qs = super(ProductNoteRUDView, self).get_queryset() filtered_product_qs = self.filter_queryset(product_qs) product = get_object_or_404(filtered_product_qs, pk=self.kwargs.get('pk')) diff --git a/apps/recipe/views/common.py b/apps/recipe/views/common.py index 31e74f20..cfce158b 100644 --- a/apps/recipe/views/common.py +++ b/apps/recipe/views/common.py @@ -1,16 +1,18 @@ """Recipe app common views.""" from django.utils import translation -from rest_framework import generics, permissions +from rest_framework import generics from recipe import models from recipe.serializers import common as serializers +from utils.methods import get_permission_classes +from utils.permissions import IsContentPageManager class RecipeViewMixin(generics.GenericAPIView): """Recipe view mixin.""" pagination_class = None - permission_classes = (permissions.AllowAny,) + permission_classes = get_permission_classes(IsContentPageManager) def get_queryset(self, *args, **kwargs): user = self.request.user diff --git a/apps/review/models.py b/apps/review/models.py index a987cf2e..f17629ba 100644 --- a/apps/review/models.py +++ b/apps/review/models.py @@ -1,11 +1,8 @@ """Review app models.""" -from pprint import pprint from django.contrib.contenttypes import fields as generic from django.core.validators import MinValueValidator, MaxValueValidator from django.db import models -from django.db.models.signals import post_init, post_save -from django.dispatch import receiver from django.utils.translation import gettext_lazy as _ from utils.models import (BaseAttributes, TranslatedFieldsMixin, @@ -16,6 +13,15 @@ from utils.models import (BaseAttributes, TranslatedFieldsMixin, class ReviewQuerySet(models.QuerySet): """QuerySets for model Review""" + def with_base_related(self): + """Return QuerySet with base related.""" + return self.select_related( + 'reviewer', + 'country', + 'child', + 'content_type', + ) + def by_reviewer(self, user): """Return reviews by user""" return self.filter(reviewer=user) diff --git a/apps/review/views/back.py b/apps/review/views/back.py index d1e470db..0b2f7b42 100644 --- a/apps/review/views/back.py +++ b/apps/review/views/back.py @@ -1,21 +1,30 @@ -from rest_framework import generics, permissions +from rest_framework import generics from review import filters from review import models from review import serializers -from utils.permissions import IsReviewManager, IsRestaurantInspector from review.serializers.back import ReviewBackSerializer +from utils.methods import get_permission_classes +from utils.permissions import ( + IsReviewManager, IsRestaurantInspector, IsWineryWineInspector, + IsArtisanInspector, IsProducerFoodInspector, IsDistilleryLiquorInspector, +) + + +class PermissionMixinView: + """Permission mixin view.""" + permission_classes = get_permission_classes( + IsReviewManager, IsRestaurantInspector, IsWineryWineInspector, + IsArtisanInspector, IsProducerFoodInspector, IsDistilleryLiquorInspector, + ) class ReviewMixinView: """Review mixin.""" - - def get_queryset(self): - """Overridden method 'get_queryset'.""" - return models.Review.objects.all() + queryset = models.Review.objects.with_base_related() -class ReviewListView(ReviewMixinView, generics.ListCreateAPIView): +class ReviewListView(PermissionMixinView, ReviewMixinView, generics.ListCreateAPIView): """Review list create view. status values: @@ -25,16 +34,10 @@ class ReviewListView(ReviewMixinView, generics.ListCreateAPIView): READY = 2 """ serializer_class = ReviewBackSerializer - queryset = models.Review.objects.all() - permission_classes = [permissions.IsAuthenticatedOrReadOnly, ] filterset_class = filters.ReviewFilter - def get_queryset(self): - """Overridden get_queryset method.""" - return super(ReviewListView, self).get_queryset() - -class ReviewRUDView(generics.RetrieveUpdateDestroyAPIView): +class ReviewRUDView(PermissionMixinView, ReviewMixinView, generics.RetrieveUpdateDestroyAPIView): """Review RUD view. status values: @@ -44,17 +47,14 @@ class ReviewRUDView(generics.RetrieveUpdateDestroyAPIView): READY = 2 """ serializer_class = ReviewBackSerializer - queryset = models.Review.objects.all() - permission_classes = [permissions.IsAdminUser | IsReviewManager | IsRestaurantInspector] lookup_field = 'id' -class InquiriesListView(generics.ListCreateAPIView): +class InquiriesListView(PermissionMixinView, generics.ListCreateAPIView): """Inquiries list create view.""" serializer_class = serializers.InquiriesBaseSerializer queryset = models.Inquiries.objects.all() - permission_classes = (permissions.IsAuthenticatedOrReadOnly,) def get_queryset(self): review_id = self.kwargs.get('review_id') @@ -63,19 +63,17 @@ class InquiriesListView(generics.ListCreateAPIView): return super().get_queryset() -class InquiriesRUDView(generics.RetrieveUpdateDestroyAPIView): +class InquiriesRUDView(PermissionMixinView, generics.RetrieveUpdateDestroyAPIView): """Inquiries RUD view.""" serializer_class = serializers.InquiriesBaseSerializer queryset = models.Inquiries.objects.all() - permission_classes = (permissions.IsAuthenticatedOrReadOnly,) lookup_field = 'id' -class GridItemsListView(generics.ListCreateAPIView): +class GridItemsListView(PermissionMixinView, generics.ListCreateAPIView): """GridItems list create view.""" serializer_class = serializers.GridItemsBaseSerializer queryset = models.GridItems.objects.all() - permission_classes = (permissions.IsAuthenticatedOrReadOnly,) def get_queryset(self): inquiry_id = self.kwargs.get('inquiry_id') @@ -84,9 +82,8 @@ class GridItemsListView(generics.ListCreateAPIView): return super().get_queryset() -class GridItemsRUDView(generics.RetrieveUpdateDestroyAPIView): +class GridItemsRUDView(PermissionMixinView, generics.RetrieveUpdateDestroyAPIView): """GridItems RUD view.""" serializer_class = serializers.GridItemsBaseSerializer queryset = models.GridItems.objects.all() - permission_classes = (permissions.IsAuthenticatedOrReadOnly,) lookup_field = 'id' diff --git a/apps/tag/views.py b/apps/tag/views.py index 41fbd77b..8e22f9e4 100644 --- a/apps/tag/views.py +++ b/apps/tag/views.py @@ -4,6 +4,7 @@ from django.contrib.contenttypes.models import ContentType from django.utils.translation import gettext_lazy as _ from rest_framework import generics, mixins, permissions, status, viewsets from rest_framework.decorators import action +from rest_framework.permissions import IsAdminUser from rest_framework.response import Response from rest_framework.serializers import ValidationError @@ -11,6 +12,9 @@ from location.models import WineRegion from product.models import ProductType from search_indexes import views as search_views from tag import filters, models, serializers +from utils.permissions import ( + IsEstablishmentManager +) class ChosenTagsView(generics.ListAPIView, viewsets.GenericViewSet): @@ -334,7 +338,9 @@ class TagBackOfficeViewSet(mixins.ListModelMixin, mixins.CreateModelMixin, """List/create tag view.""" pagination_class = None - permission_classes = (permissions.IsAdminUser,) + permission_classes = [ + IsAdminUser, IsEstablishmentManager + ] queryset = models.Tag.objects.with_base_related() serializer_class = serializers.TagBackOfficeSerializer bind_object_serializer_class = serializers.TagBindObjectSerializer @@ -388,10 +394,12 @@ class TagCategoryBackOfficeViewSet(mixins.CreateModelMixin, TagCategoryViewSet): """ViewSet for TagCategory model for BackOffice users.""" - permission_classes = (permissions.IsAdminUser,) queryset = TagCategoryViewSet.queryset.with_extended_related() serializer_class = serializers.TagCategoryBackOfficeDetailSerializer bind_object_serializer_class = serializers.TagCategoryBindObjectSerializer + permission_classes = [ + IsAdminUser, IsEstablishmentManager + ] def perform_binding(self, serializer): data = serializer.validated_data diff --git a/apps/utils/methods.py b/apps/utils/methods.py index 58cc3f52..a89f9b03 100644 --- a/apps/utils/methods.py +++ b/apps/utils/methods.py @@ -8,12 +8,12 @@ from functools import reduce from io import BytesIO import requests +from PIL import Image from django.conf import settings from django.contrib.contenttypes.models import ContentType from django.contrib.gis.geos import Point from django.http.request import HttpRequest from django.utils.timezone import datetime -from PIL import Image from rest_framework import status from rest_framework.request import Request @@ -216,3 +216,17 @@ def get_image_meta_by_url(url) -> (int, int, int): image = Image.open(BytesIO(image_raw.content)) width, height = image.size return int(image_raw.headers.get('content-length')), width, height + + +def get_permission_classes(*args) -> list: + """Return permission_class object with admin permissions.""" + from rest_framework.permissions import IsAdminUser + from utils.permissions import IsCountryAdmin + + admin_permission_classes = [IsCountryAdmin, IsAdminUser] + permission_classes = [ + reduce( + lambda a, b: a | b, admin_permission_classes + list(args) + ) + ] + return permission_classes diff --git a/apps/utils/permissions.py b/apps/utils/permissions.py index 2ea32b18..af6a0806 100644 --- a/apps/utils/permissions.py +++ b/apps/utils/permissions.py @@ -65,11 +65,8 @@ class IsGuest(permissions.IsAuthenticatedOrReadOnly): ] return all(rules) - def has_object_permission(self, request, view, obj): - return self.has_permission(request, view) - -class IsApprovedUser(permissions.IsAuthenticated): +class IsApprovedUser(IsAuthenticatedAndTokenIsValid): """ Object-level permission to only allow owners of an object to edit it. Assumes the model instance has an `owner` attribute. @@ -122,7 +119,6 @@ class IsCountryAdmin(IsApprovedUser): super().has_permission(request, view) ] has_permission = False - # check role if (request.user.is_authenticated and hasattr(request, 'country_code') and request.country_code): role = Role.objects.filter( @@ -148,7 +144,6 @@ class IsModerator(IsApprovedUser): super().has_permission(request, view) ] has_permission = False - # check role if (request.user.is_authenticated and hasattr(request, 'country_code') and request.country_code): role = Role.objects.filter( @@ -170,7 +165,6 @@ class IsEstablishmentManager(IsApprovedUser): super().has_permission(request, view) ] has_permission = False - # check role if (request.user.is_authenticated and hasattr(request, 'country_code') and request.country_code): @@ -194,7 +188,6 @@ class IsEstablishmentAdministrator(IsApprovedUser): super().has_permission(request, view) ] has_permission = False - # check role if (request.user.is_authenticated and hasattr(request, 'country_code') and request.country_code): @@ -243,7 +236,6 @@ class IsReviewManager(IsApprovedUser): super().has_permission(request, view) ] has_permission = False - # check role if (request.user.is_authenticated and hasattr(request, 'country_code') and request.country_code): @@ -277,7 +269,6 @@ class IsRestaurantInspector(IsApprovedUser): super().has_permission(request, view) ] has_permission = False - # check role if (request.user.is_authenticated and hasattr(request, 'country_code') and request.country_code): @@ -311,7 +302,6 @@ class IsArtisanInspector(IsApprovedUser): super().has_permission(request, view) ] has_permission = False - # check role if (request.user.is_authenticated and hasattr(request, 'country_code') and request.country_code): @@ -345,7 +335,6 @@ class IsWineryWineInspector(IsApprovedUser): super().has_permission(request, view) ] has_permission = False - # check role if (request.user.is_authenticated and hasattr(request, 'country_code') and request.country_code): @@ -379,7 +368,6 @@ class IsProducerFoodInspector(IsApprovedUser): super().has_permission(request, view) ] has_permission = False - # check role if (request.user.is_authenticated and hasattr(request, 'country_code') and request.country_code): @@ -413,7 +401,6 @@ class IsDistilleryLiquorInspector(IsApprovedUser): super().has_permission(request, view) ] has_permission = False - # check role if (request.user.is_authenticated and hasattr(request, 'country_code') and request.country_code):