diff --git a/app/app/settings.py b/app/app/settings.py index d2077e5..2d6acaf 100644 --- a/app/app/settings.py +++ b/app/app/settings.py @@ -41,7 +41,9 @@ 'django.contrib.staticfiles', 'core', 'rest_framework', + 'rest_framework.authtoken', 'drf_spectacular', + 'user', ] MIDDLEWARE = [ diff --git a/app/app/urls.py b/app/app/urls.py index 479b502..58d41f2 100644 --- a/app/app/urls.py +++ b/app/app/urls.py @@ -18,11 +18,11 @@ SpectacularSwaggerView, ) 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'), - + path('api/user/',include('user.urls')), ] diff --git a/app/user/__init__.py b/app/user/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/user/apps.py b/app/user/apps.py new file mode 100644 index 0000000..36cce4c --- /dev/null +++ b/app/user/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class UserConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'user' diff --git a/app/user/serializers.py b/app/user/serializers.py new file mode 100644 index 0000000..c590c38 --- /dev/null +++ b/app/user/serializers.py @@ -0,0 +1,44 @@ +""" +Serializers for the user API view +""" + +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): + class Meta: + model=get_user_model() + fields=['email','password','name'] + extra_kwargs={'password': {'write_only':True,'min_length':5}} + + def create(self, validated_data): + return get_user_model().objects.create_user(**validated_data) # type: ignore + + def update(self, instance, validated_data): + 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 token""" + 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 auth") + raise serializers.ValidationError(msg,code='authorization') + attrs['user']=user + return attrs + \ No newline at end of file diff --git a/app/user/urls.py b/app/user/urls.py new file mode 100644 index 0000000..15321cb --- /dev/null +++ b/app/user/urls.py @@ -0,0 +1,14 @@ +""" +URL mappings for User API +""" + +from django.urls import path +from user import views + +app_name='user' + +urlpatterns = [ + path('create/',views.CreateUserView.as_view(),name='create user'), + path('token/',views.CreateTokenView.as_view(),name='token'), + path('me/',views.ManageUserView.as_view(),name='me') +] diff --git a/app/user/views.py b/app/user/views.py new file mode 100644 index 0000000..c35aa4d --- /dev/null +++ b/app/user/views.py @@ -0,0 +1,25 @@ +""" +Views for the User API +""" + +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): + serializer_class=AuthTokenSerializer + +class ManageUserView(generics.RetrieveUpdateAPIView): + serializer_class=UserSerializer + authentication_classes=[authentication.TokenAuthentication] + permission_classes=[permissions.IsAuthenticated] + + def get_object(self): + return self.request.user + \ No newline at end of file