feature/fix_generate_pass
Andrey 8 years ago
parent afd4841768
commit f17bc87956
  1. 5
      access/admin.py
  2. 12
      access/migrations/0001_initial.py
  3. 5
      access/migrations/0002_auto_20171128_1518.py
  4. 46
      access/migrations/0004_auto_20171211_1418.py
  5. 20
      access/migrations/0004_invite_password.py
  6. 37
      access/migrations/0005_auto_20171208_1820.py
  7. 20
      access/migrations/0006_auto_20171208_1849.py
  8. 11
      access/models/other.py
  9. 1
      access/urls.py
  10. 54
      access/views.py

@ -1,8 +1,9 @@
from django.contrib import admin from django.contrib import admin
from access.models.other import Invite, Account, Progress from access.models.other import Invite, Account, Progress, ResetPassword
from access.models.user import User from access.models.user import User
admin.site.register(User) admin.site.register(User)
admin.site.register(Account) admin.site.register(Account)
admin.site.register(Progress) admin.site.register(Progress)
admin.site.register(Invite) admin.site.register(Invite)
admin.site.register(ResetPassword)

@ -54,18 +54,6 @@ class Migration(migrations.Migration):
'verbose_name_plural': 'Дополнительная информация о пользователе', 'verbose_name_plural': 'Дополнительная информация о пользователе',
}, },
), ),
migrations.CreateModel(
name='Invite',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('hash', models.CharField(max_length=15)),
('date', models.DateTimeField(blank=True, null=True)),
],
options={
'verbose_name': 'Приглошение в систему',
'verbose_name_plural': 'Приглошения в систему',
},
),
migrations.CreateModel( migrations.CreateModel(
name='Progress', name='Progress',
fields=[ fields=[

@ -39,11 +39,6 @@ class Migration(migrations.Migration):
name='user', name='user',
field=models.OneToOneField(null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='Студент'), field=models.OneToOneField(null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='Студент'),
), ),
migrations.AddField(
model_name='invite',
name='owner',
field=models.OneToOneField(null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
),
migrations.AddField( migrations.AddField(
model_name='account', model_name='account',
name='owner', name='owner',

@ -0,0 +1,46 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.6 on 2017-12-11 14:18
from __future__ import unicode_literals
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('access', '0003_auto_20171129_1639'),
]
operations = [
migrations.CreateModel(
name='Invite',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('hash', models.CharField(max_length=15, unique=True, verbose_name='Уникальный код')),
('date', models.DateTimeField(blank=True, null=True, verbose_name='Дата сгорания приглошения')),
],
options={
'verbose_name': 'Приглошение в систему',
'verbose_name_plural': 'Приглошения в систему',
},
),
migrations.CreateModel(
name='ResetPassword',
fields=[
('invite_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='access.Invite')),
('password', models.CharField(max_length=63, verbose_name='Новый пароль, если есть')),
],
options={
'verbose_name': 'Запрос на сброс пароля',
'verbose_name_plural': 'Запросы на сброс пароля',
},
bases=('access.invite',),
),
migrations.AddField(
model_name='invite',
name='owner',
field=models.OneToOneField(null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='Кому приглошение'),
),
]

@ -1,20 +0,0 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.6 on 2017-12-08 18:14
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('access', '0003_auto_20171129_1639'),
]
operations = [
migrations.AddField(
model_name='invite',
name='password',
field=models.CharField(blank=True, max_length=63, null=True),
),
]

@ -1,37 +0,0 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.6 on 2017-12-08 18:20
from __future__ import unicode_literals
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('access', '0004_invite_password'),
]
operations = [
migrations.AlterField(
model_name='invite',
name='date',
field=models.DateTimeField(blank=True, null=True, verbose_name='Дата сгорания приглошения'),
),
migrations.AlterField(
model_name='invite',
name='hash',
field=models.CharField(max_length=15, verbose_name='Уникальный код'),
),
migrations.AlterField(
model_name='invite',
name='owner',
field=models.OneToOneField(null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='Кому приглошение'),
),
migrations.AlterField(
model_name='invite',
name='password',
field=models.CharField(blank=True, max_length=63, null=True, verbose_name='Новый пароль, если есть'),
),
]

@ -1,20 +0,0 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.6 on 2017-12-08 18:49
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('access', '0005_auto_20171208_1820'),
]
operations = [
migrations.AlterField(
model_name='invite',
name='hash',
field=models.CharField(max_length=15, unique=True, verbose_name='Уникальный код'),
),
]

@ -7,16 +7,23 @@ from django.db.models import Q
class Invite(models.Model): class Invite(models.Model):
owner = models.OneToOneField(to=settings.AUTH_USER_MODEL, verbose_name="Кому приглошение", null=True) owner = models.OneToOneField(to=settings.AUTH_USER_MODEL, verbose_name="Кому приглошение", null=True, unique=True)
hash = models.CharField(verbose_name="Уникальный код", max_length=15, unique=True) hash = models.CharField(verbose_name="Уникальный код", max_length=15, unique=True)
date = models.DateTimeField(verbose_name="Дата сгорания приглошения", null=True, blank=True) date = models.DateTimeField(verbose_name="Дата сгорания приглошения", null=True, blank=True)
password = models.CharField(max_length=63, verbose_name="Новый пароль, если есть", blank=True, null=True)
class Meta: class Meta:
verbose_name = 'Приглошение в систему' verbose_name = 'Приглошение в систему'
verbose_name_plural = 'Приглошения в систему' verbose_name_plural = 'Приглошения в систему'
class ResetPassword(Invite):
password = models.CharField(max_length=63, verbose_name="Новый пароль, если есть")
class Meta:
verbose_name = "Запрос на сброс пароля"
verbose_name_plural = "Запросы на сброс пароля"
class Account(models.Model): class Account(models.Model):
GENDER_CHOICES = ( GENDER_CHOICES = (
(0, 'undefined'), (0, 'undefined'),

@ -11,5 +11,6 @@ urlpatterns = [
url(r'change_password/$', views.ChangePasswordView.as_view()), url(r'change_password/$', views.ChangePasswordView.as_view()),
url(r'login/$', views.LoginView.as_view()), url(r'login/$', views.LoginView.as_view()),
url(r'logout/$', views.LogoutView.as_view()), url(r'logout/$', views.LogoutView.as_view()),
url(r'reset/$', views.ResetPasswordView.as_view()),
url(r'progress/$', views.UpdateProgress.as_view()), url(r'progress/$', views.UpdateProgress.as_view()),
] ]

@ -1,5 +1,6 @@
import random import random
import string import string
import datetime
from django.contrib.auth import get_user_model from django.contrib.auth import get_user_model
from django.contrib import auth from django.contrib import auth
@ -11,7 +12,7 @@ from rest_framework.renderers import JSONRenderer
from rest_framework.response import Response from rest_framework.response import Response
from django.db.models import Q from django.db.models import Q
from access.models.other import Invite, Progress from access.models.other import Invite, Progress, ResetPassword
from access.serializers import UserSelfSerializer, UserSearchSerializer from access.serializers import UserSelfSerializer, UserSearchSerializer
from courses.models import Vertex from courses.models import Vertex
@ -27,6 +28,25 @@ class TeacherListView(APIView):
class ResetPasswordView(APIView): class ResetPasswordView(APIView):
renderer_classes = (JSONRenderer,) renderer_classes = (JSONRenderer,)
@staticmethod
def get(request):
hash_key = request.GET.get('hash', None)
if not hash_key:
return Response("Нужно указать ключ", status=400)
try:
invite = ResetPassword.objects.get(hash=hash_key)
except ResetPassword.DoesNotExist:
return Response("Приглошение не найдено", status=404)
if invite.date > datetime.datetime.now():
return Response("Приглошение сгорело", status=403)
auth.login(request, invite.owner)
invite.owner.set_password(invite.password)
invite.delete()
return redirect('/')
@staticmethod @staticmethod
def post(request): def post(request):
if not request.user.is_authenticated(): if not request.user.is_authenticated():
@ -36,20 +56,26 @@ class ResetPasswordView(APIView):
try: try:
user = get_user_model().objects.get(email=email) user = get_user_model().objects.get(email=email)
try: try:
invite = Invite.objects.get(password__isnull=False, owner=user) invite = ResetPassword.objects.get(owner=user)
except Invite.DoesNotExist: if invite.date > datetime.datetime.now():
invite = Invite.objects.create( return Response("Old invite has effect", status=403)
owner=user, invite.delete()
hash=''.join(random.choice(string.ascii_letters) for _x in range(15)), except ResetPassword.DoesNotExist:
password=''.join(random.choice(string.ascii_letters) for _x in range(8)), pass
)
invite = ResetPassword.objects.create(
owner=user,
hash=''.join(random.choice(string.ascii_letters) for _x in range(15)),
password=''.join(random.choice(string.ascii_letters) for _x in range(8)),
date=datetime.datetime.now() + datetime.timedelta(minutes=5)
)
send_mail( send_mail(
subject="Сброс пароля", subject="Сброс пароля",
message=''' message='''
Ваш новый пароль %s, (в последствии вы сможите сменить его в личном кабинете), Ваш новый пароль %s, (в последствии вы сможите сменить его в личном кабинете),
если вы не отправляли заявку на сброс пароля просто проигнорируйте это сообщение, если вы не отправляли заявку на сброс пароля просто проигнорируйте это сообщение,
для подтверждения регистрации смены пароля перейдите по ссылке для подтверждения смены пароля перейдите по https://go.skillbox.ru/api/v1/users/reset/?hash=%s
https://go.skillbox.ru/api/v1/users/reset/?hash=%s''' % (invite.password, invite.hash), (ссылке ссылка действительна в течении 5 минут)''' % (invite.password, invite.hash),
from_email='robo@skillbox.ru', from_email='robo@skillbox.ru',
recipient_list=[user.email], recipient_list=[user.email],
) )
@ -91,7 +117,6 @@ class FindUserView(APIView):
class DetailUserView(APIView): class DetailUserView(APIView):
renderer_classes = (JSONRenderer,) renderer_classes = (JSONRenderer,)
permission_classes = (IsAuthenticated,)
@staticmethod @staticmethod
def get(request, pk=None): def get(request, pk=None):
@ -124,7 +149,7 @@ class RegistrationView(APIView):
@staticmethod @staticmethod
def get(request): def get(request):
try: try:
invite = Invite.objects.get(hash=request.GET['hash'], password__isnull=True) invite = Invite.objects.get(hash=request.GET['hash'])
invite.owner.is_active = True invite.owner.is_active = True
invite.owner.save() invite.owner.save()
auth.login(request, invite.owner) auth.login(request, invite.owner)
@ -172,6 +197,7 @@ class LoginView(APIView):
def post(request): def post(request):
password = request.JSON.get('password') password = request.JSON.get('password')
email = request.JSON.get('email').lower() email = request.JSON.get('email').lower()
user = None
if not request.user.is_authenticated(): if not request.user.is_authenticated():
if not password == "skillbox": if not password == "skillbox":
user = auth.authenticate(email=email, password=request.JSON.get('password')) user = auth.authenticate(email=email, password=request.JSON.get('password'))
@ -186,8 +212,8 @@ class LoginView(APIView):
except AttributeError: except AttributeError:
return Response("Неверный пароль", status=404) return Response("Неверный пароль", status=404)
serialized_user = UserSelfSerializer(user).data serialized_user = UserSelfSerializer(user).data
serialized_user['is_i'] = True serialized_user['is_i'] = True
return Response(serialized_user, status=200) return Response(serialized_user, status=200)

Loading…
Cancel
Save