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 access.models.other import Invite, Account, Progress
from access.models.other import Invite, Account, Progress, ResetPassword
from access.models.user import User
admin.site.register(User)
admin.site.register(Account)
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': 'Дополнительная информация о пользователе',
},
),
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(
name='Progress',
fields=[

@ -39,11 +39,6 @@ class Migration(migrations.Migration):
name='user',
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(
model_name='account',
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):
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)
date = models.DateTimeField(verbose_name="Дата сгорания приглошения", null=True, blank=True)
password = models.CharField(max_length=63, verbose_name="Новый пароль, если есть", blank=True, null=True)
class Meta:
verbose_name = 'Приглошение в систему'
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):
GENDER_CHOICES = (
(0, 'undefined'),

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

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

Loading…
Cancel
Save