Commit fe546f43f2c7c9a1f7fafbaae9f59147d4506f79

Authored by Andrew Buss
1 parent 7a17fac38e
Exists in master

move verify_email outside user update

Showing 5 changed files with 33 additions and 24 deletions Side-by-side Diff

flashcards/models.py View file @ fe546f4
... ... @@ -143,7 +143,7 @@
143 143 self.save()
144 144  
145 145 def by_retention(self, sections, material_date_begin, material_date_end):
146   - section_pks = map(lambda i: i['pk'], sections.values('pk'))
  146 + section_pks = sections.values_list('pk')
147 147 user_flashcard_filter = UserFlashcard.objects.filter(
148 148 user=self, flashcard__section__pk__in=section_pks,
149 149 flashcard__material_date__gte=material_date_begin,
flashcards/serializers.py View file @ fe546f4
... ... @@ -46,23 +46,18 @@
46 46 except User.DoesNotExist:
47 47 raise serializers.ValidationError('Could not verify reset token')
48 48  
  49 +class EmailVerificationSerializer(Serializer):
  50 + confirmation_key = CharField()
49 51  
50 52 class UserUpdateSerializer(Serializer):
51 53 old_password = CharField(required=False)
52   - new_password = CharField(required=False, allow_blank=False)
53   - confirmation_key = CharField(required=False)
  54 + new_password = CharField(required=False, allow_blank=False)\
54 55 # reset_token = CharField(required=False)
55 56  
56 57 def validate(self, data):
57 58 if 'new_password' in data and 'old_password' not in data:
58 59 raise serializers.ValidationError('old_password is required to set a new_password')
59 60 return data
60   -
61   -
62   -# class Password(Serializer):
63   -# email = EmailField(required=True)
64   -# password = CharField(required=True)
65   -
66 61  
67 62 class LecturePeriodSerializer(ModelSerializer):
68 63 class Meta:
flashcards/tests/test_api.py View file @ fe546f4
... ... @@ -120,13 +120,13 @@
120 120  
121 121 # try activating with an invalid key
122 122  
123   - url = '/api/me/'
124   - response = self.client.patch(url, {'confirmation_key': 'NOT A KEY'})
  123 + url = '/api/verify_email/'
  124 + response = self.client.post(url, {'confirmation_key': 'NOT A KEY'})
125 125 self.assertContains(response, 'confirmation_key is invalid', status_code=400)
126 126  
127 127 # try activating with the valid key
128   - response = self.client.patch(url, {'confirmation_key': user.confirmation_key})
129   - self.assertTrue(response.data['is_confirmed'])
  128 + response = self.client.post(url, {'confirmation_key': user.confirmation_key})
  129 + self.assertContains(response, '', status_code=204)
130 130  
131 131  
132 132 class ProfileViewTest(APITestCase):
flashcards/views.py View file @ fe546f4
... ... @@ -10,7 +10,7 @@
10 10 from flashcards.serializers import SectionSerializer, UserUpdateSerializer, RegistrationSerializer, UserSerializer, \
11 11 PasswordResetSerializer, PasswordResetRequestSerializer, EmailPasswordSerializer, FlashcardSerializer, \
12 12 FlashcardUpdateSerializer, QuizRequestSerializer, QuizResponseSerializer, \
13   - QuizAnswerRequestSerializer, DeepSectionSerializer
  13 + QuizAnswerRequestSerializer, DeepSectionSerializer, EmailVerificationSerializer
14 14 from rest_framework.decorators import detail_route, permission_classes, api_view, list_route
15 15 from rest_framework.generics import ListAPIView, GenericAPIView
16 16 from rest_framework.mixins import CreateModelMixin, RetrieveModelMixin, UpdateModelMixin
... ... @@ -23,6 +23,7 @@
23 23 from rest_framework.response import Response
24 24 from rest_framework.exceptions import AuthenticationFailed, NotAuthenticated, ValidationError, PermissionDenied
25 25 from simple_email_confirmation import EmailAddress
  26 +from simple_email_confirmation.models import EmailAddressManager
26 27  
27 28  
28 29 def log_event(request, event=''):
... ... @@ -144,7 +145,7 @@
144 145  
145 146 def patch(self, request, format=None):
146 147 """
147   - Updates the user's password, or verifies their email address
  148 + Updates the user's password
148 149 ---
149 150 request_serializer: UserUpdateSerializer
150 151 response_serializer: UserSerializer
... ... @@ -160,13 +161,6 @@
160 161 request.user.save()
161 162 log_event(request, 'change password')
162 163  
163   - if 'confirmation_key' in data:
164   - try:
165   - request.user.confirm_email(data['confirmation_key'])
166   - log_event(request, 'confirm email')
167   - except EmailAddress.DoesNotExist:
168   - raise ValidationError('confirmation_key is invalid')
169   -
170 164 return Response(UserSerializer(request.user).data)
171 165  
172 166 def get(self, request, format=None):
173 167  
174 168  
... ... @@ -189,12 +183,31 @@
189 183 return Response(status=HTTP_204_NO_CONTENT)
190 184  
191 185  
192   -
193 186 @api_view(['POST'])
194 187 @permission_classes([IsAuthenticated])
195 188 def resend_confirmation_email(request):
  189 + "Resends a confirmation email to a user"
196 190 request.user.send_confirmation_email()
197 191 return Response(status=HTTP_204_NO_CONTENT)
  192 +
  193 +
  194 +@api_view(['POST'])
  195 +@permission_classes([IsAuthenticated])
  196 +def verify_email(request):
  197 + """
  198 + Accepts a user's email confirmation_key to verify their email address
  199 + ---
  200 + request_serializer: EmailVerificationSerializer
  201 + """
  202 + try:
  203 + data = EmailVerificationSerializer(data=request.data)
  204 + data.is_valid(raise_exception=True)
  205 + email = EmailAddress.objects.confirm(data.validated_data['confirmation_key'])
  206 + log_event(request, 'confirm email' + str(email))
  207 + return Response(status=HTTP_204_NO_CONTENT)
  208 + except EmailAddress.DoesNotExist:
  209 + raise ValidationError('confirmation_key is invalid')
  210 +
198 211  
199 212 @api_view(['POST'])
200 213 def register(request, format=None):
flashy/urls.py View file @ fe546f4
1 1 from django.conf.urls import include, url
2 2 from django.contrib import admin
3 3 from flashcards.views import SectionViewSet, UserDetail, FlashcardViewSet, UserSectionListView, request_password_reset, \
4   - reset_password, logout, login, register, UserFlashcardQuizViewSet, resend_confirmation_email
  4 + reset_password, logout, login, register, UserFlashcardQuizViewSet, resend_confirmation_email, verify_email
5 5 from flashy.frontend_serve import serve_with_default
6 6 from flashy.settings import DEBUG, IN_PRODUCTION
7 7 from rest_framework.routers import DefaultRouter
... ... @@ -20,6 +20,7 @@
20 20 url(r'^api/logout/$', logout),
21 21 url(r'^api/me/sections/', UserSectionListView.as_view()),
22 22 url(r'^api/resend_confirmation_email/', resend_confirmation_email),
  23 + url(r'^api/verify_email/', verify_email),
23 24 url(r'^api/request_password_reset/', request_password_reset),
24 25 url(r'^api/reset_password/', reset_password),
25 26 url(r'^api/', include(router.urls)),