Merge branch 'feature/fix_role' into 'develop'

Feature/fix role

See merge request gm/gm-backend!76
This commit is contained in:
d.kuzmenko 2019-10-25 13:06:38 +00:00
commit e9683ed668
9 changed files with 236 additions and 36 deletions

View File

@ -6,4 +6,4 @@ from rest_framework import serializers
class CommentBaseSerializer(serializers.ModelSerializer):
class Meta:
model = models.Comment
fields = ('id', 'text', 'mark', 'user')
fields = ('id', 'text', 'mark', 'user', 'object_id', 'content_type')

View File

@ -30,18 +30,48 @@ class CommentModeratorPermissionTests(BasePermissionTests):
)
self.userRole.save()
content_type = ContentType.objects.get(app_label='location', model='country')
self.content_type = ContentType.objects.get(app_label='location', model='country')
self.user_test = get_tokens_for_user()
self.comment = Comment.objects.create(text='Test comment', mark=1,
user=self.user_test["user"],
object_id=self.country_ru.pk,
content_type_id=content_type.id,
content_type_id=self.content_type.id,
country=self.country_ru
)
self.comment.save()
self.url = reverse('back:comment:comment-crud', kwargs={"id": self.comment.id})
def test_post(self):
self.url = reverse('back:comment:comment-list-create')
comment = {
"text": "Test comment POST",
"user": self.user_test["user"].id,
"object_id": self.country_ru.pk,
"content_type": self.content_type.id,
"country_id": self.country_ru.id
}
response = self.client.post(self.url, format='json', data=comment)
self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)
comment = {
"text": "Test comment POST moder",
"user": self.moderator.id,
"object_id": self.country_ru.id,
"content_type": self.content_type.id,
"country_id": self.country_ru.id
}
tokens = User.create_jwt_tokens(self.moderator)
self.client.cookies = SimpleCookie(
{'access_token': tokens.get('access_token'),
'refresh_token': tokens.get('access_token')})
response = self.client.post(self.url, format='json', data=comment)
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
def test_put_moderator(self):
tokens = User.create_jwt_tokens(self.moderator)
self.client.cookies = SimpleCookie(
@ -52,7 +82,9 @@ class CommentModeratorPermissionTests(BasePermissionTests):
"id": self.comment.id,
"text": "test text moderator",
"mark": 1,
"user": self.moderator.id
"user": self.moderator.id,
"object_id": self.comment.country_id,
"content_type": self.content_type.id
}
response = self.client.put(self.url, data=data, format='json')
@ -60,7 +92,7 @@ class CommentModeratorPermissionTests(BasePermissionTests):
def test_get(self):
response = self.client.get(self.url, format='json')
self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)
self.assertEqual(response.status_code, status.HTTP_200_OK)
def test_put_other_user(self):
other_user = User.objects.create_user(username='test',
@ -99,9 +131,10 @@ class CommentModeratorPermissionTests(BasePermissionTests):
"id": self.comment.id,
"text": "test text moderator",
"mark": 1,
"user": super_user.id
"user": super_user.id,
"object_id": self.country_ru.id,
"content_type": self.content_type.id,
}
response = self.client.put(self.url, data=data, format='json')
self.assertEqual(response.status_code, status.HTTP_200_OK)

View File

@ -8,12 +8,13 @@ class CommentLstView(generics.ListCreateAPIView):
"""Comment list create view."""
serializer_class = serializers.CommentBaseSerializer
queryset = models.Comment.objects.all()
permission_classes = [permissions.IsAuthenticatedOrReadOnly,]
permission_classes = [permissions.IsAuthenticatedOrReadOnly| IsCommentModerator|IsCountryAdmin]
class CommentRUDView(generics.RetrieveUpdateDestroyAPIView):
"""Comment RUD view."""
serializer_class = serializers.CommentBaseSerializer
queryset = models.Comment.objects.all()
permission_classes = [IsCountryAdmin | IsCommentModerator]
lookup_field = 'id'

View File

@ -16,4 +16,5 @@ class CountryBackSerializer(common.CountrySerializer):
'code',
'svg_image',
'name',
'country_id'
]

View File

@ -20,6 +20,7 @@ class BaseTestCase(APITestCase):
username=self.username, email=self.email, password=self.password)
tokens = User.create_jwt_tokens(self.user)
self.client.cookies = SimpleCookie(
{'access_token': tokens.get('access_token'),
'refresh_token': tokens.get('refresh_token')})

View File

@ -4,44 +4,48 @@ from rest_framework import generics
from location import models, serializers
from location.views import common
from utils.permissions import IsCountryAdmin
from rest_framework.permissions import IsAuthenticatedOrReadOnly
# Address
class AddressListCreateView(common.AddressViewMixin, generics.ListCreateAPIView):
"""Create view for model Address."""
serializer_class = serializers.AddressDetailSerializer
queryset = models.Address.objects.all()
permission_classes = [IsCountryAdmin]
permission_classes = [IsAuthenticatedOrReadOnly|IsCountryAdmin]
class AddressRUDView(common.AddressViewMixin, generics.RetrieveUpdateDestroyAPIView):
"""RUD view for model Address."""
serializer_class = serializers.AddressDetailSerializer
queryset = models.Address.objects.all()
permission_classes = [IsCountryAdmin]
permission_classes = [IsAuthenticatedOrReadOnly|IsCountryAdmin]
# City
class CityListCreateView(common.CityViewMixin, generics.ListCreateAPIView):
"""Create view for model City."""
serializer_class = serializers.CitySerializer
permission_classes = [IsCountryAdmin]
permission_classes = [IsAuthenticatedOrReadOnly|IsCountryAdmin]
class CityRUDView(common.CityViewMixin, generics.RetrieveUpdateDestroyAPIView):
"""RUD view for model City."""
serializer_class = serializers.CitySerializer
permission_classes = [IsCountryAdmin]
permission_classes = [IsAuthenticatedOrReadOnly|IsCountryAdmin]
# Region
class RegionListCreateView(common.RegionViewMixin, generics.ListCreateAPIView):
"""Create view for model Region"""
serializer_class = serializers.RegionSerializer
permission_classes = [IsCountryAdmin]
permission_classes = [IsAuthenticatedOrReadOnly|IsCountryAdmin]
class RegionRUDView(common.RegionViewMixin, generics.RetrieveUpdateDestroyAPIView):
"""Retrieve view for model Region"""
serializer_class = serializers.RegionSerializer
permission_classes = [IsCountryAdmin]
permission_classes = [IsAuthenticatedOrReadOnly|IsCountryAdmin]
# Country
@ -50,10 +54,11 @@ class CountryListCreateView(generics.ListCreateAPIView):
queryset = models.Country.objects.all()
serializer_class = serializers.CountryBackSerializer
pagination_class = None
permission_classes = [IsCountryAdmin]
permission_classes = [IsAuthenticatedOrReadOnly|IsCountryAdmin]
class CountryRUDView(generics.RetrieveUpdateDestroyAPIView):
"""RUD view for model Country."""
serializer_class = serializers.CountryBackSerializer
permission_classes = [IsCountryAdmin]
permission_classes = [IsAuthenticatedOrReadOnly|IsCountryAdmin]
queryset = models.Country.objects.all()

View File

@ -66,6 +66,22 @@ class NewsTestCase(BaseTestCase):
def setUp(self):
super().setUp()
def test_news_post(self):
test_news ={
"title": {"en-GB": "Test news POST"},
"news_type_id": self.test_news_type.id,
"description": {"en-GB": "Description test news"},
"start": datetime.now() + timedelta(hours=-2),
"end": datetime.now() + timedelta(hours=2),
"state": News.PUBLISHED,
"slug": 'test-news-slug_post',
"country_id": self.country_ru.id,
}
url = reverse("back:news:list-create")
response = self.client.post(url, data=test_news, format='json')
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
def test_web_news(self):
response = self.client.get(reverse('web:news:list'))
self.assertEqual(response.status_code, status.HTTP_200_OK)

View File

@ -31,6 +31,7 @@ class IsRefreshTokenValid(permissions.BasePermission):
"""
Check if user has a valid refresh token and authenticated
"""
def has_permission(self, request, view):
"""Check permissions by refresh token and default REST permission IsAuthenticated"""
refresh_token = request.COOKIES.get('refresh_token')
@ -55,11 +56,15 @@ class IsGuest(permissions.IsAuthenticatedOrReadOnly):
"""
Object-level permission to only allow owners of an object to edit it.
"""
def has_permission(self, request, view):
return request.user.is_authenticated
rules = [
request.user.is_superuser,
request.method in permissions.SAFE_METHODS
]
return any(rules)
def has_object_permission(self, request, view, obj):
rules = [
request.user.is_superuser,
request.method in permissions.SAFE_METHODS
@ -72,6 +77,21 @@ class IsStandardUser(IsGuest):
Object-level permission to only allow owners of an object to edit it.
Assumes the model instance has an `owner` attribute.
"""
def has_permission(self, request, view):
rules = [
super().has_permission(request, view)
]
# and request.user.email_confirmed,
if hasattr(request, 'user'):
rules = [
request.user.is_authenticated,
super().has_permission(request, view)
]
return any(rules)
def has_object_permission(self, request, view, obj):
# Read permissions are allowed to any request
rules = [
@ -92,6 +112,24 @@ class IsContentPageManager(IsStandardUser):
Object-level permission to only allow owners of an object to edit it.
Assumes the model instance has an `owner` attribute.
"""
def has_permission(self, request, view):
rules = [
super().has_permission(request, view)
]
# and request.user.email_confirmed,
if hasattr(request, 'user'):
role = Role.objects.filter(role=Role.CONTENT_PAGE_MANAGER,
country_id=request.country_id) \
.first() # 'Comments moderator'
rules = [
UserRole.objects.filter(user=request.user, role=role).exists(),
# and obj.user != request.user,
super().has_permission(request, view)
]
return any(rules)
def has_object_permission(self, request, view, obj):
# Read permissions are allowed to any request.
@ -112,17 +150,48 @@ class IsCountryAdmin(IsStandardUser):
Object-level permission to only allow owners of an object to edit it.
Assumes the model instance has an `owner` attribute.
"""
def has_permission(self, request, view):
rules = [
super().has_permission(request, view)
]
# and request.user.email_confirmed,
if hasattr(request.data, 'user') and hasattr(request.data, 'country_id'):
# Read permissions are allowed to any request.
role = Role.objects.filter(role=Role.COUNTRY_ADMIN,
country_id=request.data.country_id) \
.first() # 'Comments moderator'
rules = [
UserRole.objects.filter(user=request.user, role=role).exists(),
super().has_permission(request, view)
]
return any(rules)
def has_object_permission(self, request, view, obj):
# Read permissions are allowed to any request.
role = Role.objects.filter(role=Role.COUNTRY_ADMIN,
country_id=obj.country_id) \
.first() # 'Comments moderator'
rules = [
super().has_object_permission(request, view, obj)
]
# and request.user.email_confirmed,
if hasattr(request, 'user') and request.user.is_authenticated:
rules = [
UserRole.objects.filter(user=request.user, role=role).exists(),
super().has_object_permission(request, view, obj),
]
if hasattr(request.data, 'user'):
rules = [
UserRole.objects.filter(user=request.data.user, role=role).exists(),
super().has_object_permission(request, view, obj),
]
return any(rules)
@ -131,6 +200,27 @@ class IsCommentModerator(IsStandardUser):
Object-level permission to only allow owners of an object to edit it.
Assumes the model instance has an `owner` attribute.
"""
def has_permission(self, request, view):
rules = [
super().has_permission(request, view)
]
# and request.user.email_confirmed,
if hasattr(request.data, 'user') and hasattr(request.data, 'country_id'):
# Read permissions are allowed to any request.
role = Role.objects.filter(role=Role.COMMENTS_MODERATOR,
country_id=request.data.country_id) \
.first() # 'Comments moderator'
rules = [
UserRole.objects.filter(user=request.user, role=role).exists(),
super().has_permission(request, view)
]
return any(rules)
def has_object_permission(self, request, view, obj):
# Read permissions are allowed to any request.
role = Role.objects.filter(role=Role.COMMENTS_MODERATOR,
@ -147,6 +237,24 @@ class IsCommentModerator(IsStandardUser):
class IsEstablishmentManager(IsStandardUser):
def has_permission(self, request, view):
rules = [
super().has_permission(request, view)
]
# and request.user.email_confirmed,
if hasattr(request.data, 'user') and hasattr(request.data, 'establishment_id'):
role = Role.objects.filter(role=Role.ESTABLISHMENT_MANAGER) \
.first() # 'Comments moderator'
rules = [
UserRole.objects.filter(user=request.user, role=role,
establishment_id=request.data.establishment_id
).exists(),
super().has_permission(request, view)
]
return any(rules)
def has_object_permission(self, request, view, obj):
role = Role.objects.filter(role=Role.ESTABLISHMENT_MANAGER) \
.first() # 'Comments moderator'
@ -163,8 +271,25 @@ class IsEstablishmentManager(IsStandardUser):
class IsReviewerManager(IsStandardUser):
def has_object_permission(self, request, view, obj):
def has_permission(self, request, view):
rules = [
super().has_permission(request, view)
]
# and request.user.email_confirmed,
if hasattr(request.data, 'user') and hasattr(request.data, 'country_id'):
role = Role.objects.filter(role=Role.REVIEWER_MANGER) \
.first() # 'Comments moderator'
rules = [
UserRole.objects.filter(user=request.user, role=role,
establishment_id=request.data.country_id
).exists(),
super().has_permission(request, view)
]
return any(rules)
def has_object_permission(self, request, view, obj):
role = Role.objects.filter(role=Role.REVIEWER_MANGER,
country_id=obj.country_id) \
.first()
@ -179,8 +304,25 @@ class IsReviewerManager(IsStandardUser):
class IsRestaurantReviewer(IsStandardUser):
def has_object_permission(self, request, view, obj):
def has_permission(self, request, view):
rules = [
super().has_permission(request, view)
]
# and request.user.email_confirmed,
if hasattr(request.data, 'user') and hasattr(request.data, 'object_id'):
role = Role.objects.filter(role=Role.RESTAURANT_REVIEWER) \
.first() # 'Comments moderator'
rules = [
UserRole.objects.filter(user=request.user, role=role,
establishment_id=request.data.object_id
).exists(),
super().has_permission(request, view)
]
return any(rules)
def has_object_permission(self, request, view, obj):
content_type = ContentType.objects.get(app_lable='establishment',
model='establishment')

View File

@ -9,10 +9,11 @@ class BasePermissionTests(APITestCase):
title='Russia',
locale='ru-RU'
)
self.lang.save()
self.country_ru = Country.objects.get(
name={"en-GB": "Russian"}
)
self.country_ru.save()