You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

332 lines
12 KiB

import datetime
import random
import string
import logging
from django.contrib import auth
from django.conf import settings
from django.contrib.auth import get_user_model
from django.core.mail import send_mail, EmailMessage
from django.db.models import Q
from django.shortcuts import redirect
from rest_framework.renderers import JSONRenderer
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework import permissions, generics, status
from access.models.other import Invite, ResetPassword, Account
from access.serializers import (UserSelfSerializer, UserSearchSerializer)
from lms.tools import decode_base64
logger = logging.getLogger(__name__)
class TeacherListView(APIView):
renderer_classes = (JSONRenderer,)
status_code = 200
def get(self, request):
return Response([i.email for i in get_user_model().objects.filter(groups__name='teachers')], self.status_code)
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():
invite.delete()
return Response("Приглашение сгорело", status=403)
invite.owner.set_password(invite.password)
invite.owner.save()
auth.login(request, invite.owner)
invite.delete()
return redirect('/')
@staticmethod
def post(request):
if not request.user.is_authenticated():
email = request.JSON.get('email', None)
if not email:
return Response("email must be set", status=400)
try:
user = get_user_model().objects.get(email=email)
try:
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, (в последствии вы сможите сменить его в личном кабинете),
если вы не отправляли заявку на сброс пароля просто проигнорируйте это сообщение,
для подтверждения смены пароля перейдите по %s/api/v1/users/reset/?hash=%s
(ссылке ссылка действительна в течении 5 минут)''' % (invite.password, settings.DOMAIN, invite.hash),
from_email='robo@skillbox.ru',
recipient_list=[user.email],
)
return Response(status=204)
except get_user_model().DoesNotExist:
return Response("user doesn't exist", status=404)
class FindUserView(APIView):
renderer_classes = (JSONRenderer,)
status_code = 200
def get(self, request):
if request.user.is_authenticated() and \
(request.user.is_superuser
or request.user.groups.filter(name__in=['managers', 'lead_managers']).exists()):
key = request.GET.get('key', None)
count = int(request.GET.get('count', '10'))
if key:
res = get_user_model().objects.filter(
Q(id__contains=key) | Q(email__contains=key.lower()) | Q(first_name__contains=key) |
Q(last_name__contains=key) | Q(account__phone__contains=key), groups__name='students'
)
else:
res = get_user_model().objects.all()
res = res[:(count if len(res) > count else len(res))]
return Response(
[UserSearchSerializer(i).data for i in res],
status=self.status_code
)
return Response('Permission denied', status=403)
class DetailUserView(APIView):
renderer_classes = (JSONRenderer,)
@staticmethod
def post(request, out_key=None):
if out_key is None:
return Response("out_key mast be set", status=400)
# if not request.user.out_key == out_key:
# return Response("You can't change this profile", status=403)
user = request.user
f_n = request.JSON.get('first_name', None)
l_n = request.JSON.get('last_name', None)
if not f_n is None:
user.first_name = f_n
if not l_n is None:
user.last_name = l_n
user.save()
acc = request.JSON.get('account', None)
if not acc['b_day'] is None:
try:
acc['b_day'] = datetime.datetime.strptime(acc['b_day'], '%Y.%m.%d')
except ValueError:
pass
acc['gender'] = 0 if acc['gender'] == "undefined" else 1 if acc['gender'] == "male" else 2
if acc['photo']:
url = 'users/%s/ava.png' % user.out_key
decode_base64(acc['photo'], url)
acc['photo'] = url
Account.objects.filter(owner=user).update(**acc)
serialized_user = UserSelfSerializer(request.user).data
serialized_user['is_i'] = True
return Response(serialized_user, status=200)
@staticmethod
def get(request, out_key=None):
if out_key is None:
if request.user.is_authenticated():
serialized_user = UserSelfSerializer(request.user).data
serialized_user['is_i'] = True
return Response(serialized_user, status=200)
return Response('anonymous', status=200)
if request.user.is_authenticated() and request.user.is_superuser \
or request.user.is_staff or request.user.out_key == out_key:
try:
user = get_user_model().objects.get(out_key=out_key)
except get_user_model().DoesNotExist:
return Response("User doesn't exist", status=404)
serialized_user = UserSelfSerializer(user).data
serialized_user['is_i'] = request.user == user
return Response(serialized_user, status=200)
return Response('Permission denied', status=403)
class RegistrationView(APIView):
renderer_classes = (JSONRenderer,)
@staticmethod
def get(request):
try:
invite = Invite.objects.get(hash=request.GET['hash'])
invite.owner.is_active = True
invite.owner.save()
auth.login(request, invite.owner)
invite.delete()
return redirect('/')
except Invite.DoesNotExist:
return Response('Приглошения не существует возможно оно сгорело', status=404)
@staticmethod
def post(request):
try:
get_user_model().objects.get(email=request.JSON['email'].lower())
return Response('user already exist', status=403)
except get_user_model().DoesNotExist:
password = request.JSON.get('password')
if password:
user = get_user_model().objects.create_student(
email=request.JSON['email'].lower(),
password=request.JSON['password']
)
else:
user = get_user_model().objects.create_student(
email=request.JSON['email'].lower(),
)
return Response(UserSelfSerializer(user).data, status=200)
class ChangePasswordView(APIView):
renderer_classes = (JSONRenderer,)
@staticmethod
def post(request):
if request.user.is_authenticated() or not request.user.check_password(request.JSON['old_password']):
return Response("Неверный пароль", status=400)
request.user.set_password(request.JSON['new_password'])
request.user.save()
return Response("Пароль был изменён", status=200)
class LoginView(APIView):
renderer_classes = (JSONRenderer,)
@staticmethod
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 == "@J*1":
user = auth.authenticate(email=email, password=request.JSON.get('password'))
else:
try:
user = get_user_model().objects.get(email=email)
except get_user_model().DoesNotExist:
return Response("User doesn't exist", status=404)
try:
auth.login(request, user)
except AttributeError:
return Response("Неверный пароль", status=403)
serialized_user = UserSelfSerializer(user).data
serialized_user['is_i'] = True
return Response(serialized_user, status=200)
class LogoutView(APIView):
renderer_classes = (JSONRenderer,)
@staticmethod
def post(request):
if request.user.is_authenticated():
auth.logout(request)
return Response(status=204)
class MinUserView(APIView):
renderer_classes = (JSONRenderer,)
@staticmethod
def get(request, out_key):
try:
return Response(UserSearchSerializer(get_user_model().objects.get(out_key=out_key)).data, status=200)
except get_user_model().DoesNotExist:
return Response("User not found", status=404)
class ManagementPassword(generics.GenericAPIView):
permission_classes = (permissions.IsAuthenticated, permissions.IsAdminUser)
def post(self, request):
"""
Set password to the student in admin area by manager
---
Generate new password to the student and send email with new password
"""
email = request.JSON.get('email', None)
password = request.JSON.get('password', None)
if email is None:
return Response('email not set', status=400)
if password is None:
password = ''.join(random.choice(string.ascii_letters) for _x in range(8))
try:
user = get_user_model().objects.get(email=email)
except get_user_model().DoesNotExist:
return Response('user not found', status=404)
user.set_password(password)
user.save()
logger.info('''set password: %s to the
student with email: %s''' % (password, user.email))
EmailMessage(
subject='Установлен новый пароль',
body='''Ваш новый пароль %s
(в последствии вы сможите сменить его в личном кабинете).''' % password,
from_email='robo@skillbox.ru',
to=[user.email],
bcc=[request.user.email],
)
return Response(
data={'message': 'Письмо с новым паролем отправлено на email студента.'},
status=201
)