api.py 4.81 KB
from django.core.mail import send_mail
from django.contrib.auth import authenticate, login
from django.contrib.auth.tokens import default_token_generator
from rest_framework.status import HTTP_201_CREATED, HTTP_204_NO_CONTENT
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from rest_framework.exceptions import ValidationError, NotFound
from flashcards.serializers import *
class UserDetail(APIView):
def patch(self, request, format=None):
"""
This method checks either the email or the password passed in
is valid. If confirmation key is correct, it validates the
user. It updates the password if the new password
is valid.
"""
currentuser = request.user
if 'confirmation_key' in request.data:
if not currentuser.confirm_email( request.data['confirmation_key'] ):
raise ValidationError('confirmation_key is invalid')
if 'new_password' in request.data:
if not currentuser.check_password(request.data['old_password']):
raise ValidationError('Invalid old password')
if not request.data['new_password']:
raise ValidationError('Password cannot be blank')
currentuser.set_password(request.data['new_password'])
currentuser.save()
return Response(status=status.HTTP_204_NO_CONTENT)
def get(self, request, format=None):
serializer = UserSerializer(request.user)
return Response(serializer.data)
def post(self, request, format=None):
if 'email' not in request.data:
raise ValidationError('Email is required')
if 'password' not in request.data:
raise ValidationError('Password is required')
email = request.data['email']
user = User.objects.create_user(email, email=email, password=request.data['password'])
body = '''
Visit the following link to confirm your email address:
http://flashy.cards/app/verify_email/%s
If you did not register for Flashy, no action is required.
'''
user = authenticate(email=email, password=request.data['password'])
login(request, user)
return Response(UserSerializer(user).data, status=HTTP_201_CREATED)
def delete(self, request, format=None):
request.user.delete()
return Response(status=HTTP_204_NO_CONTENT)
class UserLogin(APIView):
"""
Authenticates user and returns user data if valid. Handles invalid
users.
"""
def post(self, request, format=None):
"""
Returns user data if valid.
"""
if 'email' not in request.data:
raise ValidationError('Email is required')
if 'password' not in request.data:
raise ValidationError('Password is required')
email = request.data['email']
password = request.data['password']
user = authenticate(email=email, password=password)
if user is None:
raise ValidationError('Invalid email or password')
if not user.is_active:
raise ValidationError('Account is disabled')
login(request, user)
return Response(UserSerializer(user).data)
class PasswordReset(APIView):
"""
Allows user to reset their password.
"""
def post(self, request, format=None):
"""
Send a password reset token/link to the provided email.
"""
if 'email' not in request.data:
raise ValidationError('Email is required')
email = request.data['email']
# Find the user since they are not logged in.
try:
user = User.objects.get(email=email)
except User.DoesNotExist:
raise NotFound('Email does not exist')
token = default_token_generator.make_token(user)
body = '''
Visit the following link to reset your password:
http://flashy.cards/app/reset_password/%d/%s
If you did not request a password reset, no action is required.
'''
send_mail("Flashy password reset",
body % (user.pk, token),
"noreply@flashy.cards",
[user.email])
return Response(status=status.HTTP_204_NO_CONTENT)
def patch(self, request, format=None):
"""
Updates user's password to new password.
"""
if 'new_password' not in request.data:
raise ValidationError('New password is required')
if not request.data['new_password']:
raise ValidationError('Password cannot be blank')
user = request.user
user.set_password(request.data['new_password'])
user.save()
return Response(status=status.HTTP_204_NO_CONTENT)