Skip to content

Commit

Permalink
Added endpoint for getting an auth token
Browse files Browse the repository at this point in the history
  • Loading branch information
mghaznav committed Jul 13, 2024
1 parent 44747df commit 1f64701
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 3 deletions.
1 change: 1 addition & 0 deletions app/app/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
'django.contrib.staticfiles',
'core',
'rest_framework',
'rest_framework.authtoken',
'drf_spectacular',
'user'
]
Expand Down
27 changes: 26 additions & 1 deletion app/user/serializers.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from django.contrib.auth import get_user_model
from django.contrib.auth import get_user_model, authenticate
from django.utils.translation import gettext as _

from rest_framework import serializers

Expand All @@ -17,3 +18,27 @@ class Meta:

def create(self, validated_data):
return get_user_model().objects.create_user(**validated_data)


class AuthTokenSerializer(serializers.Serializer):
email = serializers.EmailField()
password = serializers.CharField(
style={'input_type': 'password'},
trim_whitespace=False
)

def validate(self, attrs):
email = attrs.get('email')
password = attrs.get('password')
user = authenticate(
request=self.context.get('request'),
username=email,
password=password
)

if not user:
msg = _('Unable to authenticate with provided credentials.')
raise serializers.ValidationError(msg, code='authorization')

attrs['user'] = user
return attrs
58 changes: 58 additions & 0 deletions app/user/tests/test_user_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from rest_framework import status

CREATE_USER_URL = reverse('user:create')
TOKEN_URL = reverse('user:token')


def create_user(**params):
Expand All @@ -17,6 +18,10 @@ class PublicUserAPI(TestCase):
def setUp(self):
self.client = APIClient()

"""
Create User Tests
"""

def test_create_user_success(self):
payload = {
'email': '[email protected]',
Expand Down Expand Up @@ -59,3 +64,56 @@ def test_password_too_short_error(self):
email=payload['email']
).exists()
self.assertFalse(user_exists)

"""
Create Token Tests
"""

def test_create_token_for_user(self):
user_details = {
'email': '[email protected]',
'password': 'testpass123',
'name': 'Test Name'
}
create_user(**user_details)

payload = {
'email': user_details['email'],
'password': user_details['password']
}
res = self.client.post(TOKEN_URL, payload)

self.assertIn('token', res.data)
self.assertEqual(res.status_code, status.HTTP_200_OK)

def test_create_token_bad_credentials(self):
user_details = {
'email': '[email protected]',
'password': 'goodpass123'
}
create_user(**user_details)

payload = {
'email': user_details['email'],
'password': 'badpass123'
}
res = self.client.post(TOKEN_URL, payload)

self.assertNotIn('token', res.data)
self.assertEqual(res.status_code, status.HTTP_400_BAD_REQUEST)

def test_create_token_blank_password(self):
user_details = {
'email': '[email protected]',
'password': 'testpass123'
}
create_user(**user_details)

payload = {
'email': user_details['email'],
'password': ''
}
res = self.client.post(TOKEN_URL, payload)

self.assertNotIn('token', res.data)
self.assertEqual(res.status_code, status.HTTP_400_BAD_REQUEST)
3 changes: 2 additions & 1 deletion app/user/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@
app_name = 'user'

urlpatterns = [
path('create/', views.CreateUserView.as_view(), name='create')
path('create/', views.CreateUserView.as_view(), name='create'),
path('token/', views.CreateTokenView.as_view(), name='token')
]
10 changes: 9 additions & 1 deletion app/user/views.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
from rest_framework import generics
from user.serializers import UserSerializer
from rest_framework.authtoken.views import ObtainAuthToken
from rest_framework.settings import api_settings

from user.serializers import UserSerializer, AuthTokenSerializer


class CreateUserView(generics.CreateAPIView):
serializer_class = UserSerializer


class CreateTokenView(ObtainAuthToken):
serializer_class = AuthTokenSerializer
renderer_class = api_settings.DEFAULT_RENDERER_CLASSES

0 comments on commit 1f64701

Please sign in to comment.