Commit 33f8a47a8b87874c0ce2e7080fdb43079d2e147b
1 parent
f0ac627bcd
Exists in
master
enforce 24 hour grace period on email verification
Showing 2 changed files with 23 additions and 7 deletions Side-by-side Diff
flashcards/api.py
View file @
33f8a47
1 | +from django.utils.timezone import now | |
1 | 2 | from flashcards.models import Flashcard, UserFlashcardQuiz |
3 | +from rest_framework.exceptions import PermissionDenied | |
2 | 4 | from rest_framework.pagination import PageNumberPagination |
3 | 5 | from rest_framework.permissions import BasePermission |
4 | 6 | |
7 | +mock_no_params = lambda x: None | |
5 | 8 | |
6 | -mock_no_params = lambda x:None | |
7 | 9 | |
8 | 10 | class StandardResultsSetPagination(PageNumberPagination): |
9 | 11 | page_size = 40 |
... | ... | @@ -36,4 +38,17 @@ |
36 | 38 | return True |
37 | 39 | assert type(obj) is UserFlashcardQuiz |
38 | 40 | return request.user == obj.user_flashcard.user |
41 | + | |
42 | + | |
43 | +class IsAuthenticatedAndConfirmed(BasePermission): | |
44 | + """ | |
45 | + Allows access only to authenticated users who have verified their email address, with a 24 hour grace period | |
46 | + """ | |
47 | + | |
48 | + def has_permission(self, request, view): | |
49 | + if not (request.user and request.user.is_authenticated()): return False | |
50 | + if request.user.confirmed_email: return True | |
51 | + if (now() - request.user.date_joined).days > 0: | |
52 | + raise PermissionDenied('Please verify your email before continuing') | |
53 | + return True |
flashcards/views.py
View file @
33f8a47
... | ... | @@ -2,7 +2,8 @@ |
2 | 2 | from django.contrib import auth |
3 | 3 | from django.db import IntegrityError |
4 | 4 | from django.shortcuts import get_object_or_404 |
5 | -from flashcards.api import StandardResultsSetPagination, IsEnrolledInAssociatedSection, IsFlashcardReviewer | |
5 | +from flashcards.api import StandardResultsSetPagination, IsEnrolledInAssociatedSection, IsFlashcardReviewer, \ | |
6 | + IsAuthenticatedAndConfirmed | |
6 | 7 | from flashcards.models import Section, User, Flashcard, FlashcardHide, UserFlashcard, UserFlashcardQuiz |
7 | 8 | from flashcards.notifications import notify_new_card |
8 | 9 | from flashcards.serializers import SectionSerializer, UserUpdateSerializer, RegistrationSerializer, UserSerializer, \ |
... | ... | @@ -27,7 +28,7 @@ |
27 | 28 | queryset = Section.objects.all() |
28 | 29 | serializer_class = DeepSectionSerializer |
29 | 30 | pagination_class = StandardResultsSetPagination |
30 | - permission_classes = [IsAuthenticated] | |
31 | + permission_classes = [IsAuthenticatedAndConfirmed] | |
31 | 32 | |
32 | 33 | @detail_route(methods=['GET']) |
33 | 34 | def flashcards(self, request, pk): |
... | ... | @@ -116,7 +117,7 @@ |
116 | 117 | |
117 | 118 | class UserSectionListView(ListAPIView): |
118 | 119 | serializer_class = DeepSectionSerializer |
119 | - permission_classes = [IsAuthenticated] | |
120 | + permission_classes = [IsAuthenticatedAndConfirmed] | |
120 | 121 | |
121 | 122 | def get_queryset(self): |
122 | 123 | return self.request.user.sections.all() |
... | ... | @@ -126,7 +127,7 @@ |
126 | 127 | |
127 | 128 | class UserDetail(GenericAPIView): |
128 | 129 | serializer_class = UserSerializer |
129 | - permission_classes = [IsAuthenticated] | |
130 | + permission_classes = [IsAuthenticatedAndConfirmed] | |
130 | 131 | |
131 | 132 | def patch(self, request, format=None): |
132 | 133 | """ |
... | ... | @@ -258,7 +259,7 @@ |
258 | 259 | class FlashcardViewSet(GenericViewSet, CreateModelMixin, RetrieveModelMixin): |
259 | 260 | queryset = Flashcard.objects.all() |
260 | 261 | serializer_class = FlashcardSerializer |
261 | - permission_classes = [IsAuthenticated, IsEnrolledInAssociatedSection] | |
262 | + permission_classes = [IsAuthenticatedAndConfirmed, IsEnrolledInAssociatedSection] | |
262 | 263 | # Override create in CreateModelMixin |
263 | 264 | def create(self, request, *args, **kwargs): |
264 | 265 | serializer = FlashcardSerializer(data=request.data) |
... | ... | @@ -340,7 +341,7 @@ |
340 | 341 | |
341 | 342 | |
342 | 343 | class UserFlashcardQuizViewSet(GenericViewSet, CreateModelMixin, UpdateModelMixin): |
343 | - permission_classes = [IsAuthenticated, IsFlashcardReviewer] | |
344 | + permission_classes = [IsAuthenticatedAndConfirmed, IsFlashcardReviewer] | |
344 | 345 | queryset = UserFlashcardQuiz.objects.all() |
345 | 346 | |
346 | 347 | def get_serializer_class(self): |