Commit 9bd8c31d05d30e57cdb557c424557af104fcef23

Authored by Andrew Buss
Exists in master

Merge branch 'master' of git.ucsd.edu:110swag/flashy-backend

Showing 2 changed files Inline Diff

flashcards/api.py View file @ 9bd8c31
from django.contrib.auth import login, authenticate 1 1 from django.contrib.auth import login, authenticate
from django.core.mail import send_mail 2 2 from django.core.mail import send_mail
3 from django.contrib.auth import authenticate, login
4 from django.contrib.auth.tokens import default_token_generator
from rest_framework.views import APIView 3 5 from rest_framework.views import APIView
from rest_framework.response import Response 4 6 from rest_framework.response import Response
from rest_framework import status 5 7 from rest_framework import status
from rest_framework.exceptions import ValidationError 6 8 from rest_framework.exceptions import ValidationError, NotFound
from flashcards.serializers import * 7 9 from flashcards.serializers import *
8 10
9 11
class UserDetail(APIView): 10 12 class UserDetail(APIView):
def patch(self, request, format=None): 11 13 def patch(self, request, format=None):
""" 12 14 """
Updates a user's password after they enter a valid old password. 13 15 Updates a user's password after they enter a valid old password.
TODO: email verification 14 16 TODO: email verification
""" 15 17 """
16 18
if 'old_password' not in request.data: 17 19 if 'old_password' not in request.data:
raise ValidationError('Old password is required') 18 20 raise ValidationError('Old password is required')
if 'new_password' not in request.data: 19 21 if 'new_password' not in request.data:
raise ValidationError('New password is required') 20 22 raise ValidationError('New password is required')
if not request.data['new_password']: 21 23 if not request.data['new_password']:
raise ValidationError('Password cannot be blank') 22 24 raise ValidationError('Password cannot be blank')
23 25
currentuser = request.user 24 26 currentuser = request.user
25 27
if not currentuser.check_password(request.data['old_password']): 26 28 if not currentuser.check_password(request.data['old_password']):
raise ValidationError('Invalid old password') 27 29 raise ValidationError('Invalid old password')
28 30
currentuser.set_password(request.data['new_password']) 29 31 currentuser.set_password(request.data['new_password'])
currentuser.save() 30 32 currentuser.save()
31 33
return Response(status=status.HTTP_204_NO_CONTENT) 32 34 return Response(status=status.HTTP_204_NO_CONTENT)
33 35
def get(self, request, format=None): 34 36 def get(self, request, format=None):
serializer = UserSerializer(request.user) 35 37 serializer = UserSerializer(request.user)
return Response(serializer.data) 36 38 return Response(serializer.data)
37 39
def post(self, request, format=None): 38 40 def post(self, request, format=None):
if 'email' not in request.data: 39 41 if 'email' not in request.data:
raise ValidationError('Email is required') 40 42 raise ValidationError('Email is required')
if 'password' not in request.data: 41 43 if 'password' not in request.data:
raise ValidationError('Password is required') 42 44 raise ValidationError('Password is required')
43 45
email = request.data['email'] 44 46 email = request.data['email']
user = User.objects.create_user(email, email=email) 45 47 user = User.objects.create_user(email, email=email)
user.confirm_email(user.confirmation_key) 46 48 user.confirm_email(user.confirmation_key)
body = ''' 47 49 body = '''
Visit the following link to confirm your email address: 48 50 Visit the following link to confirm your email address:
http://flashy.cards/app/verify_email/%s 49 51 http://flashy.cards/app/verify_email/%s
50 52
If you did not register for Flashy, no action is required. 51 53 If you did not register for Flashy, no action is required.
''' 52 54 '''
53 55
send_mail("Please verify your Flashy account", 54 56 send_mail("Please verify your Flashy account",
body % user.confirmation_key, 55 57 body % user.confirmation_key,
"noreply@flashy.cards", 56 58 "noreply@flashy.cards",
[user.email]) 57 59 [user.email])
user = authenticate(username=email, password=request.data['password']) 58 60 user = authenticate(username=email, password=request.data['password'])
print user 59 61 print user
login(request, user) 60 62 login(request, user)
61 63
return Response(UserSerializer(User).data) 62 64 return Response(UserSerializer(User).data)
65
66 def delete(self, request, format=None):
67 request.user.delete()
68 return Response(status=status.HTTP_204_NO_CONTENT)
69
70 class UserLogin(APIView):
71 """
72 Authenticates user and returns user data if valid. Handles invalid
73 users.
74 """
75 def post(self, request, format=None):
76 """
77 Returns user data if valid.
78 """
79 if 'email' not in request.data:
80 raise ValidationError('Email is required')
81 if 'password' not in request.data:
82 raise ValidationError('Password is required')
83
84 email = request.data['email']
85 password = request.data['password']
86 user = authenticate(username=email, password=password)
87
88 if user is not None:
89 if user.is_active:
90 login(request, user)
91 return Response(UserSerializer(User).data)
92 else:
93 raise ValidationError('Account is disabled')
94 else:
95 raise ValidationError('Invalid email or password')
96
97 class PasswordReset(APIView):
98 """
99 Allows user to reset their password.
100 """
101 def post(self, request, format=None):
102 """
103 Send a password reset token/link to the provided email.
104 """
105 if 'email' not in request.data:
106 raise ValidationError('Email is required')
107
108 email = request.data['email']
109
110 # Find the user since they are not logged in.
111 try:
112 user = User.objects.get(email=email)
113 except User.DoesNotExist:
114 raise NotFound('Email does not exist')
115
116 token = default_token_generator.make_token(user)
117
118 body = '''
119 Visit the following link to reset your password:
120 http://flashy.cards/app/reset_password/%d/%s
121
122 If you did not request a password reset, no action is required.
123 '''
124
125 send_mail("Please verify your Flashy account",
126 body % (user.pk, token),
127 "noreply@flashy.cards",
128 [user.email])
129
130 def patch(self, request, format=None):
131 """
132 Updates user's password to new password.
flashy/urls.py View file @ 9bd8c31
from django.conf.urls import include, url 1 1 from django.conf.urls import include, url
from django.contrib import admin 2 2 from django.contrib import admin
from flashcards.views import SectionViewSet, LecturePeriodViewSet 3 3 from flashcards.views import SectionViewSet, LecturePeriodViewSet
from rest_framework.routers import DefaultRouter 4 4 from rest_framework.routers import DefaultRouter
from flashcards.api import * 5 5 from flashcards.api import *
6 6
router = DefaultRouter() 7 7 router = DefaultRouter()
router.register(r'sections', SectionViewSet) 8 8 router.register(r'sections', SectionViewSet)
router.register(r'lectureperiods', LecturePeriodViewSet) 9 9 router.register(r'lectureperiods', LecturePeriodViewSet)
10 10
urlpatterns = [ 11 11 urlpatterns = [
url(r'^api/user/me$', UserDetail.as_view()), 12 12 url(r'^api/users/me$', UserDetail.as_view()),
13 url(r'^api/login$', UserLogin.as_view()),
14 url(r'^api/reset_password$', PasswordReset.as_view()),
url(r'^api/', include(router.urls)), 13 15 url(r'^api/', include(router.urls)),
url(r'^admin/doc/', include('django.contrib.admindocs.urls')), 14 16 url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
url(r'^admin/', include(admin.site.urls)), 15 17 url(r'^admin/', include(admin.site.urls)),
url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')) 16 18 url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework'))
] 17 19 ]