middleware and respnse models updated

This commit is contained in:
berkay 2025-01-27 17:25:49 +03:00
parent e403993d24
commit b88f910a43
54 changed files with 1125 additions and 808 deletions

View File

@ -6,14 +6,59 @@
<component name="ChangeListManager">
<list default="true" id="b5202e0c-6ddf-4a56-a13a-e18798c4c7cf" name="Changes" comment="">
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/ApiLayers/AllConfigs/Redis/configs.py" beforeDir="false" afterPath="$PROJECT_DIR$/ApiLayers/AllConfigs/Redis/configs.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/ApiLayers/ApiLibrary/token/password_module.py" beforeDir="false" afterPath="$PROJECT_DIR$/ApiLayers/ApiLibrary/token/password_module.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/ApiLayers/ApiServices/Cluster/create_router.py" beforeDir="false" afterPath="$PROJECT_DIR$/ApiLayers/ApiServices/Cluster/create_router.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/ApiLayers/ApiServices/Cluster/handle_cluster.py" beforeDir="false" afterPath="$PROJECT_DIR$/ApiLayers/ApiServices/Cluster/handle_cluster.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/ApiLayers/ApiServices/Login/user_login_handler.py" beforeDir="false" afterPath="$PROJECT_DIR$/ApiLayers/ApiServices/Login/user_login_handler.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/ApiLayers/ApiServices/Token/token_handler.py" beforeDir="false" afterPath="$PROJECT_DIR$/ApiLayers/ApiServices/Token/token_handler.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/ApiLayers/ApiValidations/Custom/wrapper_contexts.py" beforeDir="false" afterPath="$PROJECT_DIR$/ApiLayers/ApiValidations/Custom/wrapper_contexts.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/ApiLayers/ApiValidations/Request/decision_book.py" beforeDir="false" afterPath="$PROJECT_DIR$/ApiLayers/ApiValidations/Request/decision_book.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/ApiLayers/ApiValidations/Response/default_response.py" beforeDir="false" afterPath="$PROJECT_DIR$/ApiLayers/ApiValidations/Response/default_response.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/ApiLayers/ErrorHandlers/Exceptions/api_exc.py" beforeDir="false" afterPath="$PROJECT_DIR$/ApiLayers/ErrorHandlers/Exceptions/api_exc.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/ApiLayers/LanguageModels/Database/__init__.py" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/ApiLayers/LanguageModels/Database/account/account.py" beforeDir="false" afterPath="$PROJECT_DIR$/ApiLayers/LanguageModels/Database/account/account.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/ApiLayers/LanguageModels/Database/account/iban.py" beforeDir="false" afterPath="$PROJECT_DIR$/ApiLayers/LanguageModels/Database/account/iban.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/ApiLayers/LanguageModels/Database/building/budget.py" beforeDir="false" afterPath="$PROJECT_DIR$/ApiLayers/LanguageModels/Database/building/budget.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/ApiLayers/LanguageModels/Database/building/build.py" beforeDir="false" afterPath="$PROJECT_DIR$/ApiLayers/LanguageModels/Database/building/build.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/ApiLayers/LanguageModels/Database/building/decision_book.py" beforeDir="false" afterPath="$PROJECT_DIR$/ApiLayers/LanguageModels/Database/building/decision_book.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/ApiLayers/LanguageModels/Database/company/company.py" beforeDir="false" afterPath="$PROJECT_DIR$/ApiLayers/LanguageModels/Database/company/company.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/ApiLayers/LanguageModels/Database/company/department.py" beforeDir="false" afterPath="$PROJECT_DIR$/ApiLayers/LanguageModels/Database/company/department.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/ApiLayers/LanguageModels/Database/company/employee.py" beforeDir="false" afterPath="$PROJECT_DIR$/ApiLayers/LanguageModels/Database/company/employee.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/ApiLayers/LanguageModels/Database/event/event.py" beforeDir="false" afterPath="$PROJECT_DIR$/ApiLayers/LanguageModels/Database/event/event.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/ApiLayers/LanguageModels/Database/identity/identity.py" beforeDir="false" afterPath="$PROJECT_DIR$/ApiLayers/LanguageModels/Database/identity/identity.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/ApiLayers/LanguageModels/Database/rules/rules.py" beforeDir="false" afterPath="$PROJECT_DIR$/ApiLayers/LanguageModels/Database/rules/rules.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/ApiLayers/LanguageModels/Errors/__init__.py" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/ApiLayers/Middleware/auth_middleware.py" beforeDir="false" afterPath="$PROJECT_DIR$/ApiLayers/Middleware/auth_middleware.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/ApiLayers/Middleware/token_event_middleware.py" beforeDir="false" afterPath="$PROJECT_DIR$/ApiLayers/Middleware/token_event_middleware.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/ApiLayers/Schemas/building/build.py" beforeDir="false" afterPath="$PROJECT_DIR$/ApiLayers/Schemas/building/build.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/ApiLayers/Schemas/identity/identity.py" beforeDir="false" afterPath="$PROJECT_DIR$/ApiLayers/Schemas/identity/identity.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/ApiLayers/Schemas/rules/rules.py" beforeDir="false" afterPath="$PROJECT_DIR$/ApiLayers/Schemas/rules/rules.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/DockerApiServices/AuthServiceApi/app_handler.py" beforeDir="false" afterPath="$PROJECT_DIR$/DockerApiServices/AuthServiceApi/app_handler.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/DockerApiServices/AuthServiceApi/config.py" beforeDir="false" afterPath="$PROJECT_DIR$/DockerApiServices/AuthServiceApi/config.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/DockerApiServices/AuthServiceApi/create_routes.py" beforeDir="false" afterPath="$PROJECT_DIR$/DockerApiServices/AuthServiceApi/create_routes.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/DockerApiServices/AuthServiceApi/open_api_creator.py" beforeDir="false" afterPath="$PROJECT_DIR$/DockerApiServices/AuthServiceApi/open_api_creator.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/DockerApiServices/EventServiceApi/app_handler.py" beforeDir="false" afterPath="$PROJECT_DIR$/DockerApiServices/EventServiceApi/app_handler.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/DockerApiServices/EventServiceApi/config.py" beforeDir="false" afterPath="$PROJECT_DIR$/DockerApiServices/EventServiceApi/config.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/DockerApiServices/EventServiceApi/create_routes.py" beforeDir="false" afterPath="$PROJECT_DIR$/DockerApiServices/EventServiceApi/create_routes.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/DockerApiServices/EventServiceApi/open_api_creator.py" beforeDir="false" afterPath="$PROJECT_DIR$/DockerApiServices/EventServiceApi/open_api_creator.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/DockerApiServices/ValidationServiceApi/app_handler.py" beforeDir="false" afterPath="$PROJECT_DIR$/DockerApiServices/ValidationServiceApi/app_handler.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/DockerApiServices/ValidationServiceApi/config.py" beforeDir="false" afterPath="$PROJECT_DIR$/DockerApiServices/ValidationServiceApi/config.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/DockerApiServices/ValidationServiceApi/create_routes.py" beforeDir="false" afterPath="$PROJECT_DIR$/DockerApiServices/ValidationServiceApi/create_routes.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/DockerApiServices/ValidationServiceApi/open_api_creator.py" beforeDir="false" afterPath="$PROJECT_DIR$/DockerApiServices/ValidationServiceApi/open_api_creator.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Events/AllEvents/authentication/auth/api_events.py" beforeDir="false" afterPath="$PROJECT_DIR$/Events/AllEvents/authentication/auth/api_events.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Events/AllEvents/authentication/auth/auth.py" beforeDir="false" afterPath="$PROJECT_DIR$/Events/AllEvents/authentication/auth/auth.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Events/AllEvents/authentication/auth/function_handlers.py" beforeDir="false" afterPath="$PROJECT_DIR$/Events/AllEvents/authentication/auth/function_handlers.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Events/AllEvents/authentication/auth/models.py" beforeDir="false" afterPath="$PROJECT_DIR$/Events/AllEvents/authentication/auth/models.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Events/AllEvents/events/__init__.py" beforeDir="false" afterPath="$PROJECT_DIR$/Events/AllEvents/events/__init__.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Events/AllEvents/events_file.py" beforeDir="false" afterPath="$PROJECT_DIR$/Events/AllEvents/events_file.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Events/Engine/abstract_class.py" beforeDir="false" afterPath="$PROJECT_DIR$/Events/Engine/abstract_class.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Events/Engine/set_defaults/category_cluster_models.py" beforeDir="false" afterPath="$PROJECT_DIR$/Events/Engine/set_defaults/category_cluster_models.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Events/Engine/set_defaults/prepare_redis_items.py" beforeDir="false" afterPath="$PROJECT_DIR$/Events/Engine/set_defaults/prepare_redis_items.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Events/Engine/set_defaults/run.py" beforeDir="false" afterPath="$PROJECT_DIR$/Events/Engine/set_defaults/run.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Events/Engine/set_defaults/setClusters.py" beforeDir="false" afterPath="$PROJECT_DIR$/Events/Engine/set_defaults/setClusters.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Events/base_request_model.py" beforeDir="false" afterPath="$PROJECT_DIR$/Events/base_request_model.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Services/PostgresDb/Models/filter_functions.py" beforeDir="false" afterPath="$PROJECT_DIR$/Services/PostgresDb/Models/filter_functions.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Services/PostgresDb/Models/mixin.py" beforeDir="false" afterPath="$PROJECT_DIR$/Services/PostgresDb/Models/mixin.py" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />

View File

@ -13,7 +13,7 @@ class PasswordModule:
return str(uuid.uuid4()) if str_std else uuid.uuid4()
@staticmethod
def generate_token(length=32):
def generate_token(length=32) -> str:
letters = "abcdefghijklmnopqrstuvwxyz"
merged_letters = [letter for letter in letters] + [
letter.upper() for letter in letters
@ -27,17 +27,17 @@ class PasswordModule:
return token_generated
@staticmethod
def generate_access_token():
def generate_access_token() -> str:
return secrets.token_urlsafe(Auth.ACCESS_TOKEN_LENGTH)
@staticmethod
def generate_refresher_token():
def generate_refresher_token() -> str:
return secrets.token_urlsafe(Auth.REFRESHER_TOKEN_LENGTH)
@staticmethod
def create_hashed_password(domain: str, id_: str, password: str):
def create_hashed_password(domain: str, id_: str, password: str) -> str:
return hashlib.sha256(f"{domain}:{id_}:{password}".encode("utf-8")).hexdigest()
@classmethod
def check_password(cls, domain, id_, password, password_hashed):
def check_password(cls, domain, id_, password, password_hashed) -> bool:
return cls.create_hashed_password(domain, id_, password) == password_hashed

View File

@ -27,7 +27,10 @@ class CreateEndpointFromCluster:
"summary": self.method_endpoint.SUMMARY,
"description": self.method_endpoint.DESCRIPTION,
}
if hasattr(self.method_endpoint, 'RESPONSE_MODEL') and self.method_endpoint.RESPONSE_MODEL is not None:
if (
hasattr(self.method_endpoint, "RESPONSE_MODEL")
and self.method_endpoint.RESPONSE_MODEL is not None
):
kwargs["response_model"] = self.method_endpoint.RESPONSE_MODEL
method(**kwargs)(self.method_endpoint.endpoint_callable)

View File

@ -2,4 +2,3 @@ from Services.Redis import RedisActions, AccessToken
from Services.Redis.Models.cluster import RedisList
redis_list = RedisList(redis_key="test")

View File

@ -1,9 +1,7 @@
from typing import Any, Dict
from ApiLayers.ErrorHandlers import HTTPExceptionApi
from ApiLayers.ApiValidations.Request.authentication import Login
from ApiLayers.ApiLibrary.token.password_module import PasswordModule
from ApiLayers.ApiLibrary.common.line_number import get_line_number_for_error
from ApiLayers.ErrorHandlers import HTTPExceptionApi
class UserLoginModule:
@ -11,13 +9,27 @@ class UserLoginModule:
def __init__(self, request: "Request"):
self.request = request
self.user = None
self.access_object = None
self.access_token = None
self.refresh_token = None
@property
def as_dict(self) -> dict:
return {
"user": self.user,
"access_object": self.access_object,
"access_token": self.access_token,
"refresh_token": self.refresh_token,
}
@staticmethod
def check_user_exists(access_key: str):
from ApiLayers.Schemas import Users
"""Check if user exists."""
db_session = Users.new_session()
"""
Check if the user exists in the database.
"""
db_session = Users.new_session() # Check if user exists.
if "@" in access_key:
found_user: Users = Users.filter_one(
Users.email == access_key.lower(), db=db_session
@ -31,39 +43,48 @@ class UserLoginModule:
error_code="HTTP_400_BAD_REQUEST",
lang="en",
loc=get_line_number_for_error(),
sys_msg="User not found",
sys_msg="check_user_exists: User not found",
)
return found_user
def login_user_via_credentials(self, access_data: "Login") -> Dict[str, Any]:
def login_user_via_credentials(self, access_data: "Login") -> None:
from ApiLayers.ApiServices.Token.token_handler import TokenService
from ApiLayers.Schemas import Users
"""
Login the user via the credentials.
"""
# Get the actual data from the BaseRequestModel if needed
found_user: Users = self.check_user_exists(access_key=access_data.access_key)
self.user = found_user
if len(found_user.hash_password) < 5:
raise HTTPExceptionApi(
error_code="HTTP_400_BAD_REQUEST",
lang=found_user.lang,
loc=get_line_number_for_error(),
sys_msg="Invalid password create a password to user first",
sys_msg="login_user_via_credentials: Invalid password create a password to user first",
)
# Check if the password is correct
if PasswordModule.check_password(
domain=access_data.domain,
id_=found_user.uu_id,
password=access_data.password,
password_hashed=found_user.hash_password,
domain=access_data.domain, id_=found_user.uu_id,
password=access_data.password, password_hashed=found_user.hash_password,
):
return TokenService.set_access_token_to_redis(
request=self.request,
user=found_user,
domain=access_data.domain,
remember=access_data.remember_me,
# Set the access token to the redis
token_response = TokenService.set_access_token_to_redis(
request=self.request, user=found_user, domain=access_data.domain, remember=access_data.remember_me,
)
# Set the user and token information to the instance
self.user = found_user.get_dict()
self.access_token = token_response.get("access_token")
self.refresh_token = token_response.get("refresh_token")
self.access_object = {
"user_type": token_response.get("user_type", None),
"selection_list": token_response.get("selection_list", {})
}
return None
raise HTTPExceptionApi(
error_code="HTTP_400_BAD_REQUEST",
lang=found_user.lang,
lang="tr",
loc=get_line_number_for_error(),
sys_msg="login_user_via_credentials raised error",
sys_msg="login_user_via_credentials: raised an unknown error",
)

View File

@ -250,7 +250,7 @@ class TokenService:
return {
"access_token": access_token,
"user_type": UserType.employee.name,
"companies_list": companies_list,
"selection_list": companies_list,
}
raise HTTPExceptionApi(
error_code="",
@ -264,8 +264,8 @@ class TokenService:
"""Remove all tokens for a user with specific domain."""
redis_rows = cls._get_user_tokens(user)
for redis_row in redis_rows.all:
if redis_row.data.get("domain") == domain:
RedisActions.delete_key(redis_row.key)
if redis_row.row.get("domain") == domain:
redis_row.delete()
@classmethod
def remove_all_token(cls, user: Users) -> None:

View File

@ -2,8 +2,7 @@ from typing import Optional, Any
from pydantic import BaseModel
class DefaultContext(BaseModel):
...
class DefaultContext(BaseModel): ...
class EventContext(DefaultContext):
@ -11,8 +10,19 @@ class EventContext(DefaultContext):
auth: Any
code: str
url: str
request: Optional[Any] = None
@property
def base(self) -> dict[str, Any]:
return {"url": self.url, "code": self.code}
class AuthContext(DefaultContext):
auth: Any
url: str
request: Optional[Any] = None
@property
def base(self) -> dict[str, Any]:
return {"url": self.url}

View File

@ -1,5 +1,9 @@
from typing import Optional
from ApiLayers.ApiValidations.Request import BaseModelRegular, PydanticBaseModel, ListOptions
from ApiLayers.ApiValidations.Request import (
BaseModelRegular,
PydanticBaseModel,
ListOptions,
)
class DecisionBookDecisionBookInvitations(BaseModelRegular):

View File

@ -15,85 +15,85 @@ class BaseEndpointResponse:
from ApiLayers.AllConfigs.Redis.configs import RedisValidationKeys
language_model_key = f"{RedisValidationKeys.LANGUAGE_MODELS}:{RedisValidationKeys.RESPONSES}"
language_model = RedisActions.get_json(list_keys=[language_model_key, self.code , self.lang])
language_model = RedisActions.get_json(list_keys=[language_model_key, self.code, self.lang])
if language_model.status:
return language_model.first.as_dict
raise ValueError("Language model not found")
return {"message": f"{self.code} -> Language model not found"}
class EndpointSuccessResponse(BaseEndpointResponse): # 1. 200 OK
class EndpointSuccessResponse(BaseEndpointResponse): # 200 OK
def as_dict(self, data: Optional[dict] = None):
return JSONResponse(
status_code=status.HTTP_200_OK,
content=dict(completed=True, lang=self.lang, data=data, **self.response)
content=dict(completed=True, **self.response, lang=self.lang, data=data),
)
class EndpointCreatedResponse(BaseEndpointResponse): # 2. 201 Created
class EndpointCreatedResponse(BaseEndpointResponse): # 201 Created
def as_dict(self, data: Optional[dict] = None):
return JSONResponse(
status_code=status.HTTP_201_CREATED,
content=dict(completed=True, lang=self.lang, data=data, **self.response)
content=dict(completed=True, **self.response, lang=self.lang, data=data),
)
class EndpointAcceptedResponse(BaseEndpointResponse): # 3. 202 Accepted
class EndpointAcceptedResponse(BaseEndpointResponse): # 202 Accepted
def as_dict(self, data: Optional[dict] = None):
return JSONResponse(
status_code=status.HTTP_202_ACCEPTED,
content=dict(completed=True, lang=self.lang, data=data, **self.response)
content=dict(completed=True, **self.response, lang=self.lang, data=data),
)
class EndpointBadRequestResponse(BaseEndpointResponse): # 4. 400 Bad Request
class EndpointBadRequestResponse(BaseEndpointResponse): # 400 Bad Request
def as_dict(self, data: Optional[dict] = None):
return JSONResponse(
status_code=status.HTTP_400_BAD_REQUEST,
content=dict(completed=False, lang=self.lang, data=data, **self.response)
content=dict(completed=False, **self.response, lang=self.lang, data=data),
)
class EndpointUnauthorizedResponse(BaseEndpointResponse): # 5. 401 Unauthorized
class EndpointUnauthorizedResponse(BaseEndpointResponse): # 401 Unauthorized
def as_dict(self):
return JSONResponse(
status_code=status.HTTP_401_UNAUTHORIZED,
content=dict(completed=False, lang=self.lang, **self.response)
content=dict(completed=False, **self.response, lang=self.lang),
)
class EndpointNotFoundResponse(BaseEndpointResponse): # 6. 404 Not Found
class EndpointNotFoundResponse(BaseEndpointResponse): # 404 Not Found
def as_dict(self):
return JSONResponse(
status_code=status.HTTP_404_NOT_FOUND,
content=dict(completed=False, lang=self.lang, **self.response)
content=dict(completed=False, **self.response, lang=self.lang),
)
class EndpointForbiddenResponse(BaseEndpointResponse): # 3. 403 Forbidden
class EndpointForbiddenResponse(BaseEndpointResponse): # 403 Forbidden
def as_dict(self):
return JSONResponse(
status_code=status.HTTP_403_FORBIDDEN,
content=dict(completed=False, lang=self.lang, **self.response)
content=dict(completed=False, **self.response, lang=self.lang),
)
class EndpointConflictResponse(BaseEndpointResponse): # 6. 409 Conflict
class EndpointConflictResponse(BaseEndpointResponse): # 409 Conflict
def as_dict(self):
return JSONResponse(
status_code=status.HTTP_409_CONFLICT,
content=dict(completed=False, lang=self.lang, **self.response)
content=dict(completed=False, **self.response, lang=self.lang),
)
class EndpointTooManyRequestsResponse(BaseEndpointResponse): # 7. 429 Too Many Requests
class EndpointTooManyRequestsResponse(BaseEndpointResponse): # 429 Too Many Requests
def __init__(self, retry_after: int, lang: str, code: str):
super().__init__(lang=lang, code=code)
@ -103,16 +103,16 @@ class EndpointTooManyRequestsResponse(BaseEndpointResponse): # 7. 429 Too Ma
return JSONResponse(
status_code=status.HTTP_429_TOO_MANY_REQUESTS,
headers={"Retry-After": str(self.retry_after)},
content=dict(completed=False, lang=self.lang, **self.response)
content=dict(completed=False, **self.response, lang=self.lang),
)
class EndpointInternalErrorResponse(BaseEndpointResponse): # 7. 500 Internal Server Error
class EndpointInternalErrorResponse(BaseEndpointResponse): # 500 Internal Server Error
def as_dict(self):
return JSONResponse(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
content=dict(completed=False, lang=self.lang, **self.response)
content=dict(completed=False, **self.response, lang=self.lang),
)
@ -121,5 +121,5 @@ class EndpointErrorResponse(BaseEndpointResponse):
def as_dict(self):
return JSONResponse(
status_code=status.HTTP_304_NOT_MODIFIED,
content=dict(completed=False, lang=self.lang, **self.response)
content=dict(completed=False, **self.response, lang=self.lang),
)

View File

@ -1,9 +1,17 @@
from Services.Redis.Actions.actions import RedisActions
from ApiLayers.AllConfigs.Redis.configs import RedisValidationKeys
class HTTPExceptionApi(Exception):
def __init__(self, error_code: str, lang: str, loc: str = "", sys_msg: str = ""):
"""
Initialize the HTTPExceptionApi class.
:param error_code: The error code. To retrieve the error message.
:param lang: The language. Catch error msg from redis.
:param loc: The location. To log where error occurred.
:param sys_msg: The system message. To log the error message.
"""
self.error_code = error_code
self.lang = lang
self.loc = loc
@ -13,6 +21,12 @@ class HTTPExceptionApi(Exception):
"""
Retrieve the error message from the redis by the error code.
"""
error_msg = RedisActions.get_json(list_keys=["LANGUAGE_MODELS", "ERRORCODES", self.lang])
if error_msg.status:
return error_msg.first
error_redis_key = (
f"{RedisValidationKeys.LANGUAGE_MODELS}:{RedisValidationKeys.ERRORCODES}"
)
error_message = RedisActions.get_json(list_keys=[error_redis_key, self.lang])
if error_message.status:
error_message_dict = error_message.first.as_dict
if error_message_dict.get(self.error_code, None):
return error_message_dict.get(self.error_code)
return f"System Message -> {self.sys_msg}"

View File

@ -1,4 +1,6 @@
from ApiLayers.LanguageModels.Database.Mixins.crud_mixin import CrudCollectionLanguageModel
from ApiLayers.LanguageModels.Database.Mixins.crud_mixin import (
CrudCollectionLanguageModel,
)
AccountBooksLanguageModel = dict(
tr={

View File

@ -1,4 +1,6 @@
from ApiLayers.LanguageModels.Database.Mixins.crud_mixin import CrudCollectionLanguageModel
from ApiLayers.LanguageModels.Database.Mixins.crud_mixin import (
CrudCollectionLanguageModel,
)
BuildIbansLanguageModel = dict(
tr={

View File

@ -1,4 +1,6 @@
from ApiLayers.LanguageModels.Database.Mixins.crud_mixin import CrudCollectionLanguageModel
from ApiLayers.LanguageModels.Database.Mixins.crud_mixin import (
CrudCollectionLanguageModel,
)
DecisionBookBudgetBooksLanguageModel = dict(
tr={

View File

@ -1,4 +1,6 @@
from ApiLayers.LanguageModels.Database.Mixins.crud_mixin import CrudCollectionLanguageModel
from ApiLayers.LanguageModels.Database.Mixins.crud_mixin import (
CrudCollectionLanguageModel,
)
BuildTypesLanguageModel = dict(
tr={

View File

@ -1,4 +1,6 @@
from ApiLayers.LanguageModels.Database.Mixins.crud_mixin import CrudCollectionLanguageModel
from ApiLayers.LanguageModels.Database.Mixins.crud_mixin import (
CrudCollectionLanguageModel,
)
BuildDecisionBookLanguageModel = dict(
tr={

View File

@ -1,4 +1,6 @@
from ApiLayers.LanguageModels.Database.Mixins.crud_mixin import CrudCollectionLanguageModel
from ApiLayers.LanguageModels.Database.Mixins.crud_mixin import (
CrudCollectionLanguageModel,
)
RelationshipDutyCompanyLanguageModel = dict(
tr={

View File

@ -1,4 +1,6 @@
from ApiLayers.LanguageModels.Database.Mixins.crud_mixin import CrudCollectionLanguageModel
from ApiLayers.LanguageModels.Database.Mixins.crud_mixin import (
CrudCollectionLanguageModel,
)
DepartmentsLanguageModel = dict(
tr={

View File

@ -1,4 +1,6 @@
from ApiLayers.LanguageModels.Database.Mixins.crud_mixin import CrudCollectionLanguageModel
from ApiLayers.LanguageModels.Database.Mixins.crud_mixin import (
CrudCollectionLanguageModel,
)
StaffLanguageModel = dict(
tr={

View File

@ -1,4 +1,6 @@
from ApiLayers.LanguageModels.Database.Mixins.crud_mixin import CrudCollectionLanguageModel
from ApiLayers.LanguageModels.Database.Mixins.crud_mixin import (
CrudCollectionLanguageModel,
)
EventsLanguageModel = dict(

View File

@ -1,4 +1,6 @@
from ApiLayers.LanguageModels.Database.Mixins.crud_mixin import CrudCollectionLanguageModel
from ApiLayers.LanguageModels.Database.Mixins.crud_mixin import (
CrudCollectionLanguageModel,
)
UsersTokensLanguageModel = dict(
tr={

View File

@ -1,4 +1,6 @@
from ApiLayers.LanguageModels.Database.Mixins.crud_mixin import CrudCollectionLanguageModel
from ApiLayers.LanguageModels.Database.Mixins.crud_mixin import (
CrudCollectionLanguageModel,
)
EndpointRestrictionLanguageModel = dict(
tr={

View File

@ -1,3 +0,0 @@
from .merge_all_error_languages import MergedErrorLanguageModels
__all__ = ["MergedErrorLanguageModels"]

View File

@ -92,11 +92,12 @@ class MiddlewareModule:
auth_context = AuthContext(
auth={"token": {"access_token": "", "refresher_token": "", "context": {}}},
url=endpoint_url,
request=request,
)
# Set auth context on the wrapper function itself
setattr(func, 'auth_context', auth_context)
setattr(wrapper, 'auth_context', auth_context)
setattr(func, "auth_context", auth_context)
setattr(wrapper, "auth_context", auth_context)
# Call the original endpoint function
if inspect.iscoroutinefunction(func):
@ -105,10 +106,11 @@ class MiddlewareModule:
result = func(request, *args, **kwargs)
# Set auth context on the wrapper function itself
setattr(func, 'auth_context', auth_context)
setattr(wrapper, 'auth_context', auth_context)
setattr(func, "auth_context", auth_context)
setattr(wrapper, "auth_context", auth_context)
return result
return wrapper

View File

@ -52,11 +52,17 @@ class TokenEventMiddleware:
)
# Get token context from Redis by access token and collect reachable event codes
token_context = TokenService.get_object_via_access_key(access_token=access_token)
token_context = TokenService.get_object_via_access_key(
access_token=access_token
)
if token_context.is_employee:
reachable_event_codes: list[str] = token_context.selected_company.reachable_event_codes
reachable_event_codes: list[str] = (
token_context.selected_company.reachable_event_codes
)
elif token_context.is_occupant:
reachable_event_codes: list[str] = token_context.selected_occupant.reachable_event_codes
reachable_event_codes: list[str] = (
token_context.selected_occupant.reachable_event_codes
)
else:
raise HTTPExceptionApi(
error_code="",
@ -67,12 +73,15 @@ class TokenEventMiddleware:
return token_context, reachable_event_codes
@staticmethod
def retrieve_intersected_event_code(request: Request, reachable_event_codes: list[str]) -> str:
def retrieve_intersected_event_code(
request: Request, reachable_event_codes: list[str]
) -> str:
"""
Match an endpoint with accessible events.
Args:
request: The endpoint to match
reachable_event_codes: The list of event codes accessible to the user
Returns:
Dict containing the endpoint registration data
@ -81,9 +90,7 @@ class TokenEventMiddleware:
endpoint_url = str(request.url.path)
# Get the endpoint URL for matching with events
function_codes_of_endpoint = RedisActions.get_json(
list_keys=[
RedisCategoryKeys.METHOD_FUNCTION_CODES, "*", endpoint_url
]
list_keys=[RedisCategoryKeys.METHOD_FUNCTION_CODES, "*", endpoint_url]
)
function_code_list_of_event = function_codes_of_endpoint.first
if not function_codes_of_endpoint.status:
@ -95,7 +102,9 @@ class TokenEventMiddleware:
)
# Intersect function codes with user accers objects available event codes
intersected_code = list(set(function_code_list_of_event) & set(reachable_event_codes))
intersected_code = list(
set(function_code_list_of_event) & set(reachable_event_codes)
)
if not len(intersected_code) == 1:
raise HTTPExceptionApi(
error_code="",
@ -125,14 +134,19 @@ class TokenEventMiddleware:
# Get and validate token context from request
# token_context, reachable_event_codes = cls.retrieve_access_content(request)
token_context, reachable_event_codes = {"token": "context", "context": {}}, ["g1j8i6j7-9k4h-0h6l-4i3j-2j0k1k0j0i0k"]
endpoint_url, reachable_event_code = cls.retrieve_intersected_event_code(request, reachable_event_codes)
event_context = EventContext(auth=token_context, code=reachable_event_code, url=endpoint_url)
reachable_event_codes = ["g1j8i6j7-9k4h-0h6l-4i3j-2j0k1k0j0i0k"]
token_context = {"token": "context","context": {}}
endpoint_url, reachable_event_code = cls.retrieve_intersected_event_code(
request, reachable_event_codes
)
event_context = EventContext(
auth=token_context, code=reachable_event_code, url=endpoint_url, request=request,
)
# Get auth context from the authenticated function's wrapper
if token_context is not None:
setattr(wrapper, 'event_context', event_context)
setattr(func, 'event_context', event_context)
setattr(wrapper, "event_context", event_context)
setattr(func, "event_context", event_context)
# Execute the authenticated function and get its result
if inspect.iscoroutinefunction(func):

View File

@ -24,7 +24,10 @@ from ApiLayers.ApiValidations.Request import (
UpdateBuild,
)
from ApiLayers.ApiValidations.Custom.token_objects import EmployeeTokenObject, OccupantTokenObject
from ApiLayers.ApiValidations.Custom.token_objects import (
EmployeeTokenObject,
OccupantTokenObject,
)
from ApiLayers.LanguageModels.Database.building.build import (
BuildTypesLanguageModel,
Part2EmployeeLanguageModel,

View File

@ -17,7 +17,10 @@ from sqlalchemy import (
from sqlalchemy.orm import mapped_column, relationship, Mapped
from ApiLayers.ApiLibrary.date_time_actions.date_functions import system_arrow
from ApiLayers.ApiLibrary.extensions.select import SelectAction, SelectActionWithEmployee
from ApiLayers.ApiLibrary.extensions.select import (
SelectAction,
SelectActionWithEmployee,
)
from ApiLayers.AllConfigs.Token.config import Auth
from ApiLayers.ApiServices.Login.user_login_handler import UserLoginModule
@ -138,6 +141,24 @@ class Users(CrudCollection, UserLoginModule, SelectAction):
def is_employee(self):
return str(self.email).split("@")[1] == Auth.ACCESS_EMAIL_EXT
@property
def user_type(self):
return "Occupant" if self.is_occupant else "Employee"
@classmethod
def credentials(cls):
db_session = cls.new_session()
person_object: People = People.filter_by_one(db=db_session, system=True, id=cls.person_id).data
if person_object:
return {
"person_id": person_object.id,
"person_uu_id": str(person_object.uu_id),
}
return {
"person_id": None,
"person_uu_id": None,
}
@property
def password_expiry_ends(self):
"""Calculates the expiry end date based on expiry begins and expires day"""
@ -153,16 +174,6 @@ class Users(CrudCollection, UserLoginModule, SelectAction):
)
)
@property
def is_super_user(self):
"""Checks if the user is a superuser based on priority code"""
return getattr(self.priority, "priority_code", 0) == 78
@property
def is_user(self):
"""Checks if the user is a regular user based on priority code"""
return getattr(self.priority, "priority_code", 0) == 0
@classmethod
def create_action(cls, create_user: InsertUsers, token_dict):
db_session = cls.new_session()
@ -192,21 +203,7 @@ class Users(CrudCollection, UserLoginModule, SelectAction):
created_user.reset_password_token(found_user=created_user)
return created_user
@classmethod
def credentials(cls):
db_session = cls.new_session()
person_object = People.filter_by_one(
db=db_session, system=True, id=cls.person_id
).data
if person_object:
return {
"person_id": person_object.id,
"person_uu_id": str(person_object.uu_id),
}
return {
"person_id": None,
"person_uu_id": None,
}
def get_employee_and_duty_details(self):
from Schemas import Employees, Duties

View File

@ -1,7 +1,9 @@
from sqlalchemy import String
from sqlalchemy.orm import mapped_column, Mapped
from ApiLayers.LanguageModels.Database.rules.rules import EndpointRestrictionLanguageModel
from ApiLayers.LanguageModels.Database.rules.rules import (
EndpointRestrictionLanguageModel,
)
from Services.PostgresDb import CrudCollection

View File

@ -12,7 +12,10 @@ from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse
from ApiLayers.ErrorHandlers.Exceptions.api_exc import HTTPExceptionApi
from ApiLayers.Middleware.auth_middleware import RequestTimingMiddleware, LoggerTimingMiddleware
from ApiLayers.Middleware.auth_middleware import (
RequestTimingMiddleware,
LoggerTimingMiddleware,
)
def setup_cors_middleware(app: FastAPI) -> None:
@ -55,7 +58,9 @@ def setup_exception_handlers(app: FastAPI) -> None:
Args:
app: FastAPI application instance
"""
from ApiLayers.ErrorHandlers.ErrorHandlers.api_exc_handler import HTTPExceptionApiHandler
from ApiLayers.ErrorHandlers.ErrorHandlers.api_exc_handler import (
HTTPExceptionApiHandler,
)
custom_exception_handler = HTTPExceptionApiHandler(response_model=JSONResponse)
app.add_exception_handler(

View File

@ -1,4 +1,3 @@
class DefaultApiConfig:
app: str
host: str
@ -41,7 +40,9 @@ class ApiConfig(DefaultApiConfig):
# Application Information
APP_NAME = "evyos-auth-api-gateway"
TITLE = "WAG API Auth Api Gateway"
DESCRIPTION = "This api is serves as web auth api gateway only to evyos web services."
DESCRIPTION = (
"This api is serves as web auth api gateway only to evyos web services."
)
APP_URL = "https://www.auth.eys.gen.tr"
# Server Configuration

View File

@ -2,10 +2,15 @@
Route configuration and factory module.
Handles dynamic route creation based on configurations.
"""
from typing import Optional
from Events.Engine.set_defaults.run import get_cluster_controller_group
from Events.Engine.set_defaults.setClusters import PrepareRouting, SetItems2Redis, PrepareEvents
from Events.Engine.set_defaults.setClusters import (
PrepareRouting,
SetItems2Redis,
PrepareEvents,
)
routers: Optional[PrepareRouting] = None

View File

@ -32,7 +32,11 @@ class OpenAPISchemaCreator:
"""
self.app = app
self.cluster = get_all_routers()
self.safe_endpoint_list = self.cluster.safe_endpoints if hasattr(self.cluster, 'safe_endpoints') else []
self.safe_endpoint_list = (
self.cluster.safe_endpoints
if hasattr(self.cluster, "safe_endpoints")
else []
)
def _create_security_schemes(self) -> Dict[str, Any]:
"""
@ -42,6 +46,7 @@ class OpenAPISchemaCreator:
Dict[str, Any]: Security scheme configurations
"""
from ApiLayers.AllConfigs.Token.config import Auth
return {
"BearerAuth": {
"type": "apiKey",
@ -191,12 +196,12 @@ class OpenAPISchemaCreator:
# Check if endpoint is in safe list
endpoint_path = f"{path}:{method}"
if endpoint_path not in [f"{e.URL}:{e.METHOD.lower()}" for e in self.safe_endpoint_list]:
if endpoint_path not in [
f"{e.URL}:{e.METHOD.lower()}" for e in self.safe_endpoint_list
]:
if "security" not in schema["paths"][path][method]:
schema["paths"][path][method]["security"] = []
schema["paths"][path][method]["security"].append(
{"BearerAuth": []}
)
schema["paths"][path][method]["security"].append({"BearerAuth": []})
def create_schema(self) -> Dict[str, Any]:
"""
@ -216,7 +221,9 @@ class OpenAPISchemaCreator:
if "components" not in openapi_schema:
openapi_schema["components"] = {}
openapi_schema["components"]["securitySchemes"] = self._create_security_schemes()
openapi_schema["components"][
"securitySchemes"
] = self._create_security_schemes()
# Configure route security and responses
for route in self.app.routes:

View File

@ -12,7 +12,10 @@ from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse
from ApiLayers.ErrorHandlers.Exceptions.api_exc import HTTPExceptionApi
from ApiLayers.Middleware.auth_middleware import RequestTimingMiddleware, LoggerTimingMiddleware
from ApiLayers.Middleware.auth_middleware import (
RequestTimingMiddleware,
LoggerTimingMiddleware,
)
def setup_cors_middleware(app: FastAPI) -> None:
@ -55,7 +58,9 @@ def setup_exception_handlers(app: FastAPI) -> None:
Args:
app: FastAPI application instance
"""
from ApiLayers.ErrorHandlers.ErrorHandlers.api_exc_handler import HTTPExceptionApiHandler
from ApiLayers.ErrorHandlers.ErrorHandlers.api_exc_handler import (
HTTPExceptionApiHandler,
)
custom_exception_handler = HTTPExceptionApiHandler(response_model=JSONResponse)
app.add_exception_handler(

View File

@ -1,4 +1,3 @@
class DefaultApiConfig:
app: str
host: str
@ -32,12 +31,13 @@ class ApiStatic:
return cls.BLACKLIST_LINK + record_id
class ApiConfig(DefaultApiConfig):
# Api configuration
APP_NAME = "evyos-event-api-gateway"
TITLE = "WAG API Event Api Gateway"
DESCRIPTION = "This api is serves as web event api gateway only to evyos web services."
DESCRIPTION = (
"This api is serves as web event api gateway only to evyos web services."
)
APP_URL = "https://www.event.eys.gen.tr"
# Uvicorn server configuration
@ -57,4 +57,3 @@ class MainConfig:
DEFAULT_TIMEZONE = "GMT+3" # Default timezone for the application
SYSTEM_TIMEZONE = "GMT+0" # System timezone (used for internal operations)
SUPPORTED_TIMEZONES = ["GMT+0", "GMT+3"] # List of supported timezones

View File

@ -5,7 +5,11 @@ Handles dynamic route creation based on configurations.
from fastapi import Request
from Events.Engine.set_defaults.run import get_cluster_controller_group
from Events.Engine.set_defaults.setClusters import PrepareRouting, SetItems2Redis, PrepareEvents
from Events.Engine.set_defaults.setClusters import (
PrepareRouting,
SetItems2Redis,
PrepareEvents,
)
routers = None

View File

@ -32,7 +32,11 @@ class OpenAPISchemaCreator:
"""
self.app = app
self.cluster = get_all_routers()
self.safe_endpoint_list = self.cluster.safe_endpoints if hasattr(self.cluster, 'safe_endpoints') else []
self.safe_endpoint_list = (
self.cluster.safe_endpoints
if hasattr(self.cluster, "safe_endpoints")
else []
)
def _create_security_schemes(self) -> Dict[str, Any]:
"""
@ -42,6 +46,7 @@ class OpenAPISchemaCreator:
Dict[str, Any]: Security scheme configurations
"""
from ApiLayers.AllConfigs.Token.config import Auth
return {
"BearerAuth": {
"type": "apiKey",
@ -191,12 +196,12 @@ class OpenAPISchemaCreator:
# Check if endpoint is in safe list
endpoint_path = f"{path}:{method}"
if endpoint_path not in [f"{e.URL}:{e.METHOD.lower()}" for e in self.safe_endpoint_list]:
if endpoint_path not in [
f"{e.URL}:{e.METHOD.lower()}" for e in self.safe_endpoint_list
]:
if "security" not in schema["paths"][path][method]:
schema["paths"][path][method]["security"] = []
schema["paths"][path][method]["security"].append(
{"BearerAuth": []}
)
schema["paths"][path][method]["security"].append({"BearerAuth": []})
def create_schema(self) -> Dict[str, Any]:
"""
@ -216,7 +221,9 @@ class OpenAPISchemaCreator:
if "components" not in openapi_schema:
openapi_schema["components"] = {}
openapi_schema["components"]["securitySchemes"] = self._create_security_schemes()
openapi_schema["components"][
"securitySchemes"
] = self._create_security_schemes()
# Configure route security and responses
for route in self.app.routes:

View File

@ -12,7 +12,10 @@ from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse
from ApiLayers.ErrorHandlers.Exceptions.api_exc import HTTPExceptionApi
from ApiLayers.Middleware.auth_middleware import RequestTimingMiddleware, LoggerTimingMiddleware
from ApiLayers.Middleware.auth_middleware import (
RequestTimingMiddleware,
LoggerTimingMiddleware,
)
def setup_cors_middleware(app: FastAPI) -> None:
@ -55,7 +58,9 @@ def setup_exception_handlers(app: FastAPI) -> None:
Args:
app: FastAPI application instance
"""
from ApiLayers.ErrorHandlers.ErrorHandlers.api_exc_handler import HTTPExceptionApiHandler
from ApiLayers.ErrorHandlers.ErrorHandlers.api_exc_handler import (
HTTPExceptionApiHandler,
)
custom_exception_handler = HTTPExceptionApiHandler(response_model=JSONResponse)
app.add_exception_handler(

View File

@ -1,4 +1,3 @@
class DefaultApiConfig:
app: str
host: str
@ -36,7 +35,9 @@ class ApiConfig(DefaultApiConfig):
# Api configuration
APP_NAME = "evyos-validation-api-gateway"
TITLE = "WAG API Validation Api Gateway"
DESCRIPTION = "This api is serves as web validation api gateway only to evyos web services."
DESCRIPTION = (
"This api is serves as web validation api gateway only to evyos web services."
)
APP_URL = "https://www.validation.eys.gen.tr"
# App configuration
app = "app:app"
@ -55,4 +56,3 @@ class MainConfig:
DEFAULT_TIMEZONE = "GMT+3" # Default timezone for the application
SYSTEM_TIMEZONE = "GMT+0" # System timezone (used for internal operations)
SUPPORTED_TIMEZONES = ["GMT+0", "GMT+3"] # List of supported timezones

View File

@ -29,5 +29,3 @@ def get_all_routers() -> PrepareRouting:
cluster_list = get_cluster_controller_group()
prepare_routing = PrepareRouting(cluster_controller_group=cluster_list)
return prepare_routing

View File

@ -32,7 +32,11 @@ class OpenAPISchemaCreator:
"""
self.app = app
self.cluster = get_all_routers()
self.safe_endpoint_list = self.cluster.safe_endpoints if hasattr(self.cluster, 'safe_endpoints') else []
self.safe_endpoint_list = (
self.cluster.safe_endpoints
if hasattr(self.cluster, "safe_endpoints")
else []
)
def _create_security_schemes(self) -> Dict[str, Any]:
"""
@ -42,6 +46,7 @@ class OpenAPISchemaCreator:
Dict[str, Any]: Security scheme configurations
"""
from ApiLayers.AllConfigs.Token.config import Auth
return {
"BearerAuth": {
"type": "apiKey",
@ -191,12 +196,12 @@ class OpenAPISchemaCreator:
# Check if endpoint is in safe list
endpoint_path = f"{path}:{method}"
if endpoint_path not in [f"{e.URL}:{e.METHOD.lower()}" for e in self.safe_endpoint_list]:
if endpoint_path not in [
f"{e.URL}:{e.METHOD.lower()}" for e in self.safe_endpoint_list
]:
if "security" not in schema["paths"][path][method]:
schema["paths"][path][method]["security"] = []
schema["paths"][path][method]["security"].append(
{"BearerAuth": []}
)
schema["paths"][path][method]["security"].append({"BearerAuth": []})
def create_schema(self) -> Dict[str, Any]:
"""
@ -216,7 +221,9 @@ class OpenAPISchemaCreator:
if "components" not in openapi_schema:
openapi_schema["components"] = {}
openapi_schema["components"]["securitySchemes"] = self._create_security_schemes()
openapi_schema["components"][
"securitySchemes"
] = self._create_security_schemes()
# Configure route security and responses
for route in self.app.routes:

View File

@ -1,56 +1,39 @@
from Events.Engine.abstract_class import Event
from .models import (
LoginSuperUserRequestModel,
LoginSuperUserResponseModel,
SelectCompanyOrOccupantTypeSuperUserRequestModel,
SelectCompanyOrOccupantTypeSuperUserResponseModel,
EmployeeSelectionSuperUserRequestModel,
EmployeeSelectionSuperUserResponseModel,
OccupantSelectionSuperUserRequestModel,
OccupantSelectionSuperUserResponseModel,
)
from .function_handlers import (
authentication_login_with_domain_and_creds,
authentication_select_company_or_occupant_type,
authentication_check_token_is_valid,
authentication_refresh_user_info,
authentication_change_password,
authentication_create_password,
authentication_disconnect_user,
authentication_logout_user,
authentication_refresher_token,
authentication_forgot_password,
authentication_reset_password,
authentication_download_avatar,
)
from .models import AuthenticationRequestModels, AuthenticationResponseModels
from .function_handlers import AuthenticationFunctions
# Auth Login
authentication_login_super_user_event = Event(
name="authentication_login_super_user_event",
key="a5d2d0d1-3e9b-4b0f-8c7d-6d4a4b4c4d4e",
request_validator=LoginSuperUserRequestModel,
request_validator=AuthenticationRequestModels.LoginSuperUserRequestModel,
# response_validator=LoginSuperUserResponseModel,
description="Login super user",
)
authentication_login_super_user_event.endpoint_callable = (
authentication_login_with_domain_and_creds
AuthenticationFunctions.authentication_login_with_domain_and_creds
)
# Auth Select Company or Occupant Type
authentication_select_company_or_occupant_type_super_user_event = Event(
name="authentication_select_company_or_occupant_type_super_user_event",
authentication_select_super_user_event = Event(
name="authentication_select_super_user_event",
key="a5d2d0d1-3e9b-4b0f-8c7d-6d4a4b4c4d4e",
request_validator=SelectCompanyOrOccupantTypeSuperUserRequestModel,
request_validator=AuthenticationRequestModels.SelectCompanyOrOccupantTypeSuperUserRequestModel,
# response_validator=SelectCompanyOrOccupantTypeSuperUserResponseModel,
description="Select company or occupant type super user",
)
authentication_select_company_or_occupant_type_super_user_event.endpoint_callable = (
authentication_select_company_or_occupant_type
authentication_select_super_user_event.endpoint_callable = (
AuthenticationFunctions.authentication_select_company_or_occupant_type
)
# Check Token Validity
authentication_check_token_event = Event(
name="authentication_check_token_event",
@ -59,7 +42,12 @@ authentication_check_token_event = Event(
# response_validator=None, # TODO: Add response validator
description="Check if token is valid",
)
authentication_check_token_event.endpoint_callable = authentication_check_token_is_valid
authentication_check_token_event.endpoint_callable = (
AuthenticationFunctions.authentication_check_token_is_valid
)
# Refresh User Info
authentication_refresh_user_info_event = Event(
@ -69,10 +57,13 @@ authentication_refresh_user_info_event = Event(
# response_validator=None, # TODO: Add response validator
description="Refresh user information",
)
authentication_refresh_user_info_event.endpoint_callable = (
authentication_refresh_user_info
AuthenticationFunctions.authentication_refresh_user_info
)
# Change Password
authentication_change_password_event = Event(
name="authentication_change_password_event",
@ -81,7 +72,12 @@ authentication_change_password_event = Event(
# response_validator=None, # TODO: Add response validator
description="Change user password",
)
authentication_change_password_event.endpoint_callable = authentication_change_password
authentication_change_password_event.endpoint_callable = (
AuthenticationFunctions.authentication_change_password
)
# Create Password
authentication_create_password_event = Event(
@ -91,7 +87,12 @@ authentication_create_password_event = Event(
# response_validator=None, # TODO: Add response validator
description="Create new password",
)
authentication_create_password_event.endpoint_callable = authentication_create_password
authentication_create_password_event.endpoint_callable = (
AuthenticationFunctions.authentication_create_password
)
# Disconnect User
authentication_disconnect_user_event = Event(
@ -101,7 +102,12 @@ authentication_disconnect_user_event = Event(
# response_validator=None, # TODO: Add response validator
description="Disconnect all user sessions",
)
authentication_disconnect_user_event.endpoint_callable = authentication_disconnect_user
authentication_disconnect_user_event.endpoint_callable = (
AuthenticationFunctions.authentication_disconnect_user
)
# Logout User
authentication_logout_user_event = Event(
@ -111,7 +117,12 @@ authentication_logout_user_event = Event(
# response_validator=None, # TODO: Add response validator
description="Logout user session",
)
authentication_logout_user_event.endpoint_callable = authentication_logout_user
authentication_logout_user_event.endpoint_callable = (
AuthenticationFunctions.authentication_logout_user
)
# Refresh Token
authentication_refresher_token_event = Event(
@ -121,7 +132,12 @@ authentication_refresher_token_event = Event(
# response_validator=None, # TODO: Add response validator
description="Refresh authentication token",
)
authentication_refresher_token_event.endpoint_callable = authentication_refresher_token
authentication_refresher_token_event.endpoint_callable = (
AuthenticationFunctions.authentication_refresher_token
)
# Forgot Password
authentication_forgot_password_event = Event(
@ -131,7 +147,12 @@ authentication_forgot_password_event = Event(
# response_validator=None, # TODO: Add response validator
description="Request password reset",
)
authentication_forgot_password_event.endpoint_callable = authentication_forgot_password
authentication_forgot_password_event.endpoint_callable = (
AuthenticationFunctions.authentication_forgot_password
)
# Reset Password
authentication_reset_password_event = Event(
@ -141,7 +162,12 @@ authentication_reset_password_event = Event(
# response_validator=None, # TODO: Add response validator
description="Reset user password",
)
authentication_reset_password_event.endpoint_callable = authentication_reset_password
authentication_reset_password_event.endpoint_callable = (
AuthenticationFunctions.authentication_reset_password
)
# Download Avatar
authentication_download_avatar_event = Event(
@ -151,4 +177,8 @@ authentication_download_avatar_event = Event(
# response_validator=None, # TODO: Add response validator
description="Download user avatar and profile info",
)
authentication_download_avatar_event.endpoint_callable = authentication_download_avatar
authentication_download_avatar_event.endpoint_callable = (
AuthenticationFunctions.authentication_download_avatar
)

View File

@ -1,19 +1,16 @@
"""
Authentication related API endpoints.
"""
from typing import Any, Dict
from fastapi import Request
from typing import Union, Any, Dict
from ApiLayers.ApiValidations.Custom.wrapper_contexts import AuthContext, EventContext
from ApiLayers.Middleware import MiddlewareModule, TokenEventMiddleware
from ApiLayers.ApiValidations.Request import EmployeeSelection, OccupantSelection
from ApiLayers.Middleware import MiddlewareModule
from Events.Engine.abstract_class import MethodToEvent
from Events.base_request_model import EndpointBaseRequestModel
from Events.base_request_model import EndpointBaseRequestModel, ContextRetrievers
from .api_events import (
authentication_login_super_user_event,
authentication_select_company_or_occupant_type_super_user_event,
authentication_select_super_user_event,
authentication_check_token_event,
authentication_refresh_user_info_event,
authentication_change_password_event,
@ -26,12 +23,6 @@ from .api_events import (
authentication_download_avatar_event,
)
from fastapi import Request
# Type aliases for common types
TokenDictType = Union["EmployeeTokenObject", "OccupantTokenObject"]
AuthenticationLoginEventMethods = MethodToEvent(
name="AuthenticationLoginEventMethods",
@ -48,20 +39,24 @@ AuthenticationLoginEventMethods = MethodToEvent(
def authentication_login_with_domain_and_creds_endpoint(
request: Request,
data: EndpointBaseRequestModel,
request: Request, data: EndpointBaseRequestModel,
) -> Dict[str, Any]:
event_2_catch = AuthenticationLoginEventMethods.retrieve_event(event_function_code=f"{authentication_login_super_user_event.key}")
event_2_catch = AuthenticationLoginEventMethods.retrieve_event(
event_function_code=f"{authentication_login_super_user_event.key}"
)
data = event_2_catch.REQUEST_VALIDATOR(**data.data)
return event_2_catch.endpoint_callable(request=request, data=data)
AuthenticationLoginEventMethods.endpoint_callable = authentication_login_with_domain_and_creds_endpoint
AuthenticationLoginEventMethods.endpoint_callable = (
authentication_login_with_domain_and_creds_endpoint
)
AuthenticationSelectEventMethods = MethodToEvent(
name="AuthenticationSelectEventMethods",
events={
authentication_select_company_or_occupant_type_super_user_event.key: authentication_select_company_or_occupant_type_super_user_event,
authentication_select_super_user_event.key: authentication_select_super_user_event,
},
decorators_list=[MiddlewareModule.auth_required],
headers=[],
@ -72,28 +67,27 @@ AuthenticationSelectEventMethods = MethodToEvent(
description="Select company or occupant type",
)
def authentication_select_company_or_occupant_type(
request: Request,
data: EndpointBaseRequestModel,
) -> Dict[str, Any]:
def authentication_select_company_or_occupant_type(data: EndpointBaseRequestModel) -> Dict[str, Any]:
"""
Select company or occupant type.
"""
auth_context = authentication_select_company_or_occupant_type.auth_context
context_retriever = ContextRetrievers(func=authentication_select_company_or_occupant_type)
function = AuthenticationSelectEventMethods.retrieve_event(
event_function_code=f"{authentication_select_company_or_occupant_type_super_user_event.key}"
event_function_code=f"{authentication_select_super_user_event.key}"
)
function.endpoint_callable.auth_context = auth_context
return function.endpoint_callable(request=request, data=data)
setattr(function.endpoint_callable, context_retriever.key, context_retriever.context)
return function.endpoint_callable(data=data)
AuthenticationSelectEventMethods.endpoint_callable = authentication_select_company_or_occupant_type
AuthenticationSelectEventMethods.endpoint_callable = (
authentication_select_company_or_occupant_type
)
AuthenticationCheckTokenEventMethods = MethodToEvent(
name="AuthenticationCheckTokenEventMethods",
events={
authentication_check_token_event.key: authentication_check_token_event
},
events={authentication_check_token_event.key: authentication_check_token_event},
headers=[],
errors=[],
decorators_list=[MiddlewareModule.auth_required],
@ -103,14 +97,20 @@ AuthenticationCheckTokenEventMethods = MethodToEvent(
description="Check if access token is valid for user",
)
def authentication_check_token_is_valid(request: Request):
def authentication_check_token_is_valid():
context_retriever = ContextRetrievers(func=authentication_check_token_is_valid)
function = AuthenticationCheckTokenEventMethods.retrieve_event(
event_function_code=f"{authentication_check_token_event.key}"
)
return function.endpoint_callable(request=request)
setattr(function.endpoint_callable, context_retriever.key, context_retriever.context)
return function.endpoint_callable()
AuthenticationCheckTokenEventMethods.endpoint_callable = authentication_check_token_is_valid
AuthenticationCheckTokenEventMethods.endpoint_callable = (
authentication_check_token_is_valid
)
AuthenticationRefreshEventMethods = MethodToEvent(
name="AuthenticationRefreshEventMethods",
@ -127,16 +127,18 @@ AuthenticationRefreshEventMethods = MethodToEvent(
)
def authentication_refresh_user_info(request: Request):
token_dict = authentication_refresh_user_info.auth
def authentication_refresh_user_info():
context_retriever = ContextRetrievers(func=authentication_refresh_user_info)
function = AuthenticationRefreshEventMethods.retrieve_event(
event_function_code=f"{authentication_refresh_user_info_event.key}"
)
return function.endpoint_callable(request=request, token_dict=token_dict)
setattr(function.endpoint_callable, context_retriever.key, context_retriever.context)
return function.endpoint_callable()
AuthenticationRefreshEventMethods.endpoint_callable = authentication_refresh_user_info
AuthenticationChangePasswordEventMethods = MethodToEvent(
name="AuthenticationChangePasswordEventMethods",
events={
@ -151,21 +153,23 @@ AuthenticationChangePasswordEventMethods = MethodToEvent(
description="Change password with access token",
)
def authentication_change_password_event_callable(request: Request, data: EndpointBaseRequestModel):
token_dict = authentication_change_password_event_callable.auth
def authentication_change_password_event_callable(data: EndpointBaseRequestModel):
context_retriever = ContextRetrievers(func=authentication_change_password_event_callable)
function = AuthenticationChangePasswordEventMethods.retrieve_event(
event_function_code=f"{authentication_change_password_event.key}"
)
return function.endpoint_callable(data=data, token_dict=token_dict)
setattr(function.endpoint_callable, context_retriever.key, context_retriever.context)
return function.endpoint_callable(data=data)
AuthenticationChangePasswordEventMethods.endpoint_callable = authentication_change_password_event_callable
AuthenticationChangePasswordEventMethods.endpoint_callable = (
authentication_change_password_event_callable
)
AuthenticationCreatePasswordEventMethods = MethodToEvent(
name="AuthenticationCreatePasswordEventMethods",
events={
authentication_create_password_event: authentication_create_password_event
},
events={authentication_create_password_event: authentication_create_password_event},
headers=[],
errors=[],
url="/create-password",
@ -174,14 +178,20 @@ AuthenticationCreatePasswordEventMethods = MethodToEvent(
description="Create password with password reset token requested via email",
)
def authentication_create_password(data: EndpointBaseRequestModel):
context_retriever = ContextRetrievers(func=authentication_create_password)
function = AuthenticationCreatePasswordEventMethods.retrieve_event(
event_function_code=f"{authentication_create_password_event.key}"
)
setattr(function.endpoint_callable, context_retriever.key, context_retriever.context)
return function.endpoint_callable(data=data)
AuthenticationCreatePasswordEventMethods.endpoint_callable = authentication_create_password
AuthenticationCreatePasswordEventMethods.endpoint_callable = (
authentication_create_password
)
AuthenticationDisconnectUserEventMethods = MethodToEvent(
name="AuthenticationDisconnectUserEventMethods",
@ -197,22 +207,22 @@ AuthenticationDisconnectUserEventMethods = MethodToEvent(
description="Disconnect all sessions of user in access token",
)
def authentication_disconnect_user(request: Request, data: EndpointBaseRequestModel):
token_dict = authentication_disconnect_user.auth
def authentication_disconnect_user(data: EndpointBaseRequestModel):
context_retriever = ContextRetrievers(func=authentication_disconnect_user)
function = AuthenticationDisconnectUserEventMethods.retrieve_event(
event_function_code=f"{authentication_disconnect_user_event.key}"
)
return function.endpoint_callable(data=data, token_dict=token_dict)
setattr(function.endpoint_callable, context_retriever.key, context_retriever.context)
return function.endpoint_callable(data=data)
AuthenticationLogoutEventMethods = MethodToEvent(
name="AuthenticationLogoutEventMethods",
events={
authentication_logout_user_event.key: authentication_logout_user_event
},
events={authentication_logout_user_event.key: authentication_logout_user_event},
headers=[],
errors=[],
decorators_list=[TokenEventMiddleware.event_required],
decorators_list=[MiddlewareModule.auth_required],
url="/logout",
method="POST",
summary="Logout user",
@ -220,12 +230,13 @@ AuthenticationLogoutEventMethods = MethodToEvent(
)
def authentication_logout_user(request: Request, data: EndpointBaseRequestModel):
event_context: EventContext = getattr(authentication_logout_user, "event_context", None)
print('event_context', event_context)
function = AuthenticationLogoutEventMethods.retrieve_event(event_function_code=f"{event_context.code}")
function.endpoint_callable.event_context = event_context
return function.endpoint_callable(request=request, data=data)
def authentication_logout_user(data: EndpointBaseRequestModel):
context_retriever = ContextRetrievers(func=authentication_logout_user)
function = AuthenticationLogoutEventMethods.retrieve_event(
event_function_code=f"{authentication_logout_user_event.key}"
)
setattr(function.endpoint_callable, context_retriever.key, context_retriever.context)
return function.endpoint_callable(data=data)
AuthenticationLogoutEventMethods.endpoint_callable = authentication_logout_user
@ -246,16 +257,18 @@ AuthenticationRefreshTokenEventMethods = MethodToEvent(
)
def authentication_refresher_token(request: Request, data: EndpointBaseRequestModel):
auth_context: AuthContext = getattr(authentication_refresher_token, "auth_context", None)
def authentication_refresher_token(data: EndpointBaseRequestModel):
context_retriever = ContextRetrievers(func=authentication_refresher_token)
function = AuthenticationRefreshTokenEventMethods.retrieve_event(
event_function_code=f"{authentication_refresher_token_event.key}"
)
function.endpoint_callable.auth_context = auth_context
return function.endpoint_callable(data=data, request=request)
setattr(function.endpoint_callable, context_retriever.key, context_retriever.context)
return function.endpoint_callable(data=data)
AuthenticationRefreshTokenEventMethods.endpoint_callable = authentication_refresher_token
AuthenticationRefreshTokenEventMethods.endpoint_callable = (
authentication_refresher_token
)
AuthenticationForgotPasswordEventMethods = MethodToEvent(
@ -272,15 +285,18 @@ AuthenticationForgotPasswordEventMethods = MethodToEvent(
)
def authentication_forgot_password(request: Request, data: EndpointBaseRequestModel):
token_dict = authentication_forgot_password.auth
def authentication_forgot_password(data: EndpointBaseRequestModel):
context_retriever = ContextRetrievers(func=authentication_forgot_password)
function = AuthenticationForgotPasswordEventMethods.retrieve_event(
event_function_code=f"{authentication_forgot_password_event.key}"
)
return function.endpoint_callable(data=data, token_dict=token_dict)
setattr(function.endpoint_callable, context_retriever.key, context_retriever.context)
return function.endpoint_callable(data=data)
AuthenticationForgotPasswordEventMethods.endpoint_callable = authentication_forgot_password
AuthenticationForgotPasswordEventMethods.endpoint_callable = (
authentication_forgot_password
)
AuthenticationResetPasswordEventMethods = MethodToEvent(
@ -299,14 +315,18 @@ AuthenticationResetPasswordEventMethods = MethodToEvent(
def authentication_reset_password(data: EndpointBaseRequestModel):
# token_dict = authentication_reset_password.auth
context_retriever = ContextRetrievers(func=authentication_reset_password)
function = AuthenticationResetPasswordEventMethods.retrieve_event(
event_function_code=f"{authentication_reset_password_event.key}"
)
setattr(function.endpoint_callable, context_retriever.key, context_retriever.context)
return function.endpoint_callable(data=data)
AuthenticationResetPasswordEventMethods.endpoint_callable = authentication_reset_password
AuthenticationResetPasswordEventMethods.endpoint_callable = (
authentication_reset_password
)
AuthenticationDownloadAvatarEventMethods = MethodToEvent(
name="AuthenticationDownloadAvatarEventMethods",
@ -315,7 +335,7 @@ AuthenticationDownloadAvatarEventMethods = MethodToEvent(
},
headers=[],
errors=[],
decorators_list=[],
decorators_list=[MiddlewareModule.auth_required],
url="/download-avatar",
method="POST",
summary="Download avatar",
@ -323,13 +343,15 @@ AuthenticationDownloadAvatarEventMethods = MethodToEvent(
)
@MiddlewareModule.auth_required
def authentication_download_avatar(request: Request):
token_dict = authentication_download_avatar.auth
def authentication_download_avatar():
context_retriever = ContextRetrievers(func=authentication_download_avatar)
function = AuthenticationDownloadAvatarEventMethods.retrieve_event(
event_function_code=f"{authentication_download_avatar_event.key}"
)
return function.endpoint_callable(token_dict=token_dict)
setattr(function.endpoint_callable, context_retriever.key, context_retriever.context)
return function.endpoint_callable()
AuthenticationDownloadAvatarEventMethods.endpoint_callable = authentication_download_avatar
AuthenticationDownloadAvatarEventMethods.endpoint_callable = (
authentication_download_avatar
)

View File

@ -1,11 +1,11 @@
from typing import Any, TYPE_CHECKING, Union, Dict
from typing import Any
from fastapi import Request
from ApiLayers.ApiLibrary.common.line_number import get_line_number_for_error
from ApiLayers.ApiServices.Login.user_login_handler import UserLoginModule
from ApiLayers.ApiServices.Token.token_handler import TokenService
from ApiLayers.ApiValidations.Custom.token_objects import CompanyToken, OccupantToken
from ApiLayers.ApiValidations.Custom.wrapper_contexts import AuthContext, EventContext
from ApiLayers.ApiValidations.Response.default_response import EndpointSuccessResponse
from ApiLayers.ErrorHandlers import HTTPExceptionApi
from ApiLayers.Schemas import (
BuildLivingSpace,
@ -22,63 +22,16 @@ from ApiLayers.Schemas import (
OccupantTypes,
Users,
)
from ApiLayers.ApiValidations.Response.default_response import EndpointSuccessResponse
from fastapi import Request
from Events.base_request_model import ContextRetrievers, TokenDictType
# Type aliases for common types
TokenDictType = Union["EmployeeTokenObject", "OccupantTokenObject"]
class Handlers:
"""Class for handling authentication functions"""
def authentication_login_with_domain_and_creds(request: Request, data: Any):
"""
Authenticate user with domain and credentials.
Args:
request: FastAPI request object
data: Request body containing login credentials
{
"domain": "evyos.com.tr",
"access_key": "karatay.berkay.sup@evyos.com.tr",
"password": "string",
"remember_me": false
}
Returns:
SuccessResponse containing authentication token and user info
"""
# Get token from login module
user_login_module = UserLoginModule(request=request)
token = user_login_module.login_user_via_credentials(access_data=data)
# Return response with token and headers
user_login_module.language = "tr"
success_response = EndpointSuccessResponse(
code="LoginSuccess", lang=user_login_module.language
)
return success_response.as_dict(
data={
"access_token": token.get("access_token"),
"refresh_token": token.get("refresher_token"),
"access_object": {"user_type": token.get("user_type"), "companies_list": token.get("companies_list")},
"user": token.get("user"),
}
)
# return {
# "completed": True,
# "message": "User is logged in successfully",
# "access_token": token.get("access_token"),
# "refresh_token": token.get("refresher_token"),
# "access_object": {
# "user_type": token.get("user_type"), "companies_list": token.get("companies_list")
# },
# "user": token.get("user"),
# }
def handle_employee_selection(request: Request, data: Any, token_dict: TokenDictType):
@classmethod # Requires no auth context
def handle_employee_selection(cls, request: Request, data: Any, token_dict: TokenDictType):
Users.set_user_define_properties(token=token_dict)
db_session = Users.new_session()
db = Users.new_session()
if data.company_uu_id not in token_dict.companies_uu_id_list:
raise HTTPExceptionApi(
error_code="HTTP_400_BAD_REQUEST",
@ -86,10 +39,10 @@ def handle_employee_selection(request: Request, data: Any, token_dict: TokenDict
loc=get_line_number_for_error(),
sys_msg="Company not found in token",
)
selected_company = Companies.filter_one(
selected_company: Companies = Companies.filter_one(
Companies.uu_id == data.company_uu_id,
db=db_session,
).first
db=db,
).data
if not selected_company:
raise HTTPExceptionApi(
error_code="HTTP_400_BAD_REQUEST",
@ -103,7 +56,7 @@ def handle_employee_selection(request: Request, data: Any, token_dict: TokenDict
dept.id
for dept in Departments.filter_all(
Departments.company_id == selected_company.id,
db=db_session,
db=db,
).data
]
@ -111,24 +64,22 @@ def handle_employee_selection(request: Request, data: Any, token_dict: TokenDict
duties_ids = [
duty.id
for duty in Duties.filter_all(
Duties.company_id == selected_company.id, db=db_session
Duties.company_id == selected_company.id, db=db
).data
]
# Get staff IDs
staff_ids = [
staff.id
for staff in Staff.filter_all(
Staff.duties_id.in_(duties_ids), db=db_session
).data
for staff in Staff.filter_all(Staff.duties_id.in_(duties_ids), db=db).data
]
# Get employee
employee = Employees.filter_one(
employee: Employees = Employees.filter_one(
Employees.people_id == token_dict.person_id,
Employees.staff_id.in_(staff_ids),
db=db_session,
).first
db=db,
).data
if not employee:
raise HTTPExceptionApi(
@ -145,20 +96,21 @@ def handle_employee_selection(request: Request, data: Any, token_dict: TokenDict
)
# Get staff and duties
staff = Staff.filter_one(Staff.id == employee.staff_id, db=db_session).data
duties = Duties.filter_one(Duties.id == staff.duties_id, db=db_session).data
staff = Staff.filter_one(Staff.id == employee.staff_id, db=db).data
duties = Duties.filter_one(Duties.id == staff.duties_id, db=db).data
department = Departments.filter_one(
Departments.id == duties.department_id, db=db_session
Departments.id == duties.department_id, db=db
).data
# Get bulk duty
bulk_id = Duty.filter_by_one(system=True, duty_code="BULK", db=db_session).data
bulk_id = Duty.filter_by_one(system=True, duty_code="BULK", db=db).data
bulk_duty_id = Duties.filter_by_one(
company_id=selected_company.id,
duties_id=bulk_id.id,
**Duties.valid_record_dict,
db=db_session,
db=db,
).data
# Create company token
company_token = CompanyToken(
company_uu_id=selected_company.uu_id.__str__(),
@ -175,11 +127,11 @@ def handle_employee_selection(request: Request, data: Any, token_dict: TokenDict
reachable_event_codes=reachable_event_codes,
reachable_event_endpoints=reachable_event_endpoints,
)
try: # Update Redis
update_token = TokenService.update_token_at_redis(
return TokenService.update_token_at_redis(
request=request, add_payload=company_token
)
return update_token
except Exception as e:
raise HTTPExceptionApi(
error_code="",
@ -188,12 +140,13 @@ def handle_employee_selection(request: Request, data: Any, token_dict: TokenDict
sys_msg=f"{e}",
)
def handle_occupant_selection(request: Request, data: Any, token_dict: TokenDictType):
@classmethod # Requires no auth context
def handle_occupant_selection(cls, request: Request, data: Any, token_dict: TokenDictType):
"""Handle occupant type selection"""
Users.set_user_define_properties(token=token_dict)
db = BuildLivingSpace.new_session()
# Get selected occupant type
selected_build_living_space = BuildLivingSpace.filter_one(
selected_build_living_space: BuildLivingSpace = BuildLivingSpace.filter_one(
BuildLivingSpace.uu_id == data.build_living_space_uu_id,
db=db,
).data
@ -212,7 +165,6 @@ def handle_occupant_selection(request: Request, data: Any, token_dict: TokenDict
reachable_event_endpoints = Event2Occupant.get_event_endpoints(
build_living_space_id=selected_build_living_space.id
)
occupant_type = OccupantTypes.filter_one(
OccupantTypes.id == selected_build_living_space.occupant_type_id,
db=db,
@ -260,10 +212,9 @@ def handle_occupant_selection(request: Request, data: Any, token_dict: TokenDict
)
try: # Update Redis
update_token = TokenService.update_token_at_redis(
return TokenService.update_token_at_redis(
request=request, add_payload=occupant_token
)
return update_token
except Exception as e:
raise HTTPExceptionApi(
error_code="",
@ -273,19 +224,59 @@ def handle_occupant_selection(request: Request, data: Any, token_dict: TokenDict
)
def authentication_select_company_or_occupant_type(request: Request, data: Any):
class AuthenticationFunctions:
"""Class for handling authentication functions"""
@classmethod # Requires auth context
def authentication_select_company_or_occupant_type(cls, data: Any):
"""Handle selection of company or occupant type"""
token_dict: TokenDictType = authentication_select_company_or_occupant_type.auth_context
if token_dict.is_employee:
if handle_employee_selection(data, token_dict, request):
return {"selected_occupant": None, "selected_company": data.company_uu_id}
elif token_dict.is_occupant:
if handle_occupant_selection(data, token_dict, request):
return {"selected_company": None, "selected_occupant": data.build_living_space_uu_id}
return {"completed": False, "selected_company": None, "selected_occupant": None}
context_retriever = ContextRetrievers(func=cls.authentication_select_company_or_occupant_type)
if context_retriever.token.is_employee:
if Handlers.handle_employee_selection(
request=context_retriever.request, data=data, token_dict=context_retriever.token
):
return {
"completed": True, "selected": data.company_uu_id, **context_retriever.base,
}
elif context_retriever.token.is_occupant:
if Handlers.handle_occupant_selection(
request=context_retriever.request, data=data, token_dict=context_retriever.token
):
return {
"completed": True, "selected": data.build_living_space_uu_id, **context_retriever.base,
}
return {"completed": False, "selected": None, **context_retriever.base}
@classmethod # Requires no auth context
def authentication_login_with_domain_and_creds(cls, request: Request, data: Any):
"""
Authenticate user with domain and credentials.
def authentication_check_token_is_valid(request: Request, data: Any):
Args:
request: FastAPI request object
data: Request body containing login credentials
{
"domain": "evyos.com.tr",
"access_key": "karatay.berkay.sup@evyos.com.tr",
"password": "string",
"remember_me": false
}
Returns:
SuccessResponse containing authentication token and user info
"""
# Get token from login module
user_login_module = UserLoginModule(request=request)
user_login_module.login_user_via_credentials(access_data=data)
user_login_module.language = "tr"
# Return response with token and headers
return EndpointSuccessResponse(
code="LOGIN_SUCCESS", lang=user_login_module.language
).as_dict(data=user_login_module.as_dict)
@classmethod # Requires not auth context
def authentication_check_token_is_valid(cls, data: Any):
"""Check if token is valid for user"""
# try:
# if RedisActions.get_object_via_access_key(request=request):
@ -294,8 +285,8 @@ def authentication_check_token_is_valid(request: Request, data: Any):
# return ResponseHandler.unauthorized("Access Token is NOT valid")
return
def authentication_refresh_user_info(request: Request, token_dict: TokenDictType, data: Any):
@classmethod # Requires not auth context
def authentication_refresh_user_info(cls, data: Any):
"""Refresh user info using access token"""
# try:
# access_token = request.headers.get(Auth.ACCESS_TOKEN_TAG)
@ -323,8 +314,8 @@ def authentication_refresh_user_info(request: Request, token_dict: TokenDictType
# return ResponseHandler.error(str(e))
return
def authentication_change_password(request: Request, token_dict: TokenDictType, data: Any):
@classmethod # Requires no auth context
def authentication_change_password(cls, data: Any):
"""Change password with access token"""
# try:
# if not isinstance(token_dict, EmployeeTokenObject):
@ -343,8 +334,8 @@ def authentication_change_password(request: Request, token_dict: TokenDictType,
# return ResponseHandler.error(str(e))
return
def authentication_create_password(request: Request, data: Any):
@classmethod # Requires not auth context
def authentication_create_password(cls, data: Any):
"""Create password with password reset token requested via email"""
# if not data.re_password == data.password:
# raise HTTPException(status_code=status.HTTP_406_NOT_ACCEPTABLE, detail="Password must match")
@ -356,8 +347,8 @@ def authentication_create_password(request: Request, data: Any):
# return ResponseHandler.not_found("Record not found")
return
def authentication_disconnect_user(request: Request, token_dict: TokenDictType, data: Any):
@classmethod # Requires auth context
def authentication_disconnect_user(cls, data: Any):
"""Disconnect all sessions of user in access token"""
# found_user = Users.filter_one(Users.uu_id == token_dict.user_uu_id).data
# if not found_user:
@ -371,8 +362,8 @@ def authentication_disconnect_user(request: Request, token_dict: TokenDictType,
# return ResponseHandler.not_found("Invalid data")
return
def authentication_logout_user(request: Request, data: Any):
@classmethod # Requires auth context
def authentication_logout_user(cls, data: Any):
"""Logout only single session of user which domain is provided"""
# token_user = None
# if already_tokens := RedisActions.get_object_via_access_key(request=request):
@ -384,12 +375,11 @@ def authentication_logout_user(request: Request, data: Any):
# selected_user.remove_refresher_token(domain=data.domain)
# return ResponseHandler.success("Session is logged out", data=token_user)
# return ResponseHandler.not_found("Logout is not successfully completed")
context_retriever = ContextRetrievers(func=cls.authentication_logout_user)
return context_retriever.base
event_context: EventContext = getattr(authentication_logout_user, "event_context", None)
return event_context.model_dump()
def authentication_refresher_token(request: Request, data: Any):
@classmethod # Requires not auth context
def authentication_refresher_token(cls, data: Any):
"""Refresh access token with refresher token"""
# token_refresher = UsersTokens.filter_by_one(
# token=data.refresh_token,
@ -412,11 +402,11 @@ def authentication_refresher_token(request: Request, data: Any):
# }
# return ResponseHandler.success("User is logged in successfully via refresher token", data=response_data)
# return ResponseHandler.not_found("Invalid data")
auth_context: AuthContext = getattr(authentication_refresher_token, "auth_context", None)
return auth_context.model_dump()
context_retriever = ContextRetrievers(func=cls.authentication_refresher_token)
return context_retriever.base
def authentication_forgot_password(request: Request, data: Any):
@classmethod # Requires not auth context
def authentication_forgot_password(cls, data: Any):
"""Send an email to user for a valid password reset token"""
# found_user: Users = Users.check_user_exits(access_key=data.access_key, domain=data.domain)
# forgot_key = AuthActions.save_access_token_to_redis(request=request, found_user=found_user, domain=data.domain)
@ -434,8 +424,8 @@ def authentication_forgot_password(request: Request, data: Any):
# return ResponseHandler.success("Password is change link is sent to your email or phone", data={})
return
def authentication_reset_password(request: Request, data: Any):
@classmethod # Requires not auth context
def authentication_reset_password(cls, data: Any):
"""Reset password with forgot password token"""
# from sqlalchemy import or_
# found_user = Users.query.filter(
@ -463,8 +453,8 @@ def authentication_reset_password(request: Request, data: Any):
# return ResponseHandler.success("Password change link is sent to your email or phone", data=found_user.get_dict())
return
def authentication_download_avatar(request: Request, data: Any, token_dict: TokenDictType):
@classmethod # Requires not auth context
def authentication_download_avatar(cls, data: Any):
"""Download avatar icon and profile info of user"""
# if found_user := Users.filter_one(Users.id == token_dict.user_id).data:
# expired_starts = str(system_arrow.now() - system_arrow.get(str(found_user.expiry_ends)))

View File

@ -1,7 +1,6 @@
from pydantic import BaseModel
from ApiLayers.ApiValidations.Request import (
Login,
)
from ApiLayers.ApiValidations.Request import Login
class LoginSuperUserRequestModel(Login):
pass
@ -33,3 +32,21 @@ class OccupantSelectionSuperUserRequestModel(BaseModel):
class OccupantSelectionSuperUserResponseModel(BaseModel):
pass
class AuthenticationRequestModels:
LoginSuperUserRequestModel = LoginSuperUserRequestModel
SelectCompanyOrOccupantTypeSuperUserRequestModel = (
SelectCompanyOrOccupantTypeSuperUserRequestModel
)
EmployeeSelectionSuperUserRequestModel = EmployeeSelectionSuperUserRequestModel
OccupantSelectionSuperUserRequestModel = OccupantSelectionSuperUserRequestModel
class AuthenticationResponseModels:
LoginSuperUserResponseModel = LoginSuperUserResponseModel
SelectCompanyOrOccupantTypeSuperUserResponseModel = (
SelectCompanyOrOccupantTypeSuperUserResponseModel
)
EmployeeSelectionSuperUserResponseModel = EmployeeSelectionSuperUserResponseModel
OccupantSelectionSuperUserResponseModel = OccupantSelectionSuperUserResponseModel

View File

@ -2,6 +2,4 @@
Events package initialization.
"""
__all__ = [
]
__all__ = []

View File

@ -10,4 +10,3 @@ def retrieve_cluster_by_name(cluster_name: str):
for module in events_list:
if hasattr(module, cluster_name, None):
return getattr(module, cluster_name, None)

View File

@ -62,7 +62,7 @@ class Event:
return self.NAME
@property
def key(self):
def key(self) -> str:
return str(self.KEY_)
@abstractmethod
@ -189,7 +189,9 @@ class CategoryCluster:
RedisCategoryKeys.CLUSTER_2_METHOD_EVENT
Returns the class name and function codes for the class.
"""
dict_cluster_2_method, list_endpoints = {}, [i.name for i in self.ENDPOINTS.values()]
dict_cluster_2_method, list_endpoints = {}, [
i.name for i in self.ENDPOINTS.values()
]
for endpoint_name in list_endpoints:
dict_cluster_2_method[endpoint_name] = self.name
dict_cluster_2_method[self.name] = list_endpoints
@ -201,7 +203,9 @@ class CategoryCluster:
"""
all_function_codes = []
for event_method in self.ENDPOINTS.values():
all_function_codes.extend([str(event_key) for event_key in event_method.EVENTS.keys()])
all_function_codes.extend(
[str(event_key) for event_key in event_method.EVENTS.keys()]
)
return all_function_codes
def retrieve_redis_value(self) -> Dict:

View File

@ -23,14 +23,17 @@ class CategoryClusterController:
{ "category_cluster_name": "category_cluster_module" }
"""
if not hasattr(category_clusters, "__all__"):
raise ValueError(f"Given module {str(category_clusters)} does not have __all__ attribute")
raise ValueError(
f"Given module {str(category_clusters)} does not have __all__ attribute"
)
for iter_module in [str(item) for item in category_clusters.__all__]:
# CategoryCluster which represent api routers for each category
cls.imports_dict.append(
CategoryBulk(
category_cluster=getattr(category_clusters, iter_module, None),
name=iter_module
))
name=iter_module,
)
)
@classmethod
def as_dict(cls):
@ -39,4 +42,5 @@ class CategoryClusterController:
to_dict[cluster.name] = cluster.category_cluster
return to_dict
cluster_controller = CategoryClusterController()

View File

@ -35,24 +35,32 @@ class DecoratorModule:
"""
decorators = []
current_func = func
original_qualname = getattr(func, '__qualname__', '')
original_qualname = getattr(func, "__qualname__", "")
while hasattr(current_func, '__wrapped__'):
if hasattr(current_func, '__closure__') and current_func.__closure__:
while hasattr(current_func, "__wrapped__"):
if hasattr(current_func, "__closure__") and current_func.__closure__:
for cell in current_func.__closure__:
decorator = cell.cell_contents
# Only add if it's a callable and not the original function
if callable(decorator) and getattr(decorator, '__qualname__', '') != original_qualname:
if (
callable(decorator)
and getattr(decorator, "__qualname__", "") != original_qualname
):
decorators.append(decorator)
current_func = current_func.__wrapped__
return list(dict.fromkeys(decorators)) # Remove duplicates while preserving order
return list(
dict.fromkeys(decorators)
) # Remove duplicates while preserving order
@staticmethod
def get_actual_decorators(method_endpoint):
original_qualname = getattr(method_endpoint.endpoint_callable, '__qualname__', '')
original_qualname = getattr(
method_endpoint.endpoint_callable, "__qualname__", ""
)
actual_decorators = [
d for d in method_endpoint.DECORATORS_LIST or []
if callable(d) and getattr(d, '__qualname__', '') != original_qualname
d
for d in method_endpoint.DECORATORS_LIST or []
if callable(d) and getattr(d, "__qualname__", "") != original_qualname
]
return actual_decorators
@ -68,17 +76,27 @@ class DecoratorModule:
try:
function_callable = decorator(function_callable)
except Exception as e:
print(f"Warning: Failed to apply decorator {decorator.__qualname__}: {str(e)}")
print(
f"Warning: Failed to apply decorator {decorator.__qualname__}: {str(e)}"
)
method_endpoint.endpoint_callable = function_callable
# Get the final list of applied decorators (for debugging)
applied_decorators = cls.get_all_decorators(method_endpoint.endpoint_callable)
applied_decorators_qualname = [getattr(d, '__qualname__', str(d)) for d in applied_decorators]
applied_decorators_qualname = [
getattr(d, "__qualname__", str(d)) for d in applied_decorators
]
if applied_decorators:
print(f"Applied decorators for {method_endpoint.name}:", applied_decorators_qualname)
print(
f"Applied decorators for {method_endpoint.name}:",
applied_decorators_qualname,
)
return applied_decorators_qualname
@classmethod
def list_qualname(cls, method_endpoint_list):
return [getattr(method_endpoint, '__qualname__', '') for method_endpoint in method_endpoint_list]
return [
getattr(method_endpoint, "__qualname__", "")
for method_endpoint in method_endpoint_list
]

View File

@ -9,8 +9,6 @@ def get_cluster_controller_group():
return cluster_controller
"""
prepare_routing = PrepareRouting(cluster_controller_group=cluster_controller)
prepare_events = PrepareEvents(cluster_controller_group=cluster_controller)

View File

@ -2,7 +2,7 @@ from typing import Any
from ApiLayers.ApiServices.Cluster.create_router import (
CreateRouterFromCluster,
CreateEndpointFromCluster
CreateEndpointFromCluster,
)
from Events.Engine.abstract_class import CategoryCluster
from Services.Redis.Actions.actions import RedisActions
@ -83,19 +83,27 @@ class PrepareEvents(DecoratorModule):
# [SAVE]REDIS => MENU_FIRST_LAYER = [ClusterToMethod, ...]
self.valid_redis_items.MENU_FIRST_LAYER_VALUE.add(cluster.name)
# [SAVE]REDIS => CLUSTER_INDEX = {ClusterToMethod: [MethodEvent, ...], "MethodEvent": "ClusterToMethod"}
self.valid_redis_items.CLUSTER_INDEX_VALUE.update(cluster.get_redis_cluster_index_value())
self.valid_redis_items.CLUSTER_INDEX_VALUE.update(
cluster.get_redis_cluster_index_value()
)
# [SAVE]REDIS => CLUSTER_FUNCTION_CODES = {"ClusterToMethod"} : [FUNCTION_CODE, ...]}
self.valid_redis_items.CLUSTER_FUNCTION_CODES_VALUE = {
f"{self.valid_redis_items.CLUSTER_FUNCTION_CODES_KEY}:{cluster.name}" : tuple(cluster.retrieve_all_function_codes())
f"{self.valid_redis_items.CLUSTER_FUNCTION_CODES_KEY}:{cluster.name}": tuple(
cluster.retrieve_all_function_codes()
)
}
for method_endpoint in list(cluster.ENDPOINTS.values()):
# [SAVE]REDIS => ENDPOINT2CLASS = {MethodEvent: Endpoint("/.../.../..."), ...}
self.valid_redis_items.ENDPOINT2CLASS_VALUE.update(
{f"{cluster.name}:{method_endpoint.name}": f"{cluster.PREFIX}{method_endpoint.URL}"}
{
f"{cluster.name}:{method_endpoint.name}": f"{cluster.PREFIX}{method_endpoint.URL}"
}
)
self.valid_redis_items.ENDPOINT2CLASS_VALUE.update(
{f"{cluster.PREFIX}{method_endpoint.URL}" :f"{cluster.name}:{method_endpoint.name}"}
{
f"{cluster.PREFIX}{method_endpoint.URL}": f"{cluster.name}:{method_endpoint.name}"
}
)
# [SAVE]REDIS => METHOD_FUNCTION_CODES:MethodEvent:Endpoint = [FUNCTION_CODE, ...]
self.valid_redis_items.METHOD_FUNCTION_CODES_VALUE.update(
@ -116,8 +124,12 @@ class SetItems2Redis:
def set_items(self):
from ApiLayers.AllConfigs.Redis.configs import RedisCategoryKeys
dict_prep = self.prepare_events.valid_redis_items.as_dict
for redis_values_to_delete, redis_key_type in RedisCategoryKeys.__annotations__.items():
for (
redis_values_to_delete,
redis_key_type,
) in RedisCategoryKeys.__annotations__.items():
if isinstance(redis_key_type, str):
continue
RedisActions.delete(list_keys=[f"{redis_values_to_delete}*"])
@ -125,19 +137,23 @@ class SetItems2Redis:
# Save MENU_FIRST_LAYER to Redis
redis_list = RedisList(redis_key=RedisCategoryKeys.MENU_FIRST_LAYER)
RedisActions.set_json(
list_keys=redis_list.to_list(), value=dict_prep.get(RedisCategoryKeys.MENU_FIRST_LAYER)
list_keys=redis_list.to_list(),
value=dict_prep.get(RedisCategoryKeys.MENU_FIRST_LAYER),
)
self.std_out += f"{RedisCategoryKeys.MENU_FIRST_LAYER}: {dict_prep.get(RedisCategoryKeys.MENU_FIRST_LAYER)}\n"
# Save CLUSTER_INDEX to Redis
redis_list = RedisList(redis_key=RedisCategoryKeys.CLUSTER_INDEX)
RedisActions.set_json(
list_keys=redis_list.to_list(), value=dict_prep.get(RedisCategoryKeys.CLUSTER_INDEX)
list_keys=redis_list.to_list(),
value=dict_prep.get(RedisCategoryKeys.CLUSTER_INDEX),
)
self.std_out += f"\n{RedisCategoryKeys.CLUSTER_INDEX}: {dict_prep.get(RedisCategoryKeys.CLUSTER_INDEX)}\n"
# Save CLUSTER_FUNCTION_CODES to Redis by iterating over the dict
for redis_key, redis_value in dict_prep.get(RedisCategoryKeys.CLUSTER_FUNCTION_CODES).items():
for redis_key, redis_value in dict_prep.get(
RedisCategoryKeys.CLUSTER_FUNCTION_CODES
).items():
redis_list = RedisList(redis_key=redis_key)
RedisActions.set_json(
list_keys=redis_list.to_list(), value=list(redis_value)
@ -145,7 +161,9 @@ class SetItems2Redis:
self.std_out += f"\n{RedisCategoryKeys.CLUSTER_FUNCTION_CODES}: {dict_prep.get(RedisCategoryKeys.CLUSTER_FUNCTION_CODES)}\n"
# Save METHOD_FUNCTION_CODES to Redis by iterating over the dict
for redis_key, redis_value in dict_prep.get(RedisCategoryKeys.METHOD_FUNCTION_CODES).items():
for redis_key, redis_value in dict_prep.get(
RedisCategoryKeys.METHOD_FUNCTION_CODES
).items():
redis_list = RedisList(redis_key=redis_key)
RedisActions.set_json(
list_keys=redis_list.to_list(), value=list(redis_value)
@ -153,19 +171,22 @@ class SetItems2Redis:
self.std_out += f"\n{RedisCategoryKeys.METHOD_FUNCTION_CODES}: {dict_prep.get(RedisCategoryKeys.METHOD_FUNCTION_CODES)}\n"
# Save ENDPOINT2CLASS to Redis by iterating over the dict
for redis_key, redis_value in dict_prep.get(RedisCategoryKeys.ENDPOINT2CLASS).items():
redis_list = RedisList(redis_key=f"{RedisCategoryKeys.ENDPOINT2CLASS}:{redis_key}\n")
RedisActions.set_json(
list_keys=redis_list.to_list(), value=redis_value
for redis_key, redis_value in dict_prep.get(
RedisCategoryKeys.ENDPOINT2CLASS
).items():
redis_list = RedisList(
redis_key=f"{RedisCategoryKeys.ENDPOINT2CLASS}:{redis_key}\n"
)
RedisActions.set_json(list_keys=redis_list.to_list(), value=redis_value)
self.std_out += f"\n{RedisCategoryKeys.ENDPOINT2CLASS}: {dict_prep.get(RedisCategoryKeys.ENDPOINT2CLASS)}\n"
RedisActions.set_json(
list_keys=[f"{RedisCategoryKeys.REBUILD}:*"], value={
list_keys=[f"{RedisCategoryKeys.REBUILD}:*"],
value={
f"{RedisCategoryKeys.MENU_FIRST_LAYER}": True,
f"{RedisCategoryKeys.CLUSTER_INDEX}": True,
f"{RedisCategoryKeys.CLUSTER_FUNCTION_CODES}": True,
f"{RedisCategoryKeys.METHOD_FUNCTION_CODES}": True,
f"{RedisCategoryKeys.ENDPOINT2CLASS}": True,
}
},
)

View File

@ -5,11 +5,19 @@ This module provides base request models that can be used across different endpo
to ensure consistent request handling and validation.
"""
from typing import Dict, Any, TypeVar
from pydantic import BaseModel, Field, ConfigDict
from typing import Union, Optional, Any
from pydantic import BaseModel, Field
from ApiLayers.ApiValidations.Custom.token_objects import (
EmployeeTokenObject,
OccupantTokenObject,
)
from ApiLayers.ApiValidations.Custom.wrapper_contexts import AuthContext, EventContext
T = TypeVar("T")
TokenDictType = Union[
EmployeeTokenObject, OccupantTokenObject
] # Type aliases for common types
class EndpointBaseRequestModel(BaseModel):
@ -17,35 +25,63 @@ class EndpointBaseRequestModel(BaseModel):
data: dict = Field(..., description="Data to be sent with the request")
class Config:
json_schema_extra = {
"data": {
"key": "value",
}
}
json_schema_extra = {"data": {"key": "value"}}
class SuccessResponse(BaseModel):
"""Standard success response model."""
class ContextRetrievers:
"""Utility class to retrieve context from functions."""
data: Dict[str, Any] = Field(
...,
example={
"id": "123",
"username": "john.doe",
"email": "john@example.com",
"role": "user",
},
)
is_auth: bool = False
is_event: bool = False
key_: str = ""
model_config = ConfigDict(
json_schema_extra={
"example": {
"data": {
"id": "123",
"username": "john.doe",
"email": "john@example.com",
"role": "user",
},
}
}
)
def __init__(self, func):
self.func = func
if hasattr(self.func, "auth_context"):
self.is_auth = True
self.key_ = "auth_context"
elif hasattr(self.func, "event_context"):
self.is_event = hasattr(self.func, "event_context")
self.key_ = "event_context"
@property
def key(self) -> Union[str, None]:
"""Retrieve key context from a function."""
return self.key_
@property
def context(self) -> Union[AuthContext, EventContext, None]:
"""Retrieve authentication or event context from a function."""
if self.is_auth:
return getattr(self.func, "auth_context", None)
elif self.is_event:
return getattr(self.func, "event_context", None)
return None
@property
def request(self) -> Union[Any, None]:
"""Retrieve request context from a function."""
return getattr(self.context, "request", None)
@property
def token(self) -> TokenDictType:
"""Retrieve token context from a function."""
if self.is_auth or self.is_event:
return getattr(self.context, "auth", None)
@property
def url(self) -> Union[str, None]:
"""Retrieve URL context from a function."""
return getattr(self.context, "url", None)
@property
def code(self) -> Union[str, None]:
"""Retrieve code context from a function."""
if self.is_event:
return getattr(self.context, "code", None)
return None
@property
def base(self) -> Optional[dict[str, Any]]:
"""Retrieve base request model from a function."""
return getattr(self.context, "base", None)

View File

@ -125,7 +125,9 @@ class QueryModel(ArgumentModel):
if not expired:
args = cls.get_not_expired_query_arg(args)
query = cls._query(db=db).filter(*args)
return PostgresResponse(pre_query=cls._query(db=db), query=query, is_array=False)
return PostgresResponse(
pre_query=cls._query(db=db), query=query, is_array=False
)
@classmethod
def filter_all_system(

View File

@ -26,7 +26,9 @@ class BasicMixin(Base, BaseAlchemyModel):
__repr__ = ReprMixin.__repr__
class CrudMixin(BasicMixin, CRUDModel, SerializeMixin, ReprMixin, SmartQueryMixin, QueryModel ):
class CrudMixin(
BasicMixin, CRUDModel, SerializeMixin, ReprMixin, SmartQueryMixin, QueryModel
):
"""
Base mixin providing CRUD operations and common fields for PostgreSQL models.