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.
 
 
 
 
 
 

140 lines
5.3 KiB

from datetime import timedelta
import string
import logging
from urllib.parse import urlencode
from django.conf import settings
from django.contrib.auth import get_user_model
from django.db.models import Q
from django.utils.translation import ugettext_lazy as _
from django.shortcuts import get_object_or_404
from django.utils.timezone import now
from django.urls import reverse_lazy
from phonenumber_field.serializerfields import PhoneNumberField
from rest_framework import serializers
from rest_framework.authtoken.views import ObtainAuthToken
from rest_framework.compat import authenticate
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework import status
from rest_framework.authentication import BasicAuthentication
from apps.auth.models import TempToken
from apps.auth.tokens import verification_email_token
from apps.notification.utils import send_email
User = get_user_model()
logger = logging.getLogger(__name__)
class AuthTokenSerializer(serializers.Serializer):
user_id = serializers.IntegerField(required=False)
email = serializers.CharField(label=_("Email"), required=False)
password = serializers.CharField(
label=_("Password"),
style={'input_type': 'password'},
trim_whitespace=False,
required=False,
)
def validate(self, attrs):
user_id = attrs.get('user_id')
email = attrs.get('email')
password = attrs.get('password')
request = self.context.get('request')
if email and password:
user = authenticate(request=request, email=email, password=password)
# The authenticate call simply returns None for is_active=False
# users. (Assuming the default ModelBackend authentication
# backend.)
if not user:
msg = _('Unable to log in with provided credentials.')
raise serializers.ValidationError(msg, code='authorization')
elif user.role != User.ADMIN_ROLE:
msg = _('Only admin have permission to login admin page.')
raise serializers.ValidationError(msg, code='authorization')
elif user_id and request.user.is_authenticated and request.user.role == User.ADMIN_ROLE:
user = get_object_or_404(User, pk=user_id)
else:
msg = _('Must include "email" and "password".')
raise serializers.ValidationError(msg, code='authorization')
attrs['user'] = user
return attrs
class LandingRegistrationSerializer(serializers.Serializer):
phone = PhoneNumberField(required=True)
email = serializers.EmailField(required=True)
first_name = serializers.CharField(required=True)
class ObtainToken(ObtainAuthToken):
serializer_class = AuthTokenSerializer
class ObtainTempToken(APIView):
def get(self, request):
user_id = request.GET.get('user')
if user_id and request.user.is_authenticated and request.user.role == User.ADMIN_ROLE:
user = get_object_or_404(User, pk=user_id)
token, created = TempToken.objects.get_or_create(user=user)
if not created and now() - token.created > timedelta(hours=1):
token.delete()
token = TempToken.objects.create(user=user)
return Response({'temp_token': token.key})
return Response(status=status.HTTP_400_BAD_REQUEST)
class LandingRegistrationView(APIView):
serializer_class = LandingRegistrationSerializer
authentication_classes = (BasicAuthentication,)
def post(self, request, *args, **kwargs):
serializer = self.serializer_class(data=request.data, context={'request': request})
if not serializer.is_valid():
return Response({
'status': 'error',
'errors': serializer.errors,
}, status=400)
email = serializer.validated_data['email']
phone = serializer.validated_data['phone']
if User.objects.filter(Q(email=email) | Q(phone=phone)).count():
return Response({
'status': 'error',
'errors': ['Возможно вы уже зарегистрированы?'],
'user_exists': True,
}, status=400)
user = User(
username=email,
email=email,
phone=phone,
)
name = serializer.validated_data['first_name'].split(' ')
user.first_name = name[0]
if len(name) > 1:
user.last_name = name[1]
password = User.objects.make_random_password(8, string.ascii_lowercase + string.digits)
user.set_password(password)
user.save()
verification_token = verification_email_token.make_token(user)
url = 'https://%s%s?%s' % (settings.MAIN_HOST,
reverse_lazy('lilcity:verification-email', args=[verification_token, user.id]),
urlencode({'next': 'https://lil.school/p/free-lesson'}))
try:
send_email('Регистрация в Lil School', email, "notification/email/landing_registration.html", url=url,
user=user, password=password)
except Exception as e:
logger.error(str(e))
return Response({
'status': 'ok',
'url': url,
})