refactored roles

This commit is contained in:
Anatoly 2020-01-30 12:50:14 +03:00
parent 25c63b8097
commit ca5440d431
9 changed files with 66 additions and 79 deletions

View File

@ -1,6 +1,7 @@
"""Account models"""
from collections import Counter
from datetime import datetime
from typing import List
from django.conf import settings
from django.contrib.auth.models import AbstractUser, UserManager as BaseUserManager
@ -15,8 +16,6 @@ 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 typing import List
from authorization.models import Application
from establishment.models import Establishment, EstablishmentSubType
@ -74,16 +73,6 @@ class Role(ProjectBaseMixin):
(ARTISAN_INSPECTOR, _('Artisan inspector')),
)
ESTABLISHMENT_EDITORS = [
COUNTRY_ADMIN,
ESTABLISHMENT_MANAGER,
ESTABLISHMENT_ADMINISTRATOR,
]
PRODUCT_EDITORS = ESTABLISHMENT_EDITORS + [
DISTILLERY_LIQUOR_INSPECTOR
]
role = models.PositiveIntegerField(verbose_name=_('Role'), choices=ROLE_CHOICES,
null=False, blank=False)
country = models.ForeignKey(Country, verbose_name=_('Country'),

View File

@ -14,7 +14,7 @@ from django.contrib.postgres.fields import ArrayField
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.core.validators import MinValueValidator, MaxValueValidator
from django.db import models
from django.db.models import When, Case, F, ExpressionWrapper, Subquery, Q, Prefetch
from django.shortcuts import get_object_or_404
@ -519,27 +519,22 @@ class EstablishmentQuerySet(models.QuerySet):
to_attr='main_image')
)
def available_establishments(self, user):
"""Return QuerySet with establishment that user has an access."""
def available_establishments(self, user, country_code: str):
"""Return QuerySet with establishments that user has an access."""
from account.models import UserRole
administrator_establishment_ids = []
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})
return self.filter(**filters).union(
self.filter(id__in=administrator_establishment_ids)
)
filters = {'address__city__country__code': country_code}
if user.is_establishment_administrator and not user.is_establishment_manager:
filters.update({
'id__in': models.Subquery(
UserRole.objects.filter(user=user, role__site__country__code=country_code)
.distinct('user', 'establishment')
.values_list('establishment', flat=True)
)
})
return self.filter(**filters)
return self
def with_contacts(self):
return self.prefetch_related('emails', 'phones')

View File

@ -3,7 +3,7 @@ from django.db.models.query_utils import Q
from django.http import Http404
from django.shortcuts import get_object_or_404
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework import generics, status, permissions
from rest_framework import generics, status
from rest_framework.response import Response
from account.models import User
@ -13,8 +13,7 @@ from timetable.models import Timetable
from timetable.serialziers import ScheduleCreateSerializer, ScheduleRUDSerializer
from utils.methods import get_permission_classes
from utils.permissions import (
IsEstablishmentManager, IsEstablishmentAdministrator, IsReviewManager,
)
IsEstablishmentManager, IsEstablishmentAdministrator, )
from utils.views import CreateDestroyGalleryViewMixin
@ -40,7 +39,7 @@ class EstablishmentMixinViews:
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().available_establishments(self.request.user, self.request.country_code)
return queryset().none()

View File

@ -1,15 +1,16 @@
"""News app models."""
import uuid
from datetime import datetime
import elasticsearch_dsl
from django.conf import settings
from django.contrib.contenttypes import fields as generic
from django.contrib.contenttypes.models import ContentType
from django.contrib.postgres.fields import HStoreField
from django.contrib.postgres.search import TrigramSimilarity
from django.db import models
from django.db.models import Case, When, Q, F
from django.db.models.functions import Cast
from django.contrib.postgres.search import TrigramSimilarity
from django.urls.exceptions import NoReverseMatch
from django.utils import timezone
from django.utils.translation import gettext_lazy as _
@ -21,7 +22,6 @@ from utils.models import (BaseAttributes, TJSONField, TranslatedFieldsMixin, Has
ProjectBaseMixin, GalleryMixin, IntermediateGalleryModelMixin,
FavoritesMixin, TypeDefaultImageMixin)
from utils.querysets import TranslationQuerysetMixin
from datetime import datetime
class Agenda(ProjectBaseMixin, TranslatedFieldsMixin):
@ -244,6 +244,10 @@ class NewsQuerySet(TranslationQuerysetMixin):
'subtitle_similarity'))
).filter(relevance__gte=0.3).order_by('-relevance')
def available_news(self, user, country_code: str):
"""Return QuerySet with news that user has an access."""
return self.filter(site__country__code=country_code) if not user.is_staff else self
class News(GalleryMixin, BaseAttributes, TranslatedFieldsMixin, HasTagsMixin,
FavoritesMixin):

View File

@ -129,11 +129,18 @@ class NewsBackOfficeMixinView:
permission_classes = get_permission_classes(IsContentPageManager, IsContentPageManager)
def get_queryset(self):
"""Override get_queryset method."""
qs = models.News.objects.with_base_related() \
.annotate_in_favorites(self.request.user) \
.order_by('-is_highlighted', '-created')
return qs
"""Overridden get_queryset method."""
queryset = models.News.objects
if hasattr(self, 'request') and \
(hasattr(self.request, 'user') and hasattr(self.request, 'country_code')):
user = self.request.user
return (
queryset.with_base_related()
.annotate_in_favorites(user)
.available_news(user, self.request.country_code)
.order_by('-is_highlighted', '-created')
)
return queryset.none()
class NewsBackOfficeLCView(NewsBackOfficeMixinView,
@ -165,8 +172,6 @@ class NewsBackOfficeLCView(NewsBackOfficeMixinView,
self.request.query_params['ordering'] = self.request.query_params['ordering']\
.replace('publication_datetime', 'publication_date,publication_time')
self.request.GET._mutable = False
if self.request.country_code:
qs = qs.by_country_code(self.request.country_code)
return qs

View File

@ -17,24 +17,24 @@ class PartnerLstView(generics.ListCreateAPIView):
queryset = Partner.objects.with_base_related()
serializer_class = serializers.BackPartnerSerializer
pagination_class = None
filter_class = filters.PartnerFilterSet
permission_classes = get_permission_classes(
IsEstablishmentManager,
IsEstablishmentAdministrator
)
filter_class = filters.PartnerFilterSet
class EstablishmentPartners(generics.ListAPIView):
queryset = PartnerToEstablishment.objects.prefetch_related('partner', 'partner__country')
serializer_class = serializers.PartnersForEstablishmentSerializer
pagination_class = None
filter_backends = (OrderingFilter, DjangoFilterBackend)
ordering_fields = '__all__'
ordering = '-partner_bind_date'
permission_classes = get_permission_classes(
IsEstablishmentManager,
IsEstablishmentAdministrator
)
filter_backends = (OrderingFilter, DjangoFilterBackend)
ordering_fields = '__all__'
ordering = '-partner_bind_date'
def get_queryset(self):
return super().get_queryset().filter(establishment=self.kwargs['establishment_id'])

View File

@ -227,27 +227,22 @@ class ProductQuerySet(models.QuerySet):
.distinct(*similarity_rules['distinction'],
'id')
def available_products(self, user):
"""Return QuerySet with establishment that user has an access."""
def available_products(self, user, country_code: str):
"""Return QuerySet with products that user has an access."""
from account.models import UserRole
administrator_establishment_ids = []
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({'establishment__address__city__country__code__in': user.administrated_country_codes})
return self.filter(**filters).union(
self.filter(establishment__id__in=administrator_establishment_ids)
)
filters = {'establishment__address__city__country__code': country_code}
if user.is_establishment_administrator and not user.is_establishment_manager:
filters.update({
'establishment__id__in': models.Subquery(
UserRole.objects.filter(user=user, role__site__country__code=country_code)
.distinct('user', 'establishment')
.values_list('establishment', flat=True)
)
})
return self.filter(**filters)
return self
class Product(GalleryMixin, TranslatedFieldsMixin, BaseAttributes,

View File

@ -28,7 +28,7 @@ class ProductBackOfficeMixinView(ProductBaseView):
)
if hasattr(self, 'request') and \
(hasattr(self.request, 'user') and hasattr(self.request, 'country_code')):
return queryset.available_products(self.request.user)
return queryset.available_products(self.request.user, self.request.country_code)
return queryset.none()

View File

@ -100,7 +100,7 @@ class IsContentPageManager(IsApprovedUser):
role=Role.CONTENT_PAGE_MANAGER, site__country__code=request.country_code,
).only('id')
if role.exists():
user_role = UserRole.objects.filter(
user_role = UserRole.objects.validated().filter(
user=request.user, role__id__in=role.values_list('id', flat=True),
).only('id')
has_permission = True if user_role.exists() else has_permission
@ -125,7 +125,7 @@ class IsCountryAdmin(IsApprovedUser):
role=Role.COUNTRY_ADMIN, site__country__code=request.country_code,
).only('id')
if role.exists():
user_role = UserRole.objects.filter(
user_role = UserRole.objects.validated().filter(
user=request.user, role__id__in=role.values_list('id', flat=True)
).only('id')
has_permission = True if user_role.exists() else has_permission
@ -150,7 +150,7 @@ class IsModerator(IsApprovedUser):
role=Role.MODERATOR, site__country__code=request.country_code,
).only('id')
if role.exists():
user_role = UserRole.objects.filter(
user_role = UserRole.objects.validated().filter(
user=request.user, role__id__in=role.values_list('id', flat=True),
).only('id')
has_permission = True if user_role.exists() else has_permission
@ -173,7 +173,7 @@ class IsEstablishmentManager(IsApprovedUser):
role=Role.ESTABLISHMENT_MANAGER, site__country__code=request.country_code,
).only('id')
if role.exists():
user_role = UserRole.objects.filter(
user_role = UserRole.objects.validated().filter(
user=user, role__id__in=role.values_list('id', flat=True),
).only('id')
has_permission = True if user_role.exists() else has_permission
@ -195,7 +195,7 @@ class IsEstablishmentAdministrator(IsApprovedUser):
role=Role.ESTABLISHMENT_ADMINISTRATOR, site__country__code=request.country_code,
).only('id')
if role.exists():
user_role = UserRole.objects.filter(
user_role = UserRole.objects.validated().filter(
user=request.user, role__id__in=role.values_list('id', flat=True),
).only('id')
has_permission = True if user_role.exists() else has_permission
@ -218,7 +218,7 @@ class IsEstablishmentAdministrator(IsApprovedUser):
if isinstance(obj, Product):
filters.update({'establishment__products__id': obj.id})
user_role = UserRole.objects.filter(**filters)
user_role = UserRole.objects.validated().filter(**filters)
has_object_permission = True if user_role.exists() else has_object_permission
rules.append(has_object_permission)
return all(rules)
@ -243,7 +243,7 @@ class IsReviewManager(IsApprovedUser):
role=Role.REVIEW_MANAGER, site__country__code=request.country_code,
).only('id')
if role.exists():
user_role = UserRole.objects.filter(
user_role = UserRole.objects.validated().filter(
user=request.user, role__id__in=role.values_list('id', flat=True),
).only('id')
if user_role.exists():
@ -276,7 +276,7 @@ class IsRestaurantInspector(IsApprovedUser):
role=Role.RESTAURANT_INSPECTOR, site__country__code=request.country_code,
).only('id')
if role.exists():
user_role = UserRole.objects.filter(
user_role = UserRole.objects.validated().filter(
user=request.user, role__id__in=role.values_list('id', flat=True),
).only('id')
if user_role.exists():
@ -309,7 +309,7 @@ class IsArtisanInspector(IsApprovedUser):
role=Role.ARTISAN_INSPECTOR, site__country__code=request.country_code,
).only('id')
if role.exists():
user_role = UserRole.objects.filter(
user_role = UserRole.objects.validated().filter(
user=request.user, role__id__in=role.values_list('id', flat=True),
).only('id')
if user_role.exists():
@ -342,7 +342,7 @@ class IsWineryWineInspector(IsApprovedUser):
role=Role.WINERY_WINE_INSPECTOR, site__country__code=request.country_code,
).only('id')
if role.exists():
user_role = UserRole.objects.filter(
user_role = UserRole.objects.validated().filter(
user=request.user, role__id__in=role.values_list('id', flat=True),
).only('id')
if user_role.exists():
@ -375,7 +375,7 @@ class IsProducerFoodInspector(IsApprovedUser):
role=Role.PRODUCER_FOOD_INSPECTOR, site__country__code=request.country_code,
).only('id')
if role.exists():
user_role = UserRole.objects.filter(
user_role = UserRole.objects.validated().filter(
user=request.user, role__id__in=role.values_list('id', flat=True),
).only('id')
if user_role.exists():
@ -408,7 +408,7 @@ class IsDistilleryLiquorInspector(IsApprovedUser):
role=Role.DISTILLERY_LIQUOR_INSPECTOR, site__country__code=request.country_code,
).only('id')
if role.exists():
user_role = UserRole.objects.filter(
user_role = UserRole.objects.validated().filter(
user=request.user, role__id__in=role.values_list('id', flat=True),
).only('id')
if user_role.exists():