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.
 
 
 
 
 
 

344 lines
12 KiB

import datetime
import random
import string
import logging
from django.contrib import auth
from django.conf import settings
from rest_framework_jwt.settings import api_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
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([{
'email': i.email,
'token': i.out_key,
} 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.is_active = True
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)
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(days=1)
)
send_mail(
subject="Сброс пароля",
message='''
Ваш новый пароль (может быть использован после перехода по ссылке) %s,
(в последствии вы сможете сменить его в личном кабинете),
если вы не отправляли заявку на сброс пароля просто проигнорируйте это сообщение,
для подтверждения смены пароля перейдите по %s/api/v1/users/reset/?hash=%s
ссылке (ссылка действительна в течении одного дня)''' % (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,)
# permission_classes = (permissions.IsAuthenticated,)
@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:
acc['b_day'] = None
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() and 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()
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 and not auth.authenticate(email=email, password=password):
return Response("Неверный пароль", status=403)
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)
response = Response(status=204)
response.delete_cookie(api_settings.JWT_AUTH_COOKIE)
return response
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)
@staticmethod
def post(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.lower())
except get_user_model().DoesNotExist:
return Response('user not found', status=404)
user.set_password(password)
user.is_active=True
user.save()
logger.info('''set password: %s to the
student with email: %s''' % (password, user.email))
msg = EmailMessage(
subject='Установлен новый пароль',
body='''Ваш новый пароль %s
(в последствии вы сможете сменить его в личном кабинете).''' % password,
from_email='robo@skillbox.ru',
to=[user.email],
bcc=[request.user.email],
)
msg.send()
return Response(
data={'message': 'Письмо с новым паролем отправлено на email студента.'},
status=201
)