Commit 016071a302a78b81283b66364f591865a5238418

Authored by Andrew Buss
1 parent 43fe5932bf
Exists in master

Removed redundant flashcard get view

Showing 1 changed file with 0 additions and 10 deletions Inline Diff

flashcards/views.py View file @ 016071a
from django.contrib import auth 1 1 from django.contrib import auth
from django.db.models import Q 2 2 from django.db.models import Q
from flashcards.api import StandardResultsSetPagination 3 3 from flashcards.api import StandardResultsSetPagination
from flashcards.models import Section, User, Flashcard, FlashcardReport 4 4 from flashcards.models import Section, User, Flashcard, FlashcardReport
from flashcards.serializers import SectionSerializer, UserUpdateSerializer, RegistrationSerializer, UserSerializer, \ 5 5 from flashcards.serializers import SectionSerializer, UserUpdateSerializer, RegistrationSerializer, UserSerializer, \
PasswordResetSerializer, PasswordResetRequestSerializer, EmailPasswordSerializer, FlashcardSerializer 6 6 PasswordResetSerializer, PasswordResetRequestSerializer, EmailPasswordSerializer, FlashcardSerializer
from rest_framework.decorators import detail_route, permission_classes, api_view, list_route 7 7 from rest_framework.decorators import detail_route, permission_classes, api_view, list_route
from rest_framework.generics import ListAPIView, GenericAPIView 8 8 from rest_framework.generics import ListAPIView, GenericAPIView
from rest_framework.mixins import CreateModelMixin, RetrieveModelMixin 9 9 from rest_framework.mixins import CreateModelMixin, RetrieveModelMixin
from rest_framework.permissions import IsAuthenticated 10 10 from rest_framework.permissions import IsAuthenticated
from rest_framework.viewsets import ReadOnlyModelViewSet, GenericViewSet 11 11 from rest_framework.viewsets import ReadOnlyModelViewSet, GenericViewSet
from django.core.mail import send_mail 12 12 from django.core.mail import send_mail
from django.contrib.auth import authenticate 13 13 from django.contrib.auth import authenticate
from django.contrib.auth.tokens import default_token_generator 14 14 from django.contrib.auth.tokens import default_token_generator
from rest_framework.status import HTTP_204_NO_CONTENT, HTTP_201_CREATED 15 15 from rest_framework.status import HTTP_204_NO_CONTENT, HTTP_201_CREATED
from rest_framework.response import Response 16 16 from rest_framework.response import Response
from rest_framework.exceptions import AuthenticationFailed, NotAuthenticated, ValidationError, PermissionDenied 17 17 from rest_framework.exceptions import AuthenticationFailed, NotAuthenticated, ValidationError, PermissionDenied
from simple_email_confirmation import EmailAddress 18 18 from simple_email_confirmation import EmailAddress
19 19
20 20
class SectionViewSet(ReadOnlyModelViewSet): 21 21 class SectionViewSet(ReadOnlyModelViewSet):
queryset = Section.objects.all() 22 22 queryset = Section.objects.all()
serializer_class = SectionSerializer 23 23 serializer_class = SectionSerializer
pagination_class = StandardResultsSetPagination 24 24 pagination_class = StandardResultsSetPagination
permission_classes = [IsAuthenticated] 25 25 permission_classes = [IsAuthenticated]
26 26
@detail_route(methods=['post'], permission_classes=[IsAuthenticated]) 27 27 @detail_route(methods=['post'], permission_classes=[IsAuthenticated])
def enroll(self, request, pk): 28 28 def enroll(self, request, pk):
""" 29 29 """
Add the current user to a specified section 30 30 Add the current user to a specified section
If the class has a whitelist, but the user is not on the whitelist, the request will fail. 31 31 If the class has a whitelist, but the user is not on the whitelist, the request will fail.
--- 32 32 ---
omit_serializer: true 33 33 omit_serializer: true
parameters: 34 34 parameters:
- fake: None 35 35 - fake: None
parameters_strategy: 36 36 parameters_strategy:
form: replace 37 37 form: replace
""" 38 38 """
section = self.get_object() 39 39 section = self.get_object()
if request.user.sections.filter(pk=section.pk).exists(): 40 40 if request.user.sections.filter(pk=section.pk).exists():
raise ValidationError("You are already in this section.") 41 41 raise ValidationError("You are already in this section.")
if section.is_whitelisted() and not section.is_user_on_whitelist(request.user): 42 42 if section.is_whitelisted() and not section.is_user_on_whitelist(request.user):
raise PermissionDenied("You must be on the whitelist to add this section.") 43 43 raise PermissionDenied("You must be on the whitelist to add this section.")
request.user.sections.add(section) 44 44 request.user.sections.add(section)
return Response(status=HTTP_204_NO_CONTENT) 45 45 return Response(status=HTTP_204_NO_CONTENT)
46 46
@detail_route(methods=['post'], permission_classes=[IsAuthenticated]) 47 47 @detail_route(methods=['post'], permission_classes=[IsAuthenticated])
def drop(self, request, pk): 48 48 def drop(self, request, pk):
""" 49 49 """
Remove the current user from a specified section 50 50 Remove the current user from a specified section
If the user is not in the class, the request will fail. 51 51 If the user is not in the class, the request will fail.
--- 52 52 ---
omit_serializer: true 53 53 omit_serializer: true
parameters: 54 54 parameters:
- fake: None 55 55 - fake: None
parameters_strategy: 56 56 parameters_strategy:
form: replace 57 57 form: replace
""" 58 58 """
section = self.get_object() 59 59 section = self.get_object()
if not section.user_set.filter(pk=request.user.pk).exists(): 60 60 if not section.user_set.filter(pk=request.user.pk).exists():
raise ValidationError("You are not in the section.") 61 61 raise ValidationError("You are not in the section.")
section.user_set.remove(request.user) 62 62 section.user_set.remove(request.user)
return Response(status=HTTP_204_NO_CONTENT) 63 63 return Response(status=HTTP_204_NO_CONTENT)
64 64
@list_route(methods=['get'], permission_classes=[IsAuthenticated]) 65 65 @list_route(methods=['get'], permission_classes=[IsAuthenticated])
def search(self, request): 66 66 def search(self, request):
query = request.GET.get('q', '').split(' ') 67 67 query = request.GET.get('q', '').split(' ')
q = Q() 68 68 q = Q()
for word in query: 69 69 for word in query:
q |= Q(course_title__icontains=word) 70 70 q |= Q(course_title__icontains=word)
qs = Section.objects.filter(q).distinct() 71 71 qs = Section.objects.filter(q).distinct()
serializer = SectionSerializer(qs, many=True) 72 72 serializer = SectionSerializer(qs, many=True)
return Response(serializer.data) 73 73 return Response(serializer.data)
74 74
75 75
class UserSectionListView(ListAPIView): 76 76 class UserSectionListView(ListAPIView):
serializer_class = SectionSerializer 77 77 serializer_class = SectionSerializer
permission_classes = [IsAuthenticated] 78 78 permission_classes = [IsAuthenticated]
79 79
def get_queryset(self): 80 80 def get_queryset(self):
return self.request.user.sections.all() 81 81 return self.request.user.sections.all()
82 82
def paginate_queryset(self, queryset): return None 83 83 def paginate_queryset(self, queryset): return None
84 84
85 85
class UserDetail(GenericAPIView): 86 86 class UserDetail(GenericAPIView):
serializer_class = UserSerializer 87 87 serializer_class = UserSerializer
permission_classes = [IsAuthenticated] 88 88 permission_classes = [IsAuthenticated]
89 89
def get_queryset(self): 90 90 def get_queryset(self):
return User.objects.all() 91 91 return User.objects.all()
92 92
def patch(self, request, format=None): 93 93 def patch(self, request, format=None):
""" 94 94 """
Updates the user's password, or verifies their email address 95 95 Updates the user's password, or verifies their email address
--- 96 96 ---
request_serializer: UserUpdateSerializer 97 97 request_serializer: UserUpdateSerializer
response_serializer: UserSerializer 98 98 response_serializer: UserSerializer
""" 99 99 """
data = UserUpdateSerializer(data=request.data, context={'user': request.user}) 100 100 data = UserUpdateSerializer(data=request.data, context={'user': request.user})
data.is_valid(raise_exception=True) 101 101 data.is_valid(raise_exception=True)
data = data.validated_data 102 102 data = data.validated_data
103 103
if 'new_password' in data: 104 104 if 'new_password' in data:
if not request.user.check_password(data['old_password']): 105 105 if not request.user.check_password(data['old_password']):
raise ValidationError('old_password is incorrect') 106 106 raise ValidationError('old_password is incorrect')
request.user.set_password(data['new_password']) 107 107 request.user.set_password(data['new_password'])
request.user.save() 108 108 request.user.save()
109 109
if 'confirmation_key' in data: 110 110 if 'confirmation_key' in data:
try: 111 111 try:
request.user.confirm_email(data['confirmation_key']) 112 112 request.user.confirm_email(data['confirmation_key'])
except EmailAddress.DoesNotExist: 113 113 except EmailAddress.DoesNotExist:
raise ValidationError('confirmation_key is invalid') 114 114 raise ValidationError('confirmation_key is invalid')
115 115
return Response(UserSerializer(request.user).data) 116 116 return Response(UserSerializer(request.user).data)
117 117
def get(self, request, format=None): 118 118 def get(self, request, format=None):
""" 119 119 """
Return data about the user 120 120 Return data about the user
--- 121 121 ---
response_serializer: UserSerializer 122 122 response_serializer: UserSerializer
""" 123 123 """
serializer = UserSerializer(request.user, context={'request': request}) 124 124 serializer = UserSerializer(request.user, context={'request': request})
return Response(serializer.data) 125 125 return Response(serializer.data)
126 126
def delete(self, request): 127 127 def delete(self, request):
""" 128 128 """
Irrevocably delete the user and their data 129 129 Irrevocably delete the user and their data
130 130
Yes, really 131 131 Yes, really
""" 132 132 """
request.user.delete() 133 133 request.user.delete()
return Response(status=HTTP_204_NO_CONTENT) 134 134 return Response(status=HTTP_204_NO_CONTENT)
135 135
136 136
@api_view(['POST']) 137 137 @api_view(['POST'])
def register(request, format=None): 138 138 def register(request, format=None):
""" 139 139 """
Register a new user 140 140 Register a new user
--- 141 141 ---
request_serializer: EmailPasswordSerializer 142 142 request_serializer: EmailPasswordSerializer
response_serializer: UserSerializer 143 143 response_serializer: UserSerializer
""" 144 144 """
data = RegistrationSerializer(data=request.data) 145 145 data = RegistrationSerializer(data=request.data)
data.is_valid(raise_exception=True) 146 146 data.is_valid(raise_exception=True)
147 147
User.objects.create_user(**data.validated_data) 148 148 User.objects.create_user(**data.validated_data)
user = authenticate(**data.validated_data) 149 149 user = authenticate(**data.validated_data)
auth.login(request, user) 150 150 auth.login(request, user)
151 151
body = ''' 152 152 body = '''
Visit the following link to confirm your email address: 153 153 Visit the following link to confirm your email address:
https://flashy.cards/app/verify_email/%s 154 154 https://flashy.cards/app/verify_email/%s
155 155
If you did not register for Flashy, no action is required. 156 156 If you did not register for Flashy, no action is required.
''' 157 157 '''
158 158
assert send_mail("Flashy email verification", 159 159 assert send_mail("Flashy email verification",
body % user.confirmation_key, 160 160 body % user.confirmation_key,
"noreply@flashy.cards", 161 161 "noreply@flashy.cards",
[user.email]) 162 162 [user.email])
163 163
return Response(UserSerializer(request.user).data, status=HTTP_201_CREATED) 164 164 return Response(UserSerializer(request.user).data, status=HTTP_201_CREATED)
165 165
166 166
@api_view(['POST']) 167 167 @api_view(['POST'])
def login(request): 168 168 def login(request):
""" 169 169 """
Authenticates user and returns user data if valid. 170 170 Authenticates user and returns user data if valid.
--- 171 171 ---
request_serializer: EmailPasswordSerializer 172 172 request_serializer: EmailPasswordSerializer
response_serializer: UserSerializer 173 173 response_serializer: UserSerializer
""" 174 174 """
175 175
data = EmailPasswordSerializer(data=request.data) 176 176 data = EmailPasswordSerializer(data=request.data)
data.is_valid(raise_exception=True) 177 177 data.is_valid(raise_exception=True)
user = authenticate(**data.validated_data) 178 178 user = authenticate(**data.validated_data)
179 179
if user is None: 180 180 if user is None:
raise AuthenticationFailed('Invalid email or password') 181 181 raise AuthenticationFailed('Invalid email or password')
if not user.is_active: 182 182 if not user.is_active:
raise NotAuthenticated('Account is disabled') 183 183 raise NotAuthenticated('Account is disabled')
auth.login(request, user) 184 184 auth.login(request, user)
return Response(UserSerializer(request.user).data) 185 185 return Response(UserSerializer(request.user).data)
186 186
187 187
@api_view(['POST']) 188 188 @api_view(['POST'])
@permission_classes((IsAuthenticated, )) 189 189 @permission_classes((IsAuthenticated, ))
def logout(request, format=None): 190 190 def logout(request, format=None):
""" 191 191 """
Logs the authenticated user out. 192 192 Logs the authenticated user out.
""" 193 193 """
auth.logout(request) 194 194 auth.logout(request)
return Response(status=HTTP_204_NO_CONTENT) 195 195 return Response(status=HTTP_204_NO_CONTENT)
196 196
197 197
@api_view(['POST']) 198 198 @api_view(['POST'])
def request_password_reset(request, format=None): 199 199 def request_password_reset(request, format=None):
""" 200 200 """
Send a password reset token/link to the provided email. 201 201 Send a password reset token/link to the provided email.
--- 202 202 ---
request_serializer: PasswordResetRequestSerializer 203 203 request_serializer: PasswordResetRequestSerializer
""" 204 204 """
data = PasswordResetRequestSerializer(data=request.data) 205 205 data = PasswordResetRequestSerializer(data=request.data)
data.is_valid(raise_exception=True) 206 206 data.is_valid(raise_exception=True)
user = User.objects.get(email=data['email'].value) 207 207 user = User.objects.get(email=data['email'].value)
token = default_token_generator.make_token(user) 208 208 token = default_token_generator.make_token(user)
209 209
body = ''' 210 210 body = '''
Visit the following link to reset your password: 211 211 Visit the following link to reset your password:
https://flashy.cards/app/reset_password/%d/%s 212 212 https://flashy.cards/app/reset_password/%d/%s
213 213
If you did not request a password reset, no action is required. 214 214 If you did not request a password reset, no action is required.
''' 215 215 '''
216 216
send_mail("Flashy password reset", 217 217 send_mail("Flashy password reset",
body % (user.pk, token), 218 218 body % (user.pk, token),
"noreply@flashy.cards", 219 219 "noreply@flashy.cards",
[user.email]) 220 220 [user.email])
221 221
return Response(status=HTTP_204_NO_CONTENT) 222 222 return Response(status=HTTP_204_NO_CONTENT)
223 223
224 224
@api_view(['POST']) 225 225 @api_view(['POST'])
def reset_password(request, format=None): 226 226 def reset_password(request, format=None):
""" 227 227 """
Updates user's password to new password if token is valid. 228 228 Updates user's password to new password if token is valid.
--- 229 229 ---