diff --git a/apps/account/admin.py b/apps/account/admin.py index a89e6693..3b247289 100644 --- a/apps/account/admin.py +++ b/apps/account/admin.py @@ -2,7 +2,6 @@ from django.contrib import admin from django.contrib.auth.admin import UserAdmin as BaseUserAdmin from django.utils.translation import ugettext_lazy as _ - from account import models diff --git a/apps/account/migrations/0009_role_userrole.py b/apps/account/migrations/0009_auto_20191011_1123.py similarity index 80% rename from apps/account/migrations/0009_role_userrole.py rename to apps/account/migrations/0009_auto_20191011_1123.py index e162bfe5..f1ec87f9 100644 --- a/apps/account/migrations/0009_role_userrole.py +++ b/apps/account/migrations/0009_auto_20191011_1123.py @@ -1,4 +1,4 @@ -# Generated by Django 2.2.4 on 2019-10-08 07:17 +# Generated by Django 2.2.4 on 2019-10-11 11:23 from django.conf import settings from django.db import migrations, models @@ -9,7 +9,7 @@ import django.utils.timezone class Migration(migrations.Migration): dependencies = [ - ('location', '0010_auto_20190904_0711'), + ('location', '0011_country_languages'), ('account', '0008_auto_20190912_1325'), ] @@ -21,10 +21,6 @@ class Migration(migrations.Migration): ('created', models.DateTimeField(default=django.utils.timezone.now, editable=False, verbose_name='Date created')), ('modified', models.DateTimeField(auto_now=True, verbose_name='Date updated')), ('role', models.PositiveIntegerField(choices=[(1, 'Standard user'), (2, 'Comments moderator')], verbose_name='Role')), - ('is_list', models.BooleanField(default=True, verbose_name='list')), - ('is_create', models.BooleanField(default=False, verbose_name='create')), - ('is_update', models.BooleanField(default=False, verbose_name='update')), - ('is_delete', models.BooleanField(default=False, verbose_name='delete')), ('country', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='location.Country', verbose_name='Country')), ], options={ @@ -44,4 +40,9 @@ class Migration(migrations.Migration): 'abstract': False, }, ), + migrations.AddField( + model_name='user', + name='roles', + field=models.ManyToManyField(through='account.UserRole', to='account.Role', verbose_name='Roles'), + ), ] diff --git a/apps/account/migrations/0010_auto_20191008_0751.py b/apps/account/migrations/0010_auto_20191008_0751.py deleted file mode 100644 index 289f8643..00000000 --- a/apps/account/migrations/0010_auto_20191008_0751.py +++ /dev/null @@ -1,29 +0,0 @@ -# Generated by Django 2.2.4 on 2019-10-08 07:51 - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('account', '0009_role_userrole'), - ] - - operations = [ - migrations.RemoveField( - model_name='role', - name='is_create', - ), - migrations.RemoveField( - model_name='role', - name='is_delete', - ), - migrations.RemoveField( - model_name='role', - name='is_list', - ), - migrations.RemoveField( - model_name='role', - name='is_update', - ), - ] diff --git a/apps/account/models.py b/apps/account/models.py index c7de88e3..206f5e02 100644 --- a/apps/account/models.py +++ b/apps/account/models.py @@ -19,6 +19,24 @@ from utils.models import ImageMixin, ProjectBaseMixin, PlatformMixin from utils.tokens import GMRefreshToken +class Role(ProjectBaseMixin): + """Base Role model.""" + STANDARD_USER = 1 + COMMENTS_MODERATOR = 2 + + ROLE_CHOICES =( + (STANDARD_USER, 'Standard user'), + (COMMENTS_MODERATOR, 'Comments moderator'), + ) + role = models.PositiveIntegerField(verbose_name=_('Role'), choices=ROLE_CHOICES, + null=False, blank=False) + country = models.ForeignKey(Country, verbose_name=_('Country'), on_delete=models.CASCADE) + # is_list = models.BooleanField(verbose_name=_('list'), default=True, null=False) + # is_create = models.BooleanField(verbose_name=_('create'), default=False, null=False) + # 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): """Extended manager for User model.""" @@ -68,6 +86,7 @@ class User(AbstractUser): USERNAME_FIELD = 'username' REQUIRED_FIELDS = ['email'] + roles = models.ManyToManyField(Role, verbose_name=_('Roles'), through='UserRole') objects = UserManager.from_queryset(UserQuerySet)() class Meta: @@ -198,20 +217,7 @@ class User(AbstractUser): context=context) -class Role(ProjectBaseMixin): - ROLE_CHOICES =( - (1, 'Standard user'), - (2, 'Comments moderator'), - ) - role = models.PositiveIntegerField(verbose_name=_('Role'), choices=ROLE_CHOICES, - null=False, blank=False) - country = models.ForeignKey(Country, verbose_name=_('Country'), on_delete=models.CASCADE) - # is_list = models.BooleanField(verbose_name=_('list'), default=True, null=False) - # is_create = models.BooleanField(verbose_name=_('create'), default=False, null=False) - # is_update = models.BooleanField(verbose_name=_('update'), default=False, null=False) - # is_delete = models.BooleanField(verbose_name=_('delete'), default=False, null=False) - - class UserRole(ProjectBaseMixin): + """UserRole model.""" user = models.ForeignKey(User, verbose_name=_('User'), on_delete=models.CASCADE) role = models.ForeignKey(Role, verbose_name=_('Role'), on_delete=models.SET_NULL, null=True) \ No newline at end of file diff --git a/apps/comment/permissions.py b/apps/comment/permissions.py index 9dacced4..6d691c07 100644 --- a/apps/comment/permissions.py +++ b/apps/comment/permissions.py @@ -2,7 +2,7 @@ from rest_framework import permissions from account.models import UserRole, Role, User -class IsCommentModerator(permissions.BasePermission): +class IsCommentModerator(permissions.IsAuthenticatedOrReadOnly): """ Object-level permission to only allow owners of an object to edit it. Assumes the model instance has an `owner` attribute. @@ -11,23 +11,18 @@ class IsCommentModerator(permissions.BasePermission): def has_object_permission(self, request, view, obj): # Read permissions are allowed to any request, # so we'll always allow GET, HEAD or OPTIONS requests. - if request.method in permissions.SAFE_METHODS: - return True - # # user owner is user request - if obj.user == request.user: + if request.method in permissions.SAFE_METHODS or \ + obj.user == request.user or request.user.is_superuser: return True # Must have role - role = Role.objects.filter(role=2, + role = Role.objects.filter(role=Role.COMMENTS_MODERATOR, country__languages__id=obj.language_id)\ .first() # 'Comments moderator' + is_access = UserRole.objects.filter(user=request.user, role=role).exists() if obj.user != request.user and is_access: return True - super_user = User.objects.filter(pk=request.user.pk, is_superuser=True).exists() - if super_user: - return True - return False diff --git a/apps/comment/views/back.py b/apps/comment/views/back.py index 16450d03..77edfa97 100644 --- a/apps/comment/views/back.py +++ b/apps/comment/views/back.py @@ -5,13 +5,15 @@ from comment.permissions import IsCommentModerator class CommentLstView(generics.ListCreateAPIView): + """Comment list create view.""" serializer_class = serializers.CommentBaseSerializer queryset = models.Comment.objects.all() permission_classes = [permissions.IsAuthenticatedOrReadOnly,] class CommentRUDView(generics.RetrieveUpdateDestroyAPIView): + """Comment RUD view.""" serializer_class = serializers.CommentBaseSerializer queryset = models.Comment.objects.all() - permission_classes = [permissions.IsAuthenticatedOrReadOnly,IsCommentModerator] + permission_classes = [IsCommentModerator] lookup_field = 'id' diff --git a/apps/location/models.py b/apps/location/models.py index f52f9fee..2298c28e 100644 --- a/apps/location/models.py +++ b/apps/location/models.py @@ -8,6 +8,7 @@ from django.utils.translation import gettext_lazy as _ from utils.models import ProjectBaseMixin, SVGImageMixin, TranslatedFieldsMixin, TJSONField from translation.models import Language + class Country(TranslatedFieldsMixin, SVGImageMixin, ProjectBaseMixin): """Country model.""" diff --git a/apps/timetable/migrations/0003_auto_20191004_0928.py b/apps/timetable/migrations/0003_auto_20191004_0928.py deleted file mode 100644 index 6e82c679..00000000 --- a/apps/timetable/migrations/0003_auto_20191004_0928.py +++ /dev/null @@ -1,17 +0,0 @@ -# Generated by Django 2.2.4 on 2019-10-04 09:28 - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('timetable', '0002_auto_20190919_1124'), - ] - - operations = [ - migrations.AlterModelOptions( - name='timetable', - options={'ordering': ['weekday'], 'verbose_name': 'Timetable', 'verbose_name_plural': 'Timetables'}, - ), - ] diff --git a/apps/timetable/migrations/0004_merge_20191009_1341.py b/apps/timetable/migrations/0004_merge_20191009_1341.py deleted file mode 100644 index 22d83ca3..00000000 --- a/apps/timetable/migrations/0004_merge_20191009_1341.py +++ /dev/null @@ -1,14 +0,0 @@ -# Generated by Django 2.2.4 on 2019-10-09 13:41 - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('timetable', '0003_auto_20191004_0928'), - ('timetable', '0003_auto_20191003_0943'), - ] - - operations = [ - ]