Skip to content

Commit

Permalink
Views: more typehinting, try/catch in get_client_obj, other improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
eshaan7 committed May 19, 2021
1 parent 4778df2 commit 9583414
Showing 1 changed file with 28 additions and 15 deletions.
43 changes: 28 additions & 15 deletions durin/views.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
from datetime import datetime

from django.contrib.auth.signals import user_logged_in, user_logged_out
from django.core.exceptions import ObjectDoesNotExist
from rest_framework import status
from rest_framework.authtoken.serializers import AuthTokenSerializer
from rest_framework.exceptions import ParseError
from rest_framework.exceptions import ValidationError
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.serializers import DateTimeField
Expand All @@ -16,7 +17,7 @@
class LoginView(APIView):
"""Durin's Login View.\n
This view will return a JSON response when valid ``username``, ``password`` and
if not overwritten ``client`` fields are POSTed to the view using
(if not overwritten) ``client`` fields are POSTed to the view using
form data or JSON.
It uses the default serializer provided by
Expand All @@ -42,27 +43,32 @@ def validate_and_return_user(request):
serializer.is_valid(raise_exception=True)
return serializer.validated_data["user"]

@staticmethod
def get_client_obj(request) -> "Client":
def get_client_obj(self, request) -> "Client":
"""
To get and return the associated :class:`durin.models.Client` object.
:raises rest_framework.exceptions.ValidationError
"""
client_name = request.data.get("client", None)
if not client_name:
raise ParseError("No client specified.", status.HTTP_400_BAD_REQUEST)
return Client.objects.get(name=client_name)
raise ValidationError({"detail": "No client specified."})

@classmethod
def get_token_obj(cls, request, client: "Client") -> "AuthToken":
try:
return Client.objects.get(name=client_name)
except Client.DoesNotExist:
raise ValidationError({"detail": "No client with that name."})

def get_token_obj(self, request, client: "Client") -> "AuthToken":
"""
Flow used to return the :class:`durin.models.AuthToken` object.
"""
try:
# a token for this user and client already exists, so we can just return it
# if a token for this user-client pair already exists,
# we can just return it
token = AuthToken.objects.get(user=request.user, client=client)
if durin_settings.REFRESH_TOKEN_ON_LOGIN:
cls.renew_token(token)
except ObjectDoesNotExist:
self.renew_token(token)
except AuthToken.DoesNotExist:
# create new token
token = AuthToken.objects.create(request.user, client)

Expand All @@ -77,7 +83,7 @@ def renew_token(cls, token_obj: "AuthToken") -> None:
token_obj.renew_token(renewed_by=cls)

@staticmethod
def format_expiry_datetime(expiry):
def format_expiry_datetime(expiry: "datetime") -> str:
"""
To format the expiry ``datetime`` object at your convenience.
"""
Expand Down Expand Up @@ -131,16 +137,23 @@ class RefreshView(APIView):
permission_classes = (IsAuthenticated,)

@staticmethod
def format_expiry_datetime(expiry):
def format_expiry_datetime(expiry: "datetime") -> str:
"""
To format the expiry ``datetime`` object at your convenience.
"""
datetime_format = durin_settings.EXPIRY_DATETIME_FORMAT
return DateTimeField(format=datetime_format).to_representation(expiry)

def renew_token(self, token_obj: "AuthToken") -> "datetime":
"""
How to renew the token instance.
"""
new_expiry = token_obj.renew_token(renewed_by=self.__class__)
return new_expiry

def post(self, request, *args, **kwargs):
auth_token = request._auth
new_expiry = auth_token.renew_token(renewed_by=self.__class__)
new_expiry = self.renew_token(auth_token)
new_expiry_repr = self.format_expiry_datetime(new_expiry)
return Response({"expiry": new_expiry_repr}, status=status.HTTP_200_OK)

Expand Down

0 comments on commit 9583414

Please sign in to comment.