schon/vibes_auth/views.py
Egor fureunoir Gorbunov 856f2ff516 Features: 1) Add app_name attribute in multiple urls.py files across apps to support namespacing;
Fixes: 1) Simplify Prometheus and GraphQL path definitions in `evibes/api_urls.py`;

Extra: 1) Add line breaks across multiple files for improved code readability.
2025-06-29 20:03:33 +03:00

117 lines
4.7 KiB
Python

import logging
from django.utils.decorators import method_decorator
from django.utils.translation import gettext_lazy as _
from django_ratelimit.decorators import ratelimit
from drf_spectacular.utils import (
extend_schema_view,
)
from rest_framework import status
from rest_framework.response import Response
from rest_framework_simplejwt.exceptions import TokenError
from rest_framework_simplejwt.views import TokenViewBase
from evibes.settings import DEBUG
from vibes_auth.docs.drf.views import TOKEN_OBTAIN_SCHEMA, TOKEN_REFRESH_SCHEMA, TOKEN_VERIFY_SCHEMA
from vibes_auth.serializers import (
TokenObtainPairSerializer,
TokenRefreshSerializer,
TokenVerifySerializer,
)
logger = logging.getLogger(__name__)
@extend_schema_view(**TOKEN_OBTAIN_SCHEMA)
class TokenObtainPairView(TokenViewBase):
"""
Represents a view for obtaining a pair of access and refresh tokens.
This view manages the process of handling token-based authentication where
clients can obtain a pair of JWT tokens (access and refresh) using provided
credentials. It is built on top of a base token view and ensures proper
rate limiting to protect against brute force attacks.
Attributes:
serializer_class: Serializer class used for processing request data
and returning response data.
_serializer_class: Internal serializer class reference.
Usage:
This view should be used in authentication-related APIs where clients
need to obtain new sets of tokens. It incorporates both a serializer for
processing incoming data and also rate limiting to enforce request limits.
Methods:
post: Handles HTTP POST requests for token retrieval. This method is
subject to rate limiting depending on the global DEBUG setting.
"""
serializer_class = TokenObtainPairSerializer # type: ignore
_serializer_class = TokenObtainPairSerializer # type: ignore
@method_decorator(ratelimit(key="ip", rate="10/h" if not DEBUG else "888/h"))
def post(self, request, *args, **kwargs):
return super().post(request, *args, **kwargs)
@extend_schema_view(**TOKEN_REFRESH_SCHEMA)
class TokenRefreshView(TokenViewBase):
"""
Handles refreshing of tokens for authentication purposes.
This class is used to provide functionality for token refresh
operations as part of an authentication system. It ensures that
clients can request a refreshed token within defined rate limits.
The view relies on the associated serializer to validate token
refresh inputs and produce appropriate outputs.
Attributes:
serializer_class (Serializer): The serializer used to handle
token refresh operations. This establishes the validation
and processing logic for incoming requests.
_serializer_class (Serializer): Internal reference to the
serializer, typically used for ensuring consistent processing
for refresh-related logic.
Methods:
post: Handles HTTP POST requests to refresh the token.
Rate limits requests based on the IP of the client submitting
the request. Rate limit settings are defined depending on
whether the application is in DEBUG mode or not.
"""
serializer_class = TokenRefreshSerializer # type: ignore
_serializer_class = TokenRefreshSerializer # type: ignore
@method_decorator(ratelimit(key="ip", rate="10/h" if not DEBUG else "888/h"))
def post(self, request, *args, **kwargs):
return super().post(request, *args, **kwargs)
@extend_schema_view(**TOKEN_VERIFY_SCHEMA)
class TokenVerifyView(TokenViewBase):
"""
Represents a view for verifying JSON Web Tokens (JWT) using specific serialization
and validation logic.
This class inherits from the `TokenViewBase` and is designed to handle the POST
request for verifying JWT tokens. Tokens are validated using the associated
`TokenVerifySerializer`. The view processes incoming requests, validates tokens,
and returns a response indicating whether the token is valid. If valid, associated
user data can also be returned. Errors during token validation result in an appropriate
error response.
"""
serializer_class = TokenVerifySerializer # type: ignore
_serializer_class = TokenVerifySerializer # type: ignore
def post(self, request, *args, **kwargs):
try:
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
user_data = serializer.validated_data.pop("user", None)
return Response({"token": _("the token is valid"), "user": user_data})
except TokenError:
return Response({"detail": _("the token is invalid")}, status=status.HTTP_400_BAD_REQUEST)