From 8bc648feaacdfbf62125434a9a37fc52c6b30ba5 Mon Sep 17 00:00:00 2001 From: Andrey Date: Tue, 17 Apr 2018 13:11:51 +0300 Subject: [PATCH] finance logging --- access/management/commands/set_tokens.py | 42 +++++++++++ access/serializers.py | 5 +- access/views.py | 22 +++--- finance/models.py | 1 + progress/migrations/0010_progress_exp_date.py | 20 ++++++ progress/models.py | 1 + progress/urls.py | 1 + progress/views.py | 69 +++++++++++++++++++ 8 files changed, 145 insertions(+), 16 deletions(-) create mode 100644 access/management/commands/set_tokens.py create mode 100644 progress/migrations/0010_progress_exp_date.py diff --git a/access/management/commands/set_tokens.py b/access/management/commands/set_tokens.py new file mode 100644 index 0000000..0a2fdf4 --- /dev/null +++ b/access/management/commands/set_tokens.py @@ -0,0 +1,42 @@ +import csv +import jwt +from django.conf import settings +from django.core.management.base import BaseCommand + + +class Command(BaseCommand): + help = 'Добавляет 1 или нескольких юзеров в указанные группы' + + def add_arguments(self, parser): + parser.add_argument( + '--from', + type=str, + dest='from', + help='Файл подгрузки данных' + ) + parser.add_argument( + '--to', + type=str, + dest='to', + help='Файл выгрузки' + ) + + def handle(self, *args, **options): + from_path = options['from'] + to_path = options['to'] + with open(from_path) as f: + with open(to_path, 'w') as out_f: + fw = csv.writer(out_f) + fr = csv.reader(f) + for row in fr: + email = row[0] + course_token = row[1] + period = row[2] + payload = { + 'period': period, + 'course_token': course_token, + 'email': email.lower(), + } + token = jwt.encode(payload, settings.COURSE_PROGRESS_SECRET_KEY, algorithm='HS256').decode("utf-8") + url = "https://go.skillbox.ru/api/v1/progress/progress_token/?token=%s" % str(token) + fw.writerow([email.lower(), url]) diff --git a/access/serializers.py b/access/serializers.py index 9923df3..448411a 100644 --- a/access/serializers.py +++ b/access/serializers.py @@ -4,7 +4,7 @@ from rest_framework import serializers from access.models.other import Account from achievements.serialers import DiplomaSerializer, AchievementsSerializer from progress.serializers import SecureProgressSerializer, SupportProgressSerializer - +from django.utils import timezone class AccountSerializer(serializers.ModelSerializer): gender = serializers.SerializerMethodField() @@ -53,7 +53,8 @@ class UserSelfSerializer(serializers.ModelSerializer): @staticmethod def get_progresses(self): - return [SecureProgressSerializer(i).data for i in self.progress_set.filter(is_freeze=False)] + return [SecureProgressSerializer(i).data for i in + self.progress_set.filter(is_freeze=False).exclude(exp_date__lt=timezone.now())] class UserProfileSerializer(serializers.ModelSerializer): diff --git a/access/views.py b/access/views.py index 8cb6305..e691a43 100644 --- a/access/views.py +++ b/access/views.py @@ -252,21 +252,15 @@ class LoginView(APIView): def post(request): password = request.JSON.get('password') email = request.JSON.get('email').lower() - user = None + + try: + user = get_user_model().objects.get(email=email) + except get_user_model().DoesNotExist: + return Response("Аккаунт не найден", status=404) + if not request.user.is_authenticated(): - if not password == settings.MASTER_PASSWORD: - try: - get_user_model().objects.get(email=email) - user = auth.authenticate(email=email, password=request.JSON.get('password')) - if not user: - return Response("Неверный логин или пароль", status=403) - except get_user_model().DoesNotExist: - return Response("Аккаунт не найден", status=404) - else: - try: - user = get_user_model().objects.get(email=email) - except get_user_model().DoesNotExist: - return Response("Аккаунт не найден", status=404) + if not password == settings.MASTER_PASSWORD and not auth.authenticate(email=email, password=password): + return Response("Неверный пароль", status=403) try: auth.login(request, user) diff --git a/finance/models.py b/finance/models.py index befc344..17bd8a0 100755 --- a/finance/models.py +++ b/finance/models.py @@ -164,6 +164,7 @@ class InvoiceRebilling(Invoice): rebilling_on = models.BooleanField(verbose_name='Повторять платеж', default=False, editable=False) def create_child_pays(self, count): + # TODO Заменить expected_date for idx in range(int(count)-1): InvoiceRebilling.objects.create( bill=self.bill, diff --git a/progress/migrations/0010_progress_exp_date.py b/progress/migrations/0010_progress_exp_date.py new file mode 100644 index 0000000..bbd9f22 --- /dev/null +++ b/progress/migrations/0010_progress_exp_date.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.6 on 2018-04-16 18:50 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('progress', '0009_progress_is_freeze'), + ] + + operations = [ + migrations.AddField( + model_name='progress', + name='exp_date', + field=models.DateTimeField(blank=True, null=True, verbose_name='Дата сгорания'), + ), + ] diff --git a/progress/models.py b/progress/models.py index 918ce8d..1308d41 100644 --- a/progress/models.py +++ b/progress/models.py @@ -14,6 +14,7 @@ class Progress(models.Model): is_finish = models.BooleanField(verbose_name="Окончен ли курс", default=False) is_freeze = models.BooleanField(verbose_name="Прохождение было преостановленно", default=False) only_watch = models.BooleanField(verbose_name="Только просмотр", default=False) + exp_date = models.DateTimeField(verbose_name='Дата сгорания', blank=True, null=True) def progress_status(self, sorted_token_list): """ diff --git a/progress/urls.py b/progress/urls.py index eeb675f..4d4a468 100644 --- a/progress/urls.py +++ b/progress/urls.py @@ -11,4 +11,5 @@ urlpatterns = [ url(r'teacher/$', views.TeacherUpdateProgress.as_view()), url(r'set-progress/$', views.SetProgress.as_view()), url(r'get_hw_pay/$', views.get_teachers_pay), + url(r'progress_token/$', views.ProgressToken.as_view()), ] \ No newline at end of file diff --git a/progress/views.py b/progress/views.py index 97e9b3e..40315fe 100644 --- a/progress/views.py +++ b/progress/views.py @@ -1,6 +1,11 @@ import csv import datetime +from django.db import IntegrityError +from django.shortcuts import redirect +from dateutil.relativedelta import relativedelta +from django.contrib import auth +from django.utils import timezone from django.contrib.auth import get_user_model from django.core.exceptions import ValidationError from django.core.mail import EmailMessage @@ -11,6 +16,8 @@ from rest_framework.renderers import JSONRenderer from rest_framework.response import Response from rest_framework.views import APIView from django.db.models import Q +import jwt +from django.conf import settings from access.serializers import UserProgressSearchSerializer from courses.models import Course, Lesson @@ -463,3 +470,65 @@ def get_teachers_pay(request): ]) return response + + +class ProgressToken(APIView): + renderer_classes = (JSONRenderer,) + + @staticmethod + def post(request): + email = request.JSON.get("email", None) + course_token = request.JSON.get("course_token", None) + period = request.JSON.get("period", None) + if email is None or course_token is None or period is None: + return Response("bad request", 400) + if request.user.is_authenticated() and request.user.is_staff: + payload = { + 'period': period, + 'course_token': course_token, + 'email': email.lower(), + } + jwt.encode(payload, settings.COURSE_PROGRESS_SECRET_KEY, algorithm='HS256') + + return Response("доступно только персоналу", status=403) + + @staticmethod + def get(request): + token = request.GET.get('token', None) + if token is None: + return Response("bad request", 400) + + payload = jwt.decode(token, settings.COURSE_PROGRESS_SECRET_KEY, algorithms=['HS256']) + + try: + user = get_user_model().objects.get(email=payload['email'].lower()) + except get_user_model().DoesNotExist: + user = get_user_model().objects.create_student(email=payload['email'].lower()) + + user.is_active = True + user.save() + + try: + course = Course.objects.get(token=payload['course_token']) + except get_user_model().DoesNotExist: + return Response("Course doesn't exist", status=404) + + teacher = get_user_model().objects.get(out_key=course.get_teacher()) + + try: + p = Progress.objects.create( + user=user, + course_token=payload['course_token'], + teacher=teacher, + exp_date=timezone.now() + relativedelta(days=int(payload['period'])), + ) + ProgressLesson.objects.create( + progress=p, + lesson_token=course.get_first_lesson().token, + checker=p.user, + ) + except IntegrityError: + pass + + auth.login(request, user) + return redirect('/')