-
Notifications
You must be signed in to change notification settings - Fork 0
User Authentication and test for all scenarios #7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
24eb1f1
User Authentication and test for all scenarios
Viton8 1a2f7c1
Added some comments
Viton8 8e1fcc9
Merge branch 'develop' into feature/registration
Viton8 113ff7b
Change test, to pytest
Viton8 11cfb76
Add base.html, and solve reviewed problems
Viton8 7982b00
unify comments across views, serializers, and tests
Viton8 a7be0ee
Refactor docstrings in authentication test cases
uxabix ffffcd5
fix wrong indentation in accounts/test_auth.py
Viton8 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| """ | ||
| Authentication API routes for the Accounts app. | ||
|
|
||
| This module defines the endpoints for user registration, login, | ||
| profile retrieval, and logout. These routes are included in the | ||
| project’s main urls.py under the prefix "api/accounts/", which means | ||
| the final URLs are: | ||
|
|
||
| /api/accounts/auth/register/ → Register a new user | ||
| /api/accounts/auth/login/ → Log in an existing user | ||
| /api/accounts/auth/profile/ → Retrieve the authenticated user's profile | ||
| /api/accounts/auth/logout/ → Log out the current user | ||
|
|
||
| Each path is mapped to a class-based API view defined in accounts/api_views.py. | ||
| """ | ||
|
|
||
| from django.urls import path | ||
| from .api_views import RegistrationAPI, LoginAPI, ProfileAPI, LogoutAPI | ||
|
|
||
|
|
||
| urlpatterns = [ | ||
| path('auth/register/', RegistrationAPI.as_view(), name='api_register'), | ||
| path('auth/login/', LoginAPI.as_view(), name='api_login'), | ||
| path('auth/profile/', ProfileAPI.as_view(), name='api_profile'), | ||
| path('auth/logout/', LogoutAPI.as_view(), name='api_logout'), | ||
| ] | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,96 @@ | ||
| """ | ||
| API views for the Accounts app. | ||
|
|
||
| This module defines class-based views for handling user authentication | ||
| via RESTful endpoints. It includes registration, login, profile retrieval, | ||
| and logout functionality. These views are connected to the routes defined | ||
| in accounts/api_urls.py and use serializers from accounts/serializers.py. | ||
|
|
||
| Available API views: | ||
| - RegistrationAPI: create a new user and log them in automatically. | ||
| - LoginAPI: authenticate user credentials and start a session. | ||
| - ProfileAPI: return profile data for the authenticated user. | ||
| - LogoutAPI: end the current user session. | ||
| """ | ||
|
|
||
| from django.contrib.auth import login as auth_login, logout as auth_logout | ||
|
Viton8 marked this conversation as resolved.
|
||
| from rest_framework import generics, permissions, status | ||
| from rest_framework.response import Response | ||
| from rest_framework.views import APIView | ||
| from .serializers import RegistrationSerializer, LoginSerializer, ProfileSerializer | ||
|
|
||
| class RegistrationAPI(generics.CreateAPIView): | ||
| """ | ||
| API endpoint for user registration. | ||
|
|
||
| Handles the creation of a new user account using validated input. | ||
| Automatically logs in the newly created user to establish a session. | ||
| """ | ||
| serializer_class = RegistrationSerializer | ||
| permission_classes = [permissions.AllowAny] | ||
|
|
||
| def perform_create(self, serializer): | ||
|
Viton8 marked this conversation as resolved.
|
||
| """ | ||
| Save the new user instance and log them in. | ||
|
|
||
| Overrides the default CreateAPIView behavior to attach the user | ||
| to the current session immediately after registration. | ||
| """ | ||
| user = serializer.save() | ||
| auth_login(self.request, user) | ||
|
|
||
| class LoginAPI(APIView): | ||
| """ | ||
| API endpoint for user login. | ||
|
|
||
| Accepts username and password, authenticates the user, | ||
| and returns their profile data upon successful login. | ||
| """ | ||
| permission_classes = [permissions.AllowAny] | ||
|
|
||
| def post(self, request): | ||
| """ | ||
| Authenticate user credentials and start a session. | ||
|
|
||
| If credentials are valid, the user is logged in and their | ||
| profile data is returned in the response. | ||
| """ | ||
| serializer = LoginSerializer(data=request.data) | ||
| serializer.is_valid(raise_exception=True) | ||
| user = serializer.validated_data['user'] | ||
| auth_login(request, user) | ||
| return Response(ProfileSerializer(user).data) | ||
|
|
||
| class ProfileAPI(generics.RetrieveAPIView): | ||
| """ | ||
| API endpoint for retrieving the authenticated user's profile. | ||
|
|
||
| Requires the user to be logged in. Returns basic profile information. | ||
| """ | ||
| serializer_class = ProfileSerializer | ||
| permission_classes = [permissions.IsAuthenticated] | ||
|
|
||
| def get_object(self): | ||
| """ | ||
| Return the current authenticated user. | ||
|
|
||
| Used by RetrieveAPIView to serialize and return profile data. | ||
| """ | ||
| return self.request.user | ||
|
|
||
| class LogoutAPI(APIView): | ||
| """ | ||
| API endpoint for logging out the current user. | ||
|
|
||
| Requires authentication. Ends the session and returns a confirmation message. | ||
| """ | ||
| permission_classes = [permissions.IsAuthenticated] | ||
|
|
||
| def post(self, request): | ||
| """ | ||
| End the current user session. | ||
|
|
||
| Logs out the user and returns a success response. | ||
| """ | ||
| auth_logout(request) | ||
| return Response({'detail': 'You are out of the system'}, status=status.HTTP_200_OK) | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| """ | ||
| Forms for the Accounts app. | ||
|
|
||
| This module defines form classes used for user registration and login. | ||
| They extend Django's built-in authentication forms to include additional | ||
| fields or custom behavior where necessary. | ||
|
|
||
| Available forms: | ||
| - RegistrationForm: extends UserCreationForm to include an email field. | ||
| - LoginForm: extends AuthenticationForm for user login. | ||
| """ | ||
|
|
||
| from django import forms | ||
| from django.contrib.auth.forms import UserCreationForm, AuthenticationForm | ||
| from django.contrib.auth import get_user_model | ||
|
|
||
| User = get_user_model() | ||
|
|
||
| class RegistrationForm(UserCreationForm): | ||
| """ | ||
| Form for user registration. | ||
|
|
||
| Extends Django's built-in UserCreationForm by adding | ||
| a required email field. Handles validation and creation | ||
| of a new user instance with username, email, and password. | ||
| """ | ||
| email = forms.EmailField(required=True) | ||
|
|
||
| class Meta: | ||
| model = User | ||
| fields = ('username', 'email', 'password1', 'password2') | ||
|
|
||
| class LoginForm(AuthenticationForm): | ||
| """ | ||
| Form for user login. | ||
|
|
||
| Extends Django's built-in AuthenticationForm without | ||
| additional fields. Used to authenticate existing users | ||
| with their username and password. | ||
| """ | ||
| pass |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,76 @@ | ||
| """ | ||
| Serializers for the Accounts app. | ||
|
|
||
| This module defines serializers used for user authentication and profile | ||
| management. They handle validation and transformation of input/output data | ||
| between Django models and API views. | ||
|
|
||
| Available serializers: | ||
| - RegistrationSerializer: validates and creates new user accounts. | ||
| - LoginSerializer: authenticates existing users with username/password. | ||
| - ProfileSerializer: returns basic profile information for authenticated users. | ||
| """ | ||
|
|
||
| from django.contrib.auth import authenticate, get_user_model | ||
| from rest_framework import serializers | ||
|
|
||
| User = get_user_model() | ||
|
|
||
| class RegistrationSerializer(serializers.ModelSerializer): | ||
| """ | ||
| Serializer for user registration. | ||
|
|
||
| Validates the provided username, email, and password. | ||
| Creates a new user instance with an encrypted password. | ||
| """ | ||
| password = serializers.CharField(write_only=True, min_length=8) | ||
|
|
||
| class Meta: | ||
| model = User | ||
| fields = ('username', 'email', 'password') | ||
|
|
||
| def create(self, validated_data): | ||
| """ | ||
| Create a new user with the given validated data. | ||
|
|
||
| Uses Django's built-in create_user method to ensure | ||
| the password is properly hashed before saving. | ||
| """ | ||
| return User.objects.create_user( | ||
| username=validated_data['username'], | ||
| email=validated_data.get('email', ''), | ||
| password=validated_data['password'], | ||
| ) | ||
|
|
||
| class LoginSerializer(serializers.Serializer): | ||
| """ | ||
| Serializer for user login. | ||
|
|
||
| Accepts username and password, and authenticates the user | ||
| using Django's built-in authentication system. | ||
| """ | ||
| username = serializers.CharField() | ||
| password = serializers.CharField(write_only=True) | ||
|
|
||
| def validate(self, attrs): | ||
| """ | ||
| Validate the provided credentials. | ||
|
|
||
| If authentication fails, raise a ValidationError. | ||
| On success, attach the authenticated user to attrs. | ||
| """ | ||
| user = authenticate(username=attrs['username'], password=attrs['password']) | ||
| if not user: | ||
| raise serializers.ValidationError('Incorrect login details') | ||
| attrs['user'] = user | ||
| return attrs | ||
|
|
||
| class ProfileSerializer(serializers.ModelSerializer): | ||
| """ | ||
| Serializer for displaying user profile data. | ||
|
|
||
| Returns basic information about the authenticated user. | ||
| """ | ||
| class Meta: | ||
| model = User | ||
| fields = ('id', 'username', 'email') |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| {% extends "base.html" %} | ||
|
|
||
| {% block title %}Login{% endblock %} | ||
|
|
||
| {% block content %} | ||
| <h1>Login</h1> | ||
| <form method="post"> | ||
| {% csrf_token %} | ||
| {{ form.as_p }} | ||
| <button type="submit">Login</button> | ||
| </form> | ||
| <p> | ||
| Don't have an account? <a href="{% url 'register' %}">Registration</a> | ||
| </p> | ||
| {% endblock %} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| {% extends "base.html" %} | ||
|
|
||
| {% block title %}Profile{% endblock %} | ||
|
|
||
| {% block content %} | ||
| <h1>Profile</h1> | ||
| <p>User name: {{ user.username }}</p> | ||
| <p>Email: {{ user.email }}</p> | ||
| <form method="post" action="{% url 'logout' %}"> | ||
| {% csrf_token %} | ||
| <button type="submit">Exit</button> | ||
| </form> | ||
| {% endblock %} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| {% extends "base.html" %} | ||
|
|
||
| {% block title %}Register{% endblock %} | ||
|
|
||
| {% block content %} | ||
| <h1>Registration</h1> | ||
| <form method="post"> | ||
| {% csrf_token %} | ||
| {{ form.as_p }} | ||
| <button type="submit">Register</button> | ||
| </form> | ||
| <a href="{% url 'login' %}">Already exist? Login</a> | ||
| {% endblock %} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| <!DOCTYPE html> | ||
| <html lang="en"> | ||
| <head> | ||
| <meta charset="UTF-8"> | ||
| <title>{% block title %}Fools Arena{% endblock %}</title> | ||
| </head> | ||
| <body> | ||
| <header> | ||
| <h1>Fools Arena</h1> | ||
| <nav> | ||
| <a href="{% url 'login' %}">Login</a> | | ||
| <a href="{% url 'register' %}">Register</a> | | ||
| <a href="{% url 'profile' %}">Profile</a> | ||
| </nav> | ||
| </header> | ||
|
|
||
| <main> | ||
| {% block content %} | ||
| <!-- Page-specific content will be injected here --> | ||
| {% endblock %} | ||
| </main> | ||
|
|
||
| <footer> | ||
| <p>© 2025 Fools Arena</p> | ||
| </footer> | ||
| </body> | ||
| </html> |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.