Merge branch 'feature/permission' into 'develop'
Feature/permission See merge request gm/gm-backend!156
This commit is contained in:
commit
357b3fdaa5
20
apps/account/migrations/0020_role_site.py
Normal file
20
apps/account/migrations/0020_role_site.py
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
# Generated by Django 2.2.7 on 2019-11-22 08:32
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('main', '0037_sitesettings_old_id'),
|
||||||
|
('account', '0019_auto_20191108_0827'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='role',
|
||||||
|
name='site',
|
||||||
|
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='main.SiteSettings', verbose_name='Site settings'),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
@ -46,10 +46,8 @@ class Role(ProjectBaseMixin):
|
||||||
null=False, blank=False)
|
null=False, blank=False)
|
||||||
country = models.ForeignKey(Country, verbose_name=_('Country'),
|
country = models.ForeignKey(Country, verbose_name=_('Country'),
|
||||||
null=True, blank=True, on_delete=models.SET_NULL)
|
null=True, blank=True, on_delete=models.SET_NULL)
|
||||||
# is_list = models.BooleanField(verbose_name=_('list'), default=True, null=False)
|
site = models.ForeignKey(SiteSettings, verbose_name=_('Site settings'),
|
||||||
# is_create = models.BooleanField(verbose_name=_('create'), default=False, null=False)
|
null=True, blank=True, on_delete=models.SET_NULL)
|
||||||
# is_update = models.BooleanField(verbose_name=_('update'), default=False, null=False)
|
|
||||||
# is_delete = models.BooleanField(verbose_name=_('delete'), default=False, null=False)
|
|
||||||
|
|
||||||
|
|
||||||
class UserManager(BaseUserManager):
|
class UserManager(BaseUserManager):
|
||||||
|
|
|
||||||
20
apps/comment/migrations/0007_comment_site.py
Normal file
20
apps/comment/migrations/0007_comment_site.py
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
# Generated by Django 2.2.7 on 2019-11-25 08:10
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('main', '0037_sitesettings_old_id'),
|
||||||
|
('comment', '0006_comment_is_publish'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='comment',
|
||||||
|
name='site',
|
||||||
|
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='main.SiteSettings', verbose_name='site'),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
@ -35,7 +35,8 @@ class Comment(ProjectBaseMixin):
|
||||||
user = models.ForeignKey('account.User', related_name='comments', on_delete=models.CASCADE, verbose_name=_('User'))
|
user = models.ForeignKey('account.User', related_name='comments', on_delete=models.CASCADE, verbose_name=_('User'))
|
||||||
old_id = models.IntegerField(null=True, blank=True, default=None)
|
old_id = models.IntegerField(null=True, blank=True, default=None)
|
||||||
is_publish = models.BooleanField(default=False, verbose_name=_('Publish status'))
|
is_publish = models.BooleanField(default=False, verbose_name=_('Publish status'))
|
||||||
|
site = models.ForeignKey('main.SiteSettings', blank=True, null=True,
|
||||||
|
on_delete=models.SET_NULL, verbose_name=_('site'))
|
||||||
content_type = models.ForeignKey(generic.ContentType, on_delete=models.CASCADE)
|
content_type = models.ForeignKey(generic.ContentType, on_delete=models.CASCADE)
|
||||||
object_id = models.PositiveIntegerField()
|
object_id = models.PositiveIntegerField()
|
||||||
content_object = generic.GenericForeignKey('content_type', 'object_id')
|
content_object = generic.GenericForeignKey('content_type', 'object_id')
|
||||||
|
|
|
||||||
|
|
@ -8,15 +8,20 @@ from account.models import Role, User, UserRole
|
||||||
from authorization.tests.tests_authorization import get_tokens_for_user
|
from authorization.tests.tests_authorization import get_tokens_for_user
|
||||||
from comment.models import Comment
|
from comment.models import Comment
|
||||||
from utils.tests.tests_permissions import BasePermissionTests
|
from utils.tests.tests_permissions import BasePermissionTests
|
||||||
|
from main.models import SiteSettings
|
||||||
|
|
||||||
|
|
||||||
class CommentModeratorPermissionTests(BasePermissionTests):
|
class CommentModeratorPermissionTests(BasePermissionTests):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super().setUp()
|
super().setUp()
|
||||||
|
|
||||||
|
self.site_ru, created = SiteSettings.objects.get_or_create(
|
||||||
|
subdomain='ru'
|
||||||
|
)
|
||||||
|
|
||||||
self.role = Role.objects.create(
|
self.role = Role.objects.create(
|
||||||
role=2,
|
role=2,
|
||||||
country=self.country_ru
|
site=self.site_ru
|
||||||
)
|
)
|
||||||
self.role.save()
|
self.role.save()
|
||||||
|
|
||||||
|
|
@ -33,11 +38,12 @@ class CommentModeratorPermissionTests(BasePermissionTests):
|
||||||
self.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.user_test = get_tokens_for_user()
|
||||||
|
|
||||||
self.comment = Comment.objects.create(text='Test comment', mark=1,
|
self.comment = Comment.objects.create(text='Test comment', mark=1,
|
||||||
user=self.user_test["user"],
|
user=self.user_test["user"],
|
||||||
object_id=self.country_ru.pk,
|
object_id=self.country_ru.pk,
|
||||||
content_type_id=self.content_type.id,
|
content_type_id=self.content_type.id,
|
||||||
country=self.country_ru
|
site=self.site_ru
|
||||||
)
|
)
|
||||||
self.comment.save()
|
self.comment.save()
|
||||||
self.url = reverse('back:comment:comment-crud', kwargs={"id": self.comment.id})
|
self.url = reverse('back:comment:comment-crud', kwargs={"id": self.comment.id})
|
||||||
|
|
@ -50,7 +56,7 @@ class CommentModeratorPermissionTests(BasePermissionTests):
|
||||||
"user": self.user_test["user"].id,
|
"user": self.user_test["user"].id,
|
||||||
"object_id": self.country_ru.pk,
|
"object_id": self.country_ru.pk,
|
||||||
"content_type": self.content_type.id,
|
"content_type": self.content_type.id,
|
||||||
"country_id": self.country_ru.id
|
"site_id": self.site_ru.id
|
||||||
}
|
}
|
||||||
|
|
||||||
response = self.client.post(self.url, format='json', data=comment)
|
response = self.client.post(self.url, format='json', data=comment)
|
||||||
|
|
@ -61,7 +67,7 @@ class CommentModeratorPermissionTests(BasePermissionTests):
|
||||||
"user": self.moderator.id,
|
"user": self.moderator.id,
|
||||||
"object_id": self.country_ru.id,
|
"object_id": self.country_ru.id,
|
||||||
"content_type": self.content_type.id,
|
"content_type": self.content_type.id,
|
||||||
"country_id": self.country_ru.id
|
"site_id": self.site_ru.id
|
||||||
}
|
}
|
||||||
|
|
||||||
tokens = User.create_jwt_tokens(self.moderator)
|
tokens = User.create_jwt_tokens(self.moderator)
|
||||||
|
|
@ -83,8 +89,9 @@ class CommentModeratorPermissionTests(BasePermissionTests):
|
||||||
"text": "test text moderator",
|
"text": "test text moderator",
|
||||||
"mark": 1,
|
"mark": 1,
|
||||||
"user": self.moderator.id,
|
"user": self.moderator.id,
|
||||||
"object_id": self.comment.country_id,
|
"object_id": self.country_ru.id,
|
||||||
"content_type": self.content_type.id
|
"content_type": self.content_type.id,
|
||||||
|
'site_id': self.site_ru.id
|
||||||
}
|
}
|
||||||
|
|
||||||
response = self.client.put(self.url, data=data, format='json')
|
response = self.client.put(self.url, data=data, format='json')
|
||||||
|
|
|
||||||
|
|
@ -8,13 +8,13 @@ class CommentLstView(generics.ListCreateAPIView):
|
||||||
"""Comment list create view."""
|
"""Comment list create view."""
|
||||||
serializer_class = serializers.CommentBaseSerializer
|
serializer_class = serializers.CommentBaseSerializer
|
||||||
queryset = models.Comment.objects.all()
|
queryset = models.Comment.objects.all()
|
||||||
permission_classes = [permissions.IsAuthenticatedOrReadOnly| IsCommentModerator|IsCountryAdmin]
|
# permission_classes = [permissions.IsAuthenticatedOrReadOnly| IsCommentModerator|IsCountryAdmin]
|
||||||
|
|
||||||
|
|
||||||
class CommentRUDView(generics.RetrieveUpdateDestroyAPIView):
|
class CommentRUDView(generics.RetrieveUpdateDestroyAPIView):
|
||||||
"""Comment RUD view."""
|
"""Comment RUD view."""
|
||||||
serializer_class = serializers.CommentBaseSerializer
|
serializer_class = serializers.CommentBaseSerializer
|
||||||
queryset = models.Comment.objects.all()
|
queryset = models.Comment.objects.all()
|
||||||
|
permission_classes = [IsCommentModerator]
|
||||||
permission_classes = [IsCountryAdmin | IsCommentModerator]
|
# permission_classes = [IsCountryAdmin | IsCommentModerator]
|
||||||
lookup_field = 'id'
|
lookup_field = 'id'
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,8 @@ from translation.models import Language
|
||||||
from account.models import Role, UserRole
|
from account.models import Role, UserRole
|
||||||
from location.models import Country, Address, City, Region
|
from location.models import Country, Address, City, Region
|
||||||
from pytz import timezone as py_tz
|
from pytz import timezone as py_tz
|
||||||
|
from main.models import SiteSettings
|
||||||
|
from timetable.models import Timetable
|
||||||
|
|
||||||
|
|
||||||
class BaseTestCase(APITestCase):
|
class BaseTestCase(APITestCase):
|
||||||
|
|
@ -278,13 +280,13 @@ class PlateTests(ChildTestCase):
|
||||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||||
|
|
||||||
menu = Menu.objects.create(
|
menu = Menu.objects.create(
|
||||||
category=json.dumps({"en-GB": "Test category"}),
|
category=json.dumps({"ru-RU": "Test category"}),
|
||||||
establishment=self.establishment
|
establishment=self.establishment
|
||||||
)
|
)
|
||||||
currency = Currency.objects.create(name="Test currency")
|
currency = Currency.objects.create(name="Test currency")
|
||||||
|
|
||||||
data = {
|
data = {
|
||||||
'name': json.dumps({"en-GB": "Test plate"}),
|
'name': json.dumps({"ru-RU": "Test plate"}),
|
||||||
'establishment': self.establishment.id,
|
'establishment': self.establishment.id,
|
||||||
'price': 10,
|
'price': 10,
|
||||||
'menu': menu.id,
|
'menu': menu.id,
|
||||||
|
|
@ -298,7 +300,7 @@ class PlateTests(ChildTestCase):
|
||||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||||
|
|
||||||
update_data = {
|
update_data = {
|
||||||
'name': json.dumps({"en-GB": "Test new plate"})
|
'name': json.dumps({"ru-RU": "Test new plate"})
|
||||||
}
|
}
|
||||||
|
|
||||||
response = self.client.patch('/api/back/establishments/plates/1/', data=update_data)
|
response = self.client.patch('/api/back/establishments/plates/1/', data=update_data)
|
||||||
|
|
@ -314,7 +316,7 @@ class MenuTests(ChildTestCase):
|
||||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||||
|
|
||||||
data = {
|
data = {
|
||||||
'category': json.dumps({"en-GB": "Test category"}),
|
'category': json.dumps({"ru-RU": "Test category"}),
|
||||||
'establishment': self.establishment.id
|
'establishment': self.establishment.id
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -325,7 +327,7 @@ class MenuTests(ChildTestCase):
|
||||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||||
|
|
||||||
update_data = {
|
update_data = {
|
||||||
'category': json.dumps({"en-GB": "Test new category"})
|
'category': json.dumps({"ru-RU": "Test new category"})
|
||||||
}
|
}
|
||||||
|
|
||||||
response = self.client.patch('/api/back/establishments/menus/1/', data=update_data)
|
response = self.client.patch('/api/back/establishments/menus/1/', data=update_data)
|
||||||
|
|
@ -336,24 +338,56 @@ class MenuTests(ChildTestCase):
|
||||||
|
|
||||||
|
|
||||||
class EstablishmentShedulerTests(ChildTestCase):
|
class EstablishmentShedulerTests(ChildTestCase):
|
||||||
def test_shedule_CRUD(self):
|
def setUp(self):
|
||||||
|
super().setUp()
|
||||||
|
|
||||||
|
self.lang, created = Language.objects.get_or_create(
|
||||||
|
title='Russia',
|
||||||
|
locale='ru-RU'
|
||||||
|
)
|
||||||
|
|
||||||
|
self.country_ru, created = Country.objects.get_or_create(
|
||||||
|
name={"en-GB": "Russian"}
|
||||||
|
)
|
||||||
|
|
||||||
|
self.site_ru, created = SiteSettings.objects.get_or_create(
|
||||||
|
subdomain='ru'
|
||||||
|
)
|
||||||
|
|
||||||
|
role, created = Role.objects.get_or_create(
|
||||||
|
role=Role.ESTABLISHMENT_MANAGER,
|
||||||
|
country_id=self.country_ru.id,
|
||||||
|
site_id=self.site_ru.id
|
||||||
|
)
|
||||||
|
|
||||||
|
user_role, created = UserRole.objects.get_or_create(
|
||||||
|
user=self.user,
|
||||||
|
role=role,
|
||||||
|
establishment_id=self.establishment.id
|
||||||
|
)
|
||||||
|
user_role.save()
|
||||||
|
|
||||||
|
def test_schedule_CRUD(self):
|
||||||
data = {
|
data = {
|
||||||
'weekday': 1
|
'weekday': 1
|
||||||
}
|
}
|
||||||
|
|
||||||
response = self.client.post(f'/api/back/establishments/{self.establishment.id}/schedule/', data=data)
|
response = self.client.post(f'/api/back/establishments/{self.establishment.id}/schedule/', data=data)
|
||||||
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
|
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
|
||||||
|
schedule = response.data
|
||||||
|
|
||||||
response = self.client.get(f'/api/back/establishments/{self.establishment.id}/schedule/1/')
|
response = self.client.get(f'/api/back/establishments/{self.establishment.id}/schedule/{schedule["id"]}/')
|
||||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||||
|
|
||||||
update_data = {
|
update_data = {
|
||||||
'weekday': 2
|
'weekday': 2
|
||||||
}
|
}
|
||||||
|
|
||||||
response = self.client.patch(f'/api/back/establishments/{self.establishment.id}/schedule/1/', data=update_data)
|
response = self.client.patch(f'/api/back/establishments/{self.establishment.id}/schedule/{schedule["id"]}/',
|
||||||
|
data=update_data)
|
||||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||||
|
|
||||||
response = self.client.delete(f'/api/back/establishments/{self.establishment.id}/schedule/1/')
|
response = self.client.delete(f'/api/back/establishments/{self.establishment.id}/schedule/{schedule["id"]}/')
|
||||||
self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT)
|
self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,12 +25,12 @@ class BaseTestCase(APITestCase):
|
||||||
{'access_token': tokens.get('access_token'),
|
{'access_token': tokens.get('access_token'),
|
||||||
'refresh_token': tokens.get('refresh_token')})
|
'refresh_token': tokens.get('refresh_token')})
|
||||||
|
|
||||||
self.lang = Language.objects.get(
|
self.lang, created = Language.objects.get_or_create(
|
||||||
title='Russia',
|
title='Russia',
|
||||||
locale='ru-RU'
|
locale='ru-RU'
|
||||||
)
|
)
|
||||||
|
|
||||||
self.country_ru = Country.objects.get(
|
self.country_ru, created = Country.objects.get_or_create(
|
||||||
name={"en-GB": "Russian"}
|
name={"en-GB": "Russian"}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -72,7 +72,7 @@ class CountryTests(BaseTestCase):
|
||||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||||
|
|
||||||
update_data = {
|
update_data = {
|
||||||
'name': json.dumps({"en-GB": "Test new country"})
|
'name': json.dumps({"ru-RU": "Test new country"})
|
||||||
}
|
}
|
||||||
|
|
||||||
response = self.client.patch(f'/api/back/location/countries/{response_data["id"]}/', data=update_data)
|
response = self.client.patch(f'/api/back/location/countries/{response_data["id"]}/', data=update_data)
|
||||||
|
|
|
||||||
20
apps/news/migrations/0036_news_site.py
Normal file
20
apps/news/migrations/0036_news_site.py
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
# Generated by Django 2.2.7 on 2019-11-22 09:12
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('main', '0037_sitesettings_old_id'),
|
||||||
|
('news', '0035_news_views_count'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='news',
|
||||||
|
name='site',
|
||||||
|
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='main.SiteSettings', verbose_name='site settings'),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
@ -204,7 +204,8 @@ class News(GalleryModelMixin, BaseAttributes, TranslatedFieldsMixin, HasTagsMixi
|
||||||
banner = models.ForeignKey('news.NewsBanner', blank=True, null=True,
|
banner = models.ForeignKey('news.NewsBanner', blank=True, null=True,
|
||||||
on_delete=models.SET_NULL,
|
on_delete=models.SET_NULL,
|
||||||
verbose_name=_('banner'))
|
verbose_name=_('banner'))
|
||||||
|
site = models.ForeignKey('main.SiteSettings', blank=True, null=True,
|
||||||
|
on_delete=models.SET_NULL, verbose_name=_('site settings'))
|
||||||
objects = NewsQuerySet.as_manager()
|
objects = NewsQuerySet.as_manager()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ from rest_framework.fields import SerializerMethodField
|
||||||
|
|
||||||
from account.serializers.common import UserBaseSerializer
|
from account.serializers.common import UserBaseSerializer
|
||||||
from gallery.models import Image
|
from gallery.models import Image
|
||||||
|
from main.models import SiteSettings
|
||||||
from location import models as location_models
|
from location import models as location_models
|
||||||
from location.serializers import CountrySimpleSerializer, AddressBaseSerializer
|
from location.serializers import CountrySimpleSerializer, AddressBaseSerializer
|
||||||
from news import models
|
from news import models
|
||||||
|
|
@ -80,7 +81,6 @@ class NewsBaseSerializer(ProjectModelSerializer):
|
||||||
'news_type',
|
'news_type',
|
||||||
'tags',
|
'tags',
|
||||||
'slug',
|
'slug',
|
||||||
'in_favorites',
|
|
||||||
'view_counter',
|
'view_counter',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -184,6 +184,9 @@ class NewsBackOfficeDetailSerializer(NewsBackOfficeBaseSerializer,
|
||||||
country_id = serializers.PrimaryKeyRelatedField(
|
country_id = serializers.PrimaryKeyRelatedField(
|
||||||
source='country', write_only=True,
|
source='country', write_only=True,
|
||||||
queryset=location_models.Country.objects.all())
|
queryset=location_models.Country.objects.all())
|
||||||
|
site_id = serializers.PrimaryKeyRelatedField(
|
||||||
|
source='site', write_only=True,
|
||||||
|
queryset=SiteSettings.objects.all())
|
||||||
template_display = serializers.CharField(source='get_template_display',
|
template_display = serializers.CharField(source='get_template_display',
|
||||||
read_only=True)
|
read_only=True)
|
||||||
|
|
||||||
|
|
@ -195,6 +198,7 @@ class NewsBackOfficeDetailSerializer(NewsBackOfficeBaseSerializer,
|
||||||
'description',
|
'description',
|
||||||
'news_type_id',
|
'news_type_id',
|
||||||
'country_id',
|
'country_id',
|
||||||
|
'site_id',
|
||||||
'template',
|
'template',
|
||||||
'template_display',
|
'template_display',
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ from rest_framework.test import APITestCase
|
||||||
from rest_framework import status
|
from rest_framework import status
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
|
|
||||||
|
from main.models import SiteSettings
|
||||||
from news.models import NewsType, News
|
from news.models import NewsType, News
|
||||||
from account.models import User, Role, UserRole
|
from account.models import User, Role, UserRole
|
||||||
from translation.models import Language
|
from translation.models import Language
|
||||||
|
|
@ -30,18 +31,23 @@ class BaseTestCase(APITestCase):
|
||||||
'refresh_token': tokens.get('refresh_token')})
|
'refresh_token': tokens.get('refresh_token')})
|
||||||
self.test_news_type = NewsType.objects.create(name="Test news type")
|
self.test_news_type = NewsType.objects.create(name="Test news type")
|
||||||
|
|
||||||
self.lang = Language.objects.create(
|
|
||||||
|
self.lang, created = Language.objects.get_or_create(
|
||||||
title='Russia',
|
title='Russia',
|
||||||
locale='ru-RU'
|
locale='ru-RU'
|
||||||
)
|
)
|
||||||
|
|
||||||
self.country_ru = Country.objects.create(
|
self.country_ru, created = Country.objects.get_or_create(
|
||||||
name={"en-GB": "Russian"}
|
name={"en-GB": "Russian"}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
self.site_ru, created = SiteSettings.objects.get_or_create(
|
||||||
|
subdomain='ru'
|
||||||
|
)
|
||||||
|
|
||||||
role = Role.objects.create(
|
role = Role.objects.create(
|
||||||
role=Role.CONTENT_PAGE_MANAGER,
|
role=Role.CONTENT_PAGE_MANAGER,
|
||||||
country=self.country_ru
|
site_id=self.site_ru.id
|
||||||
)
|
)
|
||||||
role.save()
|
role.save()
|
||||||
|
|
||||||
|
|
@ -51,16 +57,18 @@ class BaseTestCase(APITestCase):
|
||||||
)
|
)
|
||||||
user_role.save()
|
user_role.save()
|
||||||
|
|
||||||
|
|
||||||
self.test_news = News.objects.create(
|
self.test_news = News.objects.create(
|
||||||
created_by=self.user, modified_by=self.user,
|
created_by=self.user, modified_by=self.user,
|
||||||
title={"en-GB": "Test news"},
|
title={"ru-RU": "Test news"},
|
||||||
news_type=self.test_news_type,
|
news_type=self.test_news_type,
|
||||||
description={"en-GB": "Description test news"},
|
description={"ru-RU": "Description test news"},
|
||||||
start=datetime.now() + timedelta(hours=-2),
|
start=datetime.now() + timedelta(hours=-2),
|
||||||
end=datetime.now() + timedelta(hours=2),
|
end=datetime.now() + timedelta(hours=2),
|
||||||
state=News.PUBLISHED,
|
state=News.PUBLISHED,
|
||||||
slug='test-news-slug',
|
slug='test-news-slug',
|
||||||
country=self.country_ru,
|
country=self.country_ru,
|
||||||
|
site=self.site_ru
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -70,14 +78,15 @@ class NewsTestCase(BaseTestCase):
|
||||||
|
|
||||||
def test_news_post(self):
|
def test_news_post(self):
|
||||||
test_news = {
|
test_news = {
|
||||||
"title": {"en-GB": "Test news POST"},
|
"title": {"ru-RU": "Test news POST"},
|
||||||
"news_type_id": self.test_news_type.id,
|
"news_type_id": self.test_news_type.id,
|
||||||
"description": {"en-GB": "Description test news"},
|
"description": {"ru-RU": "Description test news"},
|
||||||
"start": datetime.now() + timedelta(hours=-2),
|
"start": datetime.now() + timedelta(hours=-2),
|
||||||
"end": datetime.now() + timedelta(hours=2),
|
"end": datetime.now() + timedelta(hours=2),
|
||||||
"state": News.PUBLISHED,
|
"state": News.PUBLISHED,
|
||||||
"slug": 'test-news-slug_post',
|
"slug": 'test-news-slug_post',
|
||||||
"country_id": self.country_ru.id,
|
"country_id": self.country_ru.id,
|
||||||
|
"site_id": self.site_ru.id
|
||||||
}
|
}
|
||||||
|
|
||||||
url = reverse("back:news:list-create")
|
url = reverse("back:news:list-create")
|
||||||
|
|
@ -107,11 +116,12 @@ class NewsTestCase(BaseTestCase):
|
||||||
url = reverse('back:news:retrieve-update-destroy', kwargs={'pk': self.test_news.id})
|
url = reverse('back:news:retrieve-update-destroy', kwargs={'pk': self.test_news.id})
|
||||||
data = {
|
data = {
|
||||||
'id': self.test_news.id,
|
'id': self.test_news.id,
|
||||||
'description': {"en-GB": "Description test news!"},
|
'description': {"ru-RU": "Description test news!"},
|
||||||
'slug': self.test_news.slug,
|
'slug': self.test_news.slug,
|
||||||
'start': self.test_news.start,
|
'start': self.test_news.start,
|
||||||
'news_type_id': self.test_news.news_type_id,
|
'news_type_id': self.test_news.news_type_id,
|
||||||
'country_id': self.country_ru.id
|
'country_id': self.country_ru.id,
|
||||||
|
"site_id": self.site_ru.id
|
||||||
}
|
}
|
||||||
|
|
||||||
response = self.client.put(url, data=data, format='json')
|
response = self.client.put(url, data=data, format='json')
|
||||||
|
|
|
||||||
|
|
@ -84,6 +84,7 @@ class NewsBackOfficeLCView(NewsBackOfficeMixinView,
|
||||||
serializer_class = serializers.NewsBackOfficeBaseSerializer
|
serializer_class = serializers.NewsBackOfficeBaseSerializer
|
||||||
filter_class = filters.NewsListFilterSet
|
filter_class = filters.NewsListFilterSet
|
||||||
create_serializers_class = serializers.NewsBackOfficeDetailSerializer
|
create_serializers_class = serializers.NewsBackOfficeDetailSerializer
|
||||||
|
|
||||||
permission_classes = [IsCountryAdmin | IsContentPageManager]
|
permission_classes = [IsCountryAdmin | IsContentPageManager]
|
||||||
|
|
||||||
def get_serializer_class(self):
|
def get_serializer_class(self):
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ class BackPartnerSerializer(serializers.ModelSerializer):
|
||||||
'url',
|
'url',
|
||||||
'image',
|
'image',
|
||||||
'establishment',
|
'establishment',
|
||||||
|
'establishment_id',
|
||||||
'type',
|
'type',
|
||||||
'starting_date',
|
'starting_date',
|
||||||
'expiry_date',
|
'expiry_date',
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,8 @@ class ScheduleRUDSerializer(serializers.ModelSerializer):
|
||||||
dinner_end = serializers.TimeField(required=False)
|
dinner_end = serializers.TimeField(required=False)
|
||||||
opening_at = serializers.TimeField(required=False)
|
opening_at = serializers.TimeField(required=False)
|
||||||
closed_at = serializers.TimeField(required=False)
|
closed_at = serializers.TimeField(required=False)
|
||||||
|
# For permission!!
|
||||||
|
establishment_id = serializers.ReadOnlyField(source='establishment.id')
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
"""Meta class."""
|
"""Meta class."""
|
||||||
|
|
@ -34,6 +36,7 @@ class ScheduleRUDSerializer(serializers.ModelSerializer):
|
||||||
'dinner_end',
|
'dinner_end',
|
||||||
'opening_at',
|
'opening_at',
|
||||||
'closed_at',
|
'closed_at',
|
||||||
|
'establishment_id'
|
||||||
]
|
]
|
||||||
|
|
||||||
def validate(self, attrs):
|
def validate(self, attrs):
|
||||||
|
|
|
||||||
|
|
@ -36,10 +36,6 @@ class ProjectBaseMixin(models.Model):
|
||||||
abstract = True
|
abstract = True
|
||||||
|
|
||||||
|
|
||||||
def valid(value):
|
|
||||||
print("Run")
|
|
||||||
|
|
||||||
|
|
||||||
class TJSONField(JSONField):
|
class TJSONField(JSONField):
|
||||||
"""Overrided JsonField."""
|
"""Overrided JsonField."""
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -100,7 +100,10 @@ class IsStandardUser(IsGuest):
|
||||||
|
|
||||||
if hasattr(obj, 'user'):
|
if hasattr(obj, 'user'):
|
||||||
rules = [
|
rules = [
|
||||||
obj.user == request.user and obj.user.email_confirmed,
|
obj.user == request.user
|
||||||
|
and obj.user.email_confirmed
|
||||||
|
and request.user.is_authenticated,
|
||||||
|
|
||||||
super().has_object_permission(request, view, obj)
|
super().has_object_permission(request, view, obj)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -117,31 +120,50 @@ class IsContentPageManager(IsStandardUser):
|
||||||
rules = [
|
rules = [
|
||||||
super().has_permission(request, view)
|
super().has_permission(request, view)
|
||||||
]
|
]
|
||||||
# and request.user.email_confirmed,
|
|
||||||
if hasattr(request, 'user'):
|
if hasattr(request, 'user'):
|
||||||
|
if hasattr(request.data, 'site_id'):
|
||||||
role = Role.objects.filter(role=Role.CONTENT_PAGE_MANAGER,
|
role = Role.objects.filter(role=Role.CONTENT_PAGE_MANAGER,
|
||||||
country_id=request.country_id) \
|
site_id=request.data.site_id,) \
|
||||||
.first() # 'Comments moderator'
|
.first()
|
||||||
|
|
||||||
rules = [
|
rules = [
|
||||||
UserRole.objects.filter(user=request.user, role=role).exists(),
|
UserRole.objects.filter(user=request.user, role=role).exists(),
|
||||||
# and obj.user != request.user,
|
|
||||||
super().has_permission(request, view)
|
super().has_permission(request, view)
|
||||||
]
|
]
|
||||||
|
elif hasattr(request.data, 'country_id'):
|
||||||
|
role = Role.objects.filter(role=Role.CONTENT_PAGE_MANAGER,
|
||||||
|
country_id=request.data.country_id) \
|
||||||
|
.first()
|
||||||
|
|
||||||
|
rules = [
|
||||||
|
UserRole.objects.filter(user=request.user, role=role).exists(),
|
||||||
|
super().has_permission(request, view)
|
||||||
|
]
|
||||||
|
|
||||||
return any(rules)
|
return any(rules)
|
||||||
|
|
||||||
def has_object_permission(self, request, view, obj):
|
def has_object_permission(self, request, view, obj):
|
||||||
# Read permissions are allowed to any request.
|
# Read permissions are allowed to any request.
|
||||||
|
if hasattr(obj, 'site_id'):
|
||||||
role = Role.objects.filter(role=Role.CONTENT_PAGE_MANAGER,
|
role = Role.objects.filter(role=Role.CONTENT_PAGE_MANAGER,
|
||||||
country_id=obj.country_id) \
|
site_id=obj.site_id) \
|
||||||
.first() # 'Comments moderator'
|
.first()
|
||||||
|
|
||||||
rules = [
|
rules = [
|
||||||
UserRole.objects.filter(user=request.user, role=role).exists(),
|
UserRole.objects.filter(user=request.user, role=role).exists(),
|
||||||
# and obj.user != request.user,
|
|
||||||
super().has_object_permission(request, view, obj)
|
super().has_object_permission(request, view, obj)
|
||||||
]
|
]
|
||||||
|
elif hasattr(obj, 'country_id'):
|
||||||
|
role = Role.objects.filter(role=Role.CONTENT_PAGE_MANAGER,
|
||||||
|
country_id=obj.country_id) \
|
||||||
|
.first()
|
||||||
|
|
||||||
|
rules = [
|
||||||
|
UserRole.objects.filter(user=request.user, role=role).exists(),
|
||||||
|
super().has_object_permission(request, view, obj)
|
||||||
|
]
|
||||||
|
|
||||||
return any(rules)
|
return any(rules)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -150,19 +172,29 @@ class IsCountryAdmin(IsStandardUser):
|
||||||
Object-level permission to only allow owners of an object to edit it.
|
Object-level permission to only allow owners of an object to edit it.
|
||||||
Assumes the model instance has an `owner` attribute.
|
Assumes the model instance has an `owner` attribute.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def has_permission(self, request, view):
|
def has_permission(self, request, view):
|
||||||
|
|
||||||
rules = [
|
rules = [
|
||||||
super().has_permission(request, view)
|
super().has_permission(request, view)
|
||||||
]
|
]
|
||||||
# and request.user.email_confirmed,
|
# and request.user.email_confirmed,
|
||||||
if hasattr(request.data, 'user') and hasattr(request.data, 'country_id'):
|
if hasattr(request.data, 'user'):
|
||||||
|
if hasattr(request.data, 'site_id'):
|
||||||
# Read permissions are allowed to any request.
|
# Read permissions are allowed to any request.
|
||||||
|
|
||||||
|
role = Role.objects.filter(role=Role.COUNTRY_ADMIN,
|
||||||
|
site_id=request.data.site_id) \
|
||||||
|
.first()
|
||||||
|
|
||||||
|
rules = [
|
||||||
|
UserRole.objects.filter(user=request.user, role=role).exists(),
|
||||||
|
super().has_permission(request, view)
|
||||||
|
]
|
||||||
|
elif hasattr(request.data, 'country_id'):
|
||||||
|
|
||||||
role = Role.objects.filter(role=Role.COUNTRY_ADMIN,
|
role = Role.objects.filter(role=Role.COUNTRY_ADMIN,
|
||||||
country_id=request.data.country_id) \
|
country_id=request.data.country_id) \
|
||||||
.first() # 'Comments moderator'
|
.first()
|
||||||
|
|
||||||
rules = [
|
rules = [
|
||||||
UserRole.objects.filter(user=request.user, role=role).exists(),
|
UserRole.objects.filter(user=request.user, role=role).exists(),
|
||||||
|
|
@ -172,14 +204,23 @@ class IsCountryAdmin(IsStandardUser):
|
||||||
|
|
||||||
def has_object_permission(self, request, view, obj):
|
def has_object_permission(self, request, view, obj):
|
||||||
# Read permissions are allowed to any request.
|
# Read permissions are allowed to any request.
|
||||||
|
if hasattr(obj, 'site_id'):
|
||||||
role = Role.objects.filter(role=Role.COUNTRY_ADMIN,
|
role = Role.objects.filter(role=Role.COUNTRY_ADMIN,
|
||||||
country_id=obj.country_id) \
|
site_id=obj.site_id) \
|
||||||
.first() # 'Comments moderator'
|
.first()
|
||||||
|
|
||||||
rules = [
|
rules = [
|
||||||
super().has_object_permission(request, view, obj)
|
super().has_object_permission(request, view, obj)
|
||||||
]
|
]
|
||||||
# and request.user.email_confirmed,
|
elif hasattr(obj, 'country_id'):
|
||||||
|
role = Role.objects.filter(role=Role.COUNTRY_ADMIN,
|
||||||
|
country_id=obj.country_id) \
|
||||||
|
.first()
|
||||||
|
|
||||||
|
rules = [
|
||||||
|
super().has_object_permission(request, view, obj)
|
||||||
|
]
|
||||||
|
|
||||||
if hasattr(request, 'user') and request.user.is_authenticated:
|
if hasattr(request, 'user') and request.user.is_authenticated:
|
||||||
rules = [
|
rules = [
|
||||||
UserRole.objects.filter(user=request.user, role=role).exists(),
|
UserRole.objects.filter(user=request.user, role=role).exists(),
|
||||||
|
|
@ -206,13 +247,12 @@ class IsCommentModerator(IsStandardUser):
|
||||||
super().has_permission(request, view)
|
super().has_permission(request, view)
|
||||||
]
|
]
|
||||||
|
|
||||||
# and request.user.email_confirmed,
|
if any(rules) and hasattr(request.data, 'site_id'):
|
||||||
if hasattr(request.data, 'user') and hasattr(request.data, 'country_id'):
|
|
||||||
# Read permissions are allowed to any request.
|
# Read permissions are allowed to any request.
|
||||||
|
|
||||||
role = Role.objects.filter(role=Role.COMMENTS_MODERATOR,
|
role = Role.objects.filter(role=Role.COMMENTS_MODERATOR,
|
||||||
country_id=request.data.country_id) \
|
site_id=request.data.site_id) \
|
||||||
.first() # 'Comments moderator'
|
.first()
|
||||||
|
|
||||||
rules = [
|
rules = [
|
||||||
UserRole.objects.filter(user=request.user, role=role).exists(),
|
UserRole.objects.filter(user=request.user, role=role).exists(),
|
||||||
|
|
@ -222,9 +262,15 @@ class IsCommentModerator(IsStandardUser):
|
||||||
return any(rules)
|
return any(rules)
|
||||||
|
|
||||||
def has_object_permission(self, request, view, obj):
|
def has_object_permission(self, request, view, obj):
|
||||||
# Read permissions are allowed to any request.
|
|
||||||
|
rules = [
|
||||||
|
super().has_object_permission(request, view, obj)
|
||||||
|
]
|
||||||
|
|
||||||
|
if request.user.is_authenticated:
|
||||||
|
|
||||||
role = Role.objects.filter(role=Role.COMMENTS_MODERATOR,
|
role = Role.objects.filter(role=Role.COMMENTS_MODERATOR,
|
||||||
country_id=obj.country_id) \
|
site_id=obj.site_id) \
|
||||||
.first() # 'Comments moderator'
|
.first() # 'Comments moderator'
|
||||||
|
|
||||||
rules = [
|
rules = [
|
||||||
|
|
@ -242,10 +288,10 @@ class IsEstablishmentManager(IsStandardUser):
|
||||||
super().has_permission(request, view)
|
super().has_permission(request, view)
|
||||||
]
|
]
|
||||||
|
|
||||||
# and request.user.email_confirmed,
|
if hasattr(request.data, 'user'):
|
||||||
if hasattr(request.data, 'user') and hasattr(request.data, 'establishment_id'):
|
if hasattr(request.data, 'establishment_id'):
|
||||||
role = Role.objects.filter(role=Role.ESTABLISHMENT_MANAGER) \
|
role = Role.objects.filter(role=Role.ESTABLISHMENT_MANAGER) \
|
||||||
.first() # 'Comments moderator'
|
.first()
|
||||||
|
|
||||||
rules = [
|
rules = [
|
||||||
UserRole.objects.filter(user=request.user, role=role,
|
UserRole.objects.filter(user=request.user, role=role,
|
||||||
|
|
@ -256,14 +302,24 @@ class IsEstablishmentManager(IsStandardUser):
|
||||||
return any(rules)
|
return any(rules)
|
||||||
|
|
||||||
def has_object_permission(self, request, view, obj):
|
def has_object_permission(self, request, view, obj):
|
||||||
role = Role.objects.filter(role=Role.ESTABLISHMENT_MANAGER) \
|
|
||||||
.first() # 'Comments moderator'
|
|
||||||
|
|
||||||
|
rules = [
|
||||||
|
# special!
|
||||||
|
super().has_permission(request, view)
|
||||||
|
# super().has_object_permission(request, view, obj)
|
||||||
|
]
|
||||||
|
|
||||||
|
role = Role.objects.filter(role=Role.ESTABLISHMENT_MANAGER) \
|
||||||
|
.first()
|
||||||
|
|
||||||
|
if hasattr(obj, 'establishment_id'):
|
||||||
rules = [
|
rules = [
|
||||||
UserRole.objects.filter(user=request.user, role=role,
|
UserRole.objects.filter(user=request.user, role=role,
|
||||||
establishment_id=obj.establishment_id
|
establishment_id=obj.establishment_id
|
||||||
).exists(),
|
).exists(),
|
||||||
super().has_object_permission(request, view, obj)
|
# special!
|
||||||
|
super().has_permission(request, view)
|
||||||
|
# super().has_object_permission(request, view, obj)
|
||||||
]
|
]
|
||||||
|
|
||||||
return any(rules)
|
return any(rules)
|
||||||
|
|
@ -277,13 +333,13 @@ class IsReviewerManager(IsStandardUser):
|
||||||
]
|
]
|
||||||
|
|
||||||
# and request.user.email_confirmed,
|
# and request.user.email_confirmed,
|
||||||
if hasattr(request.data, 'user') and hasattr(request.data, 'country_id'):
|
if hasattr(request.data, 'user') and hasattr(request.data, 'site_id'):
|
||||||
role = Role.objects.filter(role=Role.REVIEWER_MANGER) \
|
role = Role.objects.filter(role=Role.REVIEWER_MANGER) \
|
||||||
.first() # 'Comments moderator'
|
.first()
|
||||||
|
|
||||||
rules = [
|
rules = [
|
||||||
UserRole.objects.filter(user=request.user, role=role,
|
UserRole.objects.filter(user=request.user, role=role,
|
||||||
establishment_id=request.data.country_id
|
establishment_id=request.data.site_id
|
||||||
).exists(),
|
).exists(),
|
||||||
super().has_permission(request, view)
|
super().has_permission(request, view)
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -5,15 +5,13 @@ from translation.models import Language
|
||||||
|
|
||||||
class BasePermissionTests(APITestCase):
|
class BasePermissionTests(APITestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.lang = Language.objects.get(
|
self.lang, created = Language.objects.get_or_create(
|
||||||
title='Russia',
|
title='Russia',
|
||||||
locale='ru-RU'
|
locale='ru-RU'
|
||||||
)
|
)
|
||||||
self.lang.save()
|
|
||||||
|
|
||||||
self.country_ru = Country.objects.get(
|
self.country_ru, created = Country.objects.get_or_create(
|
||||||
name={"en-GB": "Russian"}
|
name={"en-GB": "Russian"}
|
||||||
)
|
)
|
||||||
self.country_ru.save()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -40,8 +40,7 @@ class TranslateFieldTests(BaseTestCase):
|
||||||
self.news_type = NewsType.objects.create(name="Test news type")
|
self.news_type = NewsType.objects.create(name="Test news type")
|
||||||
self.news_type.save()
|
self.news_type.save()
|
||||||
|
|
||||||
|
self.country_ru, created = Country.objects.get_or_create(
|
||||||
self.country_ru = Country.objects.get(
|
|
||||||
name={"en-GB": "Russian"}
|
name={"en-GB": "Russian"}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ MEDIA_ROOT = os.path.join(PUBLIC_ROOT, MEDIA_LOCATION)
|
||||||
THUMBNAIL_DEBUG = True
|
THUMBNAIL_DEBUG = True
|
||||||
|
|
||||||
# ADDED TRANSFER APP
|
# ADDED TRANSFER APP
|
||||||
INSTALLED_APPS.append('transfer.apps.TransferConfig')
|
# INSTALLED_APPS.append('transfer.apps.TransferConfig')
|
||||||
|
|
||||||
# DATABASES
|
# DATABASES
|
||||||
DATABASES.update({
|
DATABASES.update({
|
||||||
|
|
@ -93,6 +93,7 @@ ELASTICSEARCH_INDEX_NAMES = {
|
||||||
'search_indexes.documents.establishment': 'local_establishment',
|
'search_indexes.documents.establishment': 'local_establishment',
|
||||||
'search_indexes.documents.product': 'local_product',
|
'search_indexes.documents.product': 'local_product',
|
||||||
}
|
}
|
||||||
|
ELASTICSEARCH_DSL_AUTOSYNC = False
|
||||||
|
|
||||||
TESTING = sys.argv[1:2] == ['test']
|
TESTING = sys.argv[1:2] == ['test']
|
||||||
if TESTING:
|
if TESTING:
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user