Skip to content

Commit

Permalink
Merge 9d13ab6 into b56cb36
Browse files Browse the repository at this point in the history
  • Loading branch information
engjames committed Apr 25, 2019
2 parents b56cb36 + 9d13ab6 commit e4286cb
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 20 deletions.
49 changes: 40 additions & 9 deletions authors/apps/authentication/backends.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,41 @@
# import jwt
#
# from django.conf import settings
#
# from rest_framework import authentication, exceptions
#
# from .models import User

"""Configure JWT Here"""
from django.conf import settings
from rest_framework import authentication, exceptions
from authors.apps.authentication.models import User
from rest_framework.response import Response
from rest_framework import status
import jwt


class JWTAuthentication(authentication.BaseAuthentication):
"""Authenticate requests by using tokens."""
authentication_header_prefix = "Bearer"

def authenticate(self, request):
"""Check for authorization header."""
try:
request.user = None
header = authentication.get_authorization_header(request).split()
token = header[1]
if header[0] != self.authentication_header_prefix:
message = "Bearer prefix missing in Authorization header"
return Response(message, status=status.HTTP_401_UNAUTHORIZED)
return self.authenticate_credentials(request, token)
except Exception as e:
raise exceptions.AuthenticationFailed(e)

def authenticate_credentials(self, request, token):
"""Identify a user using the token provided"""
try:
payload = jwt.decode(token, settings.SECRET_KEY, 'utf-8')
except BaseException:
message = "The token provided can not be decoded."
raise exceptions.AuthenticationFailed(message)
user = User.objects.get(username=payload['sub']['username'])
if not user:
message = "User does not exist in the database."
raise exceptions.AuthenticationFailed(message)
if not user.is_active:
message = "User is not activated."
raise exceptions.AuthenticationFailed(message)
return (user, token)

22 changes: 18 additions & 4 deletions authors/apps/authentication/models.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import jwt

from datetime import datetime, timedelta
import datetime
# from datetime import datetime, timedelta

from django.conf import settings
from django.contrib.auth.models import (
Expand All @@ -12,7 +12,7 @@ class UserManager(BaseUserManager):
"""
Django requires that custom users define their own Manager class. By
inheriting from `BaseUserManager`, we get a lot of the same code used by
Django to create a `User` for free.
Django to create a `User` for free.
All we have to do is override the `create_user` function which we will use
to create `User` objects.
Expand Down Expand Up @@ -117,4 +117,18 @@ def get_short_name(self):
"""
return self.username


@staticmethod
def encode_auth_token(username):
"""Generates auth token."""
try:
payload = {
'exp': datetime.datetime.utcnow() + datetime.timedelta(
days=2, seconds=20000),
'iat': datetime.datetime.utcnow(),
'sub': username
}
return jwt.encode(
payload, settings.SECRET_KEY, algorithm='HS256'
)
except Exception as e:
return e
1 change: 0 additions & 1 deletion authors/apps/authentication/urls.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from django.urls import path

from .views import (
LoginAPIView, RegistrationAPIView, UserRetrieveUpdateAPIView
)
Expand Down
26 changes: 20 additions & 6 deletions authors/apps/authentication/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from rest_framework.permissions import AllowAny, IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIView

from authors.apps.authentication.models import User
from .renderers import UserJSONRenderer
from .serializers import (
LoginSerializer, RegistrationSerializer, UserSerializer
Expand All @@ -13,6 +13,7 @@
class RegistrationAPIView(APIView):
# Allow any user (authenticated or not) to hit this endpoint.
permission_classes = (AllowAny,)
authentication_classes = ()
renderer_classes = (UserJSONRenderer,)
serializer_class = RegistrationSerializer

Expand All @@ -25,12 +26,18 @@ def post(self, request):
serializer = self.serializer_class(data=user)
serializer.is_valid(raise_exception=True)
serializer.save()

return Response(serializer.data, status=status.HTTP_201_CREATED)
token = User.encode_auth_token(user).decode('utf-8')
response_data = {
'data': serializer.data,
'token': token
}
return Response(response_data,
status=status.HTTP_201_CREATED)


class LoginAPIView(APIView):
permission_classes = (AllowAny,)
authentication_classes = ()
renderer_classes = (UserJSONRenderer,)
serializer_class = LoginSerializer

Expand All @@ -43,8 +50,16 @@ def post(self, request):
# handles everything we need.
serializer = self.serializer_class(data=user)
serializer.is_valid(raise_exception=True)

return Response(serializer.data, status=status.HTTP_200_OK)
token = User.encode_auth_token(user).decode('utf-8')
user = User()
response_data = {
'username': user.get_full_name,
'token': token
}
response_data.update(serializer.data)
return Response(
response_data, status=status.HTTP_200_OK
)


class UserRetrieveUpdateAPIView(RetrieveUpdateAPIView):
Expand Down Expand Up @@ -72,4 +87,3 @@ def update(self, request, *args, **kwargs):
serializer.save()

return Response(serializer.data, status=status.HTTP_200_OK)

4 changes: 4 additions & 0 deletions authors/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,4 +140,8 @@
REST_FRAMEWORK = {
'EXCEPTION_HANDLER': 'authors.apps.core.exceptions.core_exception_handler',
'NON_FIELD_ERRORS_KEY': 'error',

'DEFAULT_AUTHENTICATION_CLASSES': (
'authors.apps.authentication.backends.JWTAuthentication',
)
}

0 comments on commit e4286cb

Please sign in to comment.