Skip to content

Commit

Permalink
feat: user auth API
Browse files Browse the repository at this point in the history
  • Loading branch information
chandansgowda committed Aug 21, 2023
1 parent a64b197 commit 3ba18d5
Show file tree
Hide file tree
Showing 7 changed files with 108 additions and 2 deletions.
2 changes: 2 additions & 0 deletions app/app/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,10 @@
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'rest_framework.authtoken',
'drf_spectacular',
'core',
'user'
]

MIDDLEWARE = [
Expand Down
5 changes: 3 additions & 2 deletions app/app/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,12 @@
)

from django.contrib import admin
from django.urls import path
from django.urls import path, include

urlpatterns = [
path('admin/', admin.site.urls),
path('api/schema/', SpectacularAPIView.as_view(), name='api-schema'),
path('api/docs/', SpectacularSwaggerView.as_view(url_name='api-schema'),
name='api-docs',)
name='api-docs',),
path('api/user/', include('user.urls')),
]
Empty file added app/user/__init__.py
Empty file.
6 changes: 6 additions & 0 deletions app/user/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from django.apps import AppConfig


class UserConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'user'
56 changes: 56 additions & 0 deletions app/user/serializers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
from django.contrib.auth import (
get_user_model,
authenticate,
)
from django.utils.translation import gettext as _

from rest_framework import serializers


class UserSerializer(serializers.ModelSerializer):
"""Serializer for the user object."""

class Meta:
model = get_user_model()
fields = ['email', 'password', 'name']
extra_kwargs = {'password': {'write_only': True, 'min_length': 5}}

def create(self, validated_data):
"""Create and return a user with encrypted password."""
return get_user_model().objects.create_user(**validated_data)

def update(self, instance, validated_data):
"""Update and return user."""
password = validated_data.pop('password', None)
user = super().update(instance, validated_data)

if password:
user.set_password(password)
user.save()

return user


class AuthTokenSerializer(serializers.Serializer):
"""Serializer for the user auth token."""
email = serializers.EmailField()
password = serializers.CharField(
style={'input_type': 'password'},
trim_whitespace=False,
)

def validate(self, attrs):
"""Validate and authenticate the user."""
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
12 changes: 12 additions & 0 deletions app/user/urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from django.urls import path

from user import views


app_name = 'user'

urlpatterns = [
path('create/', views.CreateUserView.as_view(), name='create'),
path('token/', views.CreateTokenView.as_view(), name='token'),
path('me/', views.ManageUserView.as_view(), name='me'),
]
29 changes: 29 additions & 0 deletions app/user/views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
from rest_framework import generics, authentication, permissions
from rest_framework.authtoken.views import ObtainAuthToken
from rest_framework.settings import api_settings
from user.serializers import (
UserSerializer,
AuthTokenSerializer,
)


class CreateUserView(generics.CreateAPIView):
"""Create a new user in the system."""
serializer_class = UserSerializer


class CreateTokenView(ObtainAuthToken):
"""Create a new auth token for user."""
serializer_class = AuthTokenSerializer
renderer_classes = api_settings.DEFAULT_RENDERER_CLASSES


class ManageUserView(generics.RetrieveUpdateAPIView):
"""Manage the authenticated user."""
serializer_class = UserSerializer
authentication_classes = [authentication.TokenAuthentication]
permission_classes = [permissions.IsAuthenticated]

def get_object(self):
"""Retrieve and return the authenticated user."""
return self.request.user

0 comments on commit 3ba18d5

Please sign in to comment.