Commit 25cc754dea73a51d30ff6415dde4f47500d8c298
1 parent
15af7095ef
Exists in
master
api/reset_password post and patch added, not done
Showing 2 changed files with 55 additions and 1 deletions Side-by-side Diff
flashcards/api.py
View file @
25cc754
1 | 1 | from django.core.mail import send_mail |
2 | 2 | from django.contrib.auth import authenticate, login |
3 | +from django.contrib.auth.tokens import default_token_generator | |
3 | 4 | from rest_framework.views import APIView |
4 | 5 | from rest_framework.response import Response |
5 | 6 | from rest_framework import status |
6 | -from rest_framework.exceptions import ValidationError | |
7 | +from rest_framework.exceptions import ValidationError, NotFound | |
7 | 8 | from flashcards.serializers import * |
8 | 9 | |
9 | 10 | |
... | ... | @@ -68,6 +69,9 @@ |
68 | 69 | users. |
69 | 70 | """ |
70 | 71 | def post(self, request, format=None): |
72 | + """ | |
73 | + Returns user data if valid. | |
74 | + """ | |
71 | 75 | if 'email' not in request.data: |
72 | 76 | raise ValidationError('Email is required') |
73 | 77 | if 'password' not in request.data: |
... | ... | @@ -85,4 +89,53 @@ |
85 | 89 | raise ValidationError('Account is disabled') |
86 | 90 | else: |
87 | 91 | raise ValidationError('Invalid email or password') |
92 | + | |
93 | +class PasswordReset(APIView): | |
94 | + """ | |
95 | + Allows user to reset their password. | |
96 | + """ | |
97 | + def post(self, request, format=None): | |
98 | + """ | |
99 | + Send a password reset token/link to the provided email. | |
100 | + """ | |
101 | + if 'email' not in request.data: | |
102 | + raise ValidationError('Email is required') | |
103 | + | |
104 | + email = request.data['email'] | |
105 | + | |
106 | + # Find the user since they are not logged in. | |
107 | + try: | |
108 | + user = User.objects.get(email=email) | |
109 | + except User.DoesNotExist: | |
110 | + raise NotFound('Email does not exist') | |
111 | + | |
112 | + token = default_token_generator.make_token(user) | |
113 | + | |
114 | + body = ''' | |
115 | + Visit the following link to reset your password: | |
116 | + http://flashy.cards/app/reset_password/%d/%s | |
117 | + | |
118 | + If you did not request a password reset, no action is required. | |
119 | + ''' | |
120 | + | |
121 | + send_mail("Please verify your Flashy account", | |
122 | + body % (user.pk, token), | |
123 | + "noreply@flashy.cards", | |
124 | + [user.email]) | |
125 | + | |
126 | + def patch(self, request, format=None): | |
127 | + """ | |
128 | + Updates user's password to new password. | |
129 | + """ | |
130 | + if 'new_password' not in request.data: | |
131 | + raise ValidationError('New password is required') | |
132 | + if not request.data['new_password']: | |
133 | + raise ValidationError('Password cannot be blank') | |
134 | + | |
135 | + user = request.user | |
136 | + | |
137 | + user.set_password(request.data['new_password']) | |
138 | + user.save() | |
139 | + | |
140 | + return Response(status=status.HTTP_204_NO_CONTENT) |
flashy/urls.py
View file @
25cc754
... | ... | @@ -11,6 +11,7 @@ |
11 | 11 | urlpatterns = [ |
12 | 12 | url(r'^api/users/me$', UserDetail.as_view()), |
13 | 13 | url(r'^api/login$', UserLogin.as_view()), |
14 | + url(r'^api/reset_password$', PasswordReset.as_view()), | |
14 | 15 | url(r'^api/', include(router.urls)), |
15 | 16 | url(r'^admin/doc/', include('django.contrib.admindocs.urls')), |
16 | 17 | url(r'^admin/', include(admin.site.urls)), |