From c18b5d556f8155fc9c4a3a5700790fa674ca4605 Mon Sep 17 00:00:00 2001 From: Andrey Date: Tue, 21 Nov 2017 14:24:17 +0300 Subject: [PATCH] a --- .../commands/add_users_in_groups.py | 7 +- access/migrations/0009_auto_20171119_1736.py | 20 ++++ access/migrations/0010_teacher.py | 29 ++++++ access/migrations/0011_delete_teacher.py | 18 ++++ access/models.py | 11 ++- access/urls.py | 1 + access/views.py | 93 +++++++++++++++++-- courses/models.py | 6 +- 8 files changed, 168 insertions(+), 17 deletions(-) create mode 100644 access/migrations/0009_auto_20171119_1736.py create mode 100644 access/migrations/0010_teacher.py create mode 100644 access/migrations/0011_delete_teacher.py diff --git a/access/management/commands/add_users_in_groups.py b/access/management/commands/add_users_in_groups.py index 5d8b87f..830ba01 100644 --- a/access/management/commands/add_users_in_groups.py +++ b/access/management/commands/add_users_in_groups.py @@ -1,9 +1,6 @@ from django.contrib.auth import get_user_model from django.contrib.auth.models import Group -from django.core.management.base import BaseCommand, CommandError -import os -import shutil -from django.conf import settings +from django.core.management.base import BaseCommand class Command(BaseCommand): @@ -31,6 +28,7 @@ class Command(BaseCommand): for name in options['groups_names'].split(', '): try: g = Group.objects.get(name=name) + g.user_set.add(user) except Group.DoesNotExist: print("""Group with name "%s" doesn't exist""") @@ -39,7 +37,6 @@ class Command(BaseCommand): user.is_staff = True if name != "students": user.is_staff = True - g.user_set.add(user) user.save() except get_user_model().DoesNotExist: print("""user with email: "%s" not found""" % email) \ No newline at end of file diff --git a/access/migrations/0009_auto_20171119_1736.py b/access/migrations/0009_auto_20171119_1736.py new file mode 100644 index 0000000..5ac943a --- /dev/null +++ b/access/migrations/0009_auto_20171119_1736.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.6 on 2017-11-19 17:36 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('access', '0008_auto_20171117_1113'), + ] + + operations = [ + migrations.AlterField( + model_name='account', + name='photo', + field=models.ImageField(blank=True, default='/static/default/access/default.png', null=True, upload_to='user/photo/'), + ), + ] diff --git a/access/migrations/0010_teacher.py b/access/migrations/0010_teacher.py new file mode 100644 index 0000000..cff8448 --- /dev/null +++ b/access/migrations/0010_teacher.py @@ -0,0 +1,29 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.6 on 2017-11-20 12:34 +from __future__ import unicode_literals + +import access.models +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('access', '0009_auto_20171119_1736'), + ] + + operations = [ + migrations.CreateModel( + name='Teacher', + fields=[ + ], + options={ + 'proxy': True, + 'indexes': [], + }, + bases=('access.user',), + managers=[ + ('objects', access.models.CustomUserManager()), + ], + ), + ] diff --git a/access/migrations/0011_delete_teacher.py b/access/migrations/0011_delete_teacher.py new file mode 100644 index 0000000..6467113 --- /dev/null +++ b/access/migrations/0011_delete_teacher.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.6 on 2017-11-20 12:37 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('access', '0010_teacher'), + ] + + operations = [ + migrations.DeleteModel( + name='Teacher', + ), + ] diff --git a/access/models.py b/access/models.py index c4240c0..477e332 100755 --- a/access/models.py +++ b/access/models.py @@ -41,7 +41,7 @@ class Account(models.Model): city = models.CharField(max_length=63, null=True, blank=True) gender = models.SmallIntegerField(choices=GENDER_CHOICES, default=0) owner = models.OneToOneField(to=settings.AUTH_USER_MODEL) - photo = models.ImageField(null=True, blank=True, default='user/photo/default_avatar.png', upload_to='user/photo/') + photo = models.ImageField(null=True, blank=True, default='/static/default/access/default.png', upload_to='user/photo/') phone = models.CharField(max_length=15, null=True, blank=True) def __str__(self): @@ -86,6 +86,12 @@ class CustomUserManager(BaseUserManager): user = self.model(email=email, is_staff=is_staff, is_active=is_active, first_name=first_name, is_superuser=is_superuser, date_joined=date_joined, last_login=last_login, **extra_fields) + Thread.objects.create( + key="""user_%s""" % user.id, + text="""Приватный тред пользователя %s""" % user.email, + is_recurse=True, + ) + if not password: password = ''.join(random.choice(string.ascii_letters) for x in range(8)) @@ -157,6 +163,9 @@ class User(AbstractBaseUser, PermissionsMixin): def get_short_name(self): return self.first_name + def get_thread(self): + Thread.objects.get(key="""user_%s""" % self.id,) + class Meta: verbose_name = _('Пользователь') verbose_name_plural = _('Пользователи') diff --git a/access/urls.py b/access/urls.py index 019b0ef..d13a251 100644 --- a/access/urls.py +++ b/access/urls.py @@ -5,6 +5,7 @@ urlpatterns = [ url(r'teachers/$', views.TeacherListView.as_view()), url(r'info/$', views.InfoUserView.as_view()), url(r'detail/([0-9]{1,99})/$', views.DetailUserView.as_view()), + url(r'guard/(?P[0-9]{1,99})/(?P.+)/$', views.UserGuardView.as_view()), url(r'find/$', views.FindUserView.as_view()), url(r'check/$', views.CheckUserView.as_view()), url(r'registration/$', views.RegistrationView.as_view()), diff --git a/access/views.py b/access/views.py index cd14ef9..8b8b748 100644 --- a/access/views.py +++ b/access/views.py @@ -1,6 +1,7 @@ from django.contrib.auth import get_user_model from django.contrib import auth from django.shortcuts import redirect +from rest_framework.permissions import IsAuthenticated from rest_framework.views import APIView from rest_framework.renderers import JSONRenderer from rest_framework.response import Response @@ -9,6 +10,7 @@ from django.db.models import Q from access.models import Invite, Progress, ExtraPrivilege from access.serializers import UserInitSerializer, UserSearchSerializer, UserProfileSerializer from courses.models import Vertex +from journals.models import Thread class TeacherListView(APIView): @@ -72,18 +74,22 @@ class FindUserView(APIView): class DetailUserView(APIView): renderer_classes = (JSONRenderer,) + permission_classes = (IsAuthenticated,) @staticmethod def get(request, pk): - if request.user.is_authenticated() and \ - (request.user.is_superuser or request.user.is_staff or request.user.id == pk): + if request.user.is_superuser or request.user.is_staff or request.user.id == pk: try: user = get_user_model().objects.get(id=pk) except get_user_model().DoesNotExist: return Response("User doesn't exist", status=404) - return Response(UserProfileSerializer(user).data, status=200) + serialized_user = UserProfileSerializer(user).data + + serialized_user['is_i'] = request.user == user + + return Response(serialized_user, status=200) return Response('Permission denied', status=403) @@ -168,20 +174,55 @@ class UpdateProgress(APIView): @staticmethod def post(request): + """ + На вход обязательно передаётся параметр id (id узла). + """ pk = int(request.JSON.get('id')) + res_403 = Response('Permission denied', status=403) + try: vertex = Vertex.objects.get(id=pk) except Vertex.DoesNotExist: return Response("Объект не найден", status=404) - next_vertex = vertex.get_next(['task', 'tutorial']) + if vertex.content_type.model == 'task': + return res_403 try: - progress = Progress.objects.get(user=request.user, course=vertex.course) - if progress.active_obj == vertex: - if next_vertex.is_more(progress.active_obj): - progress.active_obj = next_vertex - progress.save() + next_vertex = vertex.get_next(['task', 'tutorial']) + except ValueError: + next_vertex = None + + try: + progress = Progress.objects.get(user=request.user, course=vertex.course, active_obj=vertex) + progress.active_obj = next_vertex + + if not next_vertex: + progress.success = True + + if next_vertex.content_type.model == 'task': + """ + создание тредов для приёма домашки + """ + thread, is_create = Thread.objects.get_or_create( + key="""user_%s__user_%s""" % (vertex.course.get_teacher().id, request.user.id,), + text="""Приватный диалог %s и %s""" % (vertex.course.get_teacher().email, request.user.email,), + is_recurse=True, + ) + + if is_create: + thread.subscribers.add(request.user) + thread.subscribers.add(vertex.course.get_teacher()) + + child_thread = Thread.objects.create( + key="""user_%s__vertex_%s""" % (request.id, vertex.id,), + text="""Домашняя работа по курсу %s и теме %s для студента %s""" % + (vertex.course.title, vertex.vertex_set.all()[0].title, request.user.get_full_name()), + ) + + child_thread.parent.add(thread) + + progress.save() return Response({'id': progress.active_obj.id, 'type': progress.active_obj.content_type.model}, status=200) except Progress.DoesNotExist: pass @@ -192,4 +233,36 @@ class UpdateProgress(APIView): privilege.save() return Response({'id': next_vertex.id, 'type': next_vertex.content_type.model}, status=200) except ExtraPrivilege.DoesNotExist: - return Response('У вас нет прав', status=403) \ No newline at end of file + return res_403 + + +class UserGuardView(APIView): + renderer_classes = (JSONRenderer,) + permission_classes = (IsAuthenticated,) + + @staticmethod + def get(request, pk, page): + try: + user = get_user_model().objects.get(id=pk) + except get_user_model().DoesNotExist: + return Response("User doesn't exist", status=404) + + is_i = request.user == user + res_403 = Response('Permission denied', status=403) + res_204 = Response(status=204) + + if is_i and not request.user.groups.filter(name='teachers').exists() and page == 'homeworks': + return res_403 + + if is_i and not \ + request.user.groups.filter(name__in=['students', 'managers', 'lead_managers']).exists() \ + and page == 'payment': + return res_403 + + if is_i: + return res_204 + + if page == 'profile' and (request.user.is_superuser or request.user.is_staff): + return res_204 + + return res_403 diff --git a/courses/models.py b/courses/models.py index 1cbfe80..696669e 100755 --- a/courses/models.py +++ b/courses/models.py @@ -55,7 +55,8 @@ class CourseManager(models.Manager): try: course = self.get(id=id) for i in kwargs: - setattr(course, i, kwargs[i]) + if kwargs[i]: + setattr(course, i, kwargs[i]) course.save() except ObjectDoesNotExist: kwargs['slug'] = slug @@ -93,6 +94,9 @@ class Course(models.Model): def __str__(self): return self.title + def get_teacher(self): + return + def get_tree(self, serializer): """ Способ отображения дочерних элементов.