feat: added business models, implemented business signup and signin

This commit is contained in:
ITQ
2025-01-20 16:09:37 +03:00
parent 2eef92b617
commit 9ae9b46780
19 changed files with 272 additions and 2 deletions
+6
View File
@@ -0,0 +1,6 @@
from django.apps import AppConfig
class PingConfig(AppConfig):
name = "api.v1.business"
label = "api_v1_business"
+45
View File
@@ -0,0 +1,45 @@
import uuid
from typing import ClassVar
from ninja import ModelSchema, Schema
from pydantic import EmailStr
from apps.business.models import Business
class BusinessSignUpIn(ModelSchema):
email: EmailStr
class Meta:
model = Business
fields: ClassVar[list[str]] = [
Business.name.field.name,
Business.password.field.name,
]
class BusinessSignUpOut(Schema):
token: str
company_id: uuid.UUID
class BusinessSignInIn(ModelSchema):
email: EmailStr
class Meta:
model = Business
fields: ClassVar[list[str]] = [
Business.password.field.name,
]
class BusinessSignInOut(Schema):
token: str
__all__ = [
"BusinessSignInIn",
"BusinessSignInOut",
"BusinessSignUpIn",
"BusinessSignUpOut",
]
+57
View File
@@ -0,0 +1,57 @@
from http import HTTPStatus as status
from django.http import HttpRequest
from ninja import Router
from ninja.errors import AuthenticationError
from api.v1 import schemas as global_schemas
from api.v1.business import schemas
from apps.business.models import Business
router = Router(tags=["business"])
@router.post(
"/auth/sign-up",
response={
status.OK: schemas.BusinessSignUpOut,
status.BAD_REQUEST: global_schemas.ValidationError,
status.CONFLICT: global_schemas.UniqueConstraintError,
},
)
def signup(
request: HttpRequest, business: schemas.BusinessSignUpIn
) -> tuple[int, schemas.BusinessSignUpOut]:
business_obj = Business(**business.dict())
business_obj.save()
return status.OK, schemas.BusinessSignUpOut(
token=business_obj.generate_token(), company_id=business_obj.id
)
@router.post(
"/auth/sign-in",
response={
status.OK: schemas.BusinessSignInOut,
status.BAD_REQUEST: global_schemas.ValidationError,
status.UNAUTHORIZED: global_schemas.UnauthorizedError,
},
)
def signin(
request: HttpRequest, login_data: schemas.BusinessSignInIn
) -> tuple[int, schemas.BusinessSignInOut]:
try:
business_obj = Business.objects.get(email=login_data.email)
except Business.DoesNotExist:
raise AuthenticationError from None
if business_obj.password != login_data.password:
raise AuthenticationError
business_obj.token_version += 1
business_obj.save()
return status.OK, schemas.BusinessSignInOut(
token=business_obj.generate_token()
)
+22 -2
View File
@@ -6,9 +6,28 @@ import django.http
from django.http import HttpRequest, HttpResponse
from ninja import NinjaAPI, errors
from config.errors import UniqueConstraintError
logger = logging.getLogger("django")
def handle_unique_constraint_error(
request: HttpRequest,
exc: UniqueConstraintError,
router: NinjaAPI,
) -> HttpResponse:
detail = list(exc.validation_error)
if hasattr(exc, "error_dict"):
detail = dict(exc.validation_error)
return router.create_response(
request,
{"detail": detail},
status=status.CONFLICT,
)
def handle_django_validation_error(
request: HttpRequest,
exc: django.core.exceptions.ValidationError,
@@ -22,7 +41,7 @@ def handle_django_validation_error(
return router.create_response(
request,
{"detail": detail},
status=status.UNPROCESSABLE_ENTITY,
status=status.BAD_REQUEST,
)
@@ -42,7 +61,7 @@ def handle_validation_error(
return router.create_response(
request,
{"detail": exc.errors},
status=status.UNPROCESSABLE_ENTITY,
status=status.BAD_REQUEST,
)
@@ -69,6 +88,7 @@ def handle_unknown_exception(
exception_handlers = [
(UniqueConstraintError, handle_unique_constraint_error),
(django.core.exceptions.ValidationError, handle_django_validation_error),
(errors.AuthenticationError, handle_authentication_error),
(errors.ValidationError, handle_validation_error),
+5
View File
@@ -3,6 +3,7 @@ from functools import partial
from ninja import NinjaAPI
from api.v1 import handlers
from api.v1.business.views import router as business_router
from api.v1.ping.views import router as ping_router
router = NinjaAPI(
@@ -20,6 +21,10 @@ router.add_router(
"ping",
ping_router,
)
router.add_router(
"business",
business_router,
)
# Register exception handlers
+16
View File
@@ -9,3 +9,19 @@ class UnauthorizedError(Schema):
class NotFoundError(Schema):
detail: str = status.NOT_FOUND.phrase
class ValidationError(Schema):
detail: str
class UniqueConstraintError(Schema):
detail: str
__all__ = [
"NotFoundError",
"UnauthorizedError",
"UniqueConstraintError",
"ValidationError",
]