events auth repair
This commit is contained in:
9
ApiEvents/AuthServiceApi/auth/__init__.py
Normal file
9
ApiEvents/AuthServiceApi/auth/__init__.py
Normal file
@@ -0,0 +1,9 @@
|
||||
"""
|
||||
Authentication package initialization.
|
||||
"""
|
||||
|
||||
from .endpoints import AUTH_CONFIG
|
||||
|
||||
__all__ = [
|
||||
"AUTH_CONFIG",
|
||||
]
|
||||
@@ -2,103 +2,37 @@
|
||||
Authentication related API endpoints.
|
||||
"""
|
||||
|
||||
from typing import TYPE_CHECKING, Union, Optional, Dict, Any
|
||||
from typing import TYPE_CHECKING, Union, Dict, Any
|
||||
|
||||
# Regular imports (non-TYPE_CHECKING)
|
||||
from ApiEvents.abstract_class import (
|
||||
MethodToEvent,
|
||||
RouteFactoryConfig,
|
||||
EndpointFactoryConfig,
|
||||
)
|
||||
from ApiEvents.base_request_model import (
|
||||
BaseRequestModel,
|
||||
DictRequestModel,
|
||||
SuccessResponse,
|
||||
from ApiEvents.abstract_class import MethodToEvent
|
||||
from ApiEvents.base_request_model import DictRequestModel, SuccessResponse
|
||||
from ApiLibrary.common.line_number import get_line_number_for_error
|
||||
from ApiServices.Login.user_login_handler import UserLoginModule
|
||||
from ApiServices.Token.token_handler import AccessToken, TokenService
|
||||
from ApiValidations.Request.authentication import EmployeeSelectionValidation, Login, OccupantSelectionValidation
|
||||
from ErrorHandlers import HTTPExceptionApi
|
||||
from .models import (
|
||||
LoginData,
|
||||
LoginRequestModel,
|
||||
LogoutRequestModel,
|
||||
RememberRequestModel,
|
||||
ForgotRequestModel,
|
||||
ChangePasswordRequestModel,
|
||||
CreatePasswordRequestModel,
|
||||
SelectionDataEmployee,
|
||||
SelectionDataOccupant,
|
||||
)
|
||||
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from fastapi import Request
|
||||
from ApiServices.Token.token_handler import OccupantTokenObject, EmployeeTokenObject
|
||||
from Schemas import (
|
||||
Login,
|
||||
ChangePassword,
|
||||
CreatePassword,
|
||||
Forgot,
|
||||
Logout,
|
||||
Remember,
|
||||
EmployeeSelection,
|
||||
OccupantSelection,
|
||||
)
|
||||
|
||||
from ApiLibrary.common.line_number import get_line_number_for_error
|
||||
from ApiServices.Login.user_login_handler import UserLoginModule
|
||||
from ApiValidations.Request import (
|
||||
Login,
|
||||
Logout,
|
||||
Remember,
|
||||
Forgot,
|
||||
ChangePassword,
|
||||
CreatePassword,
|
||||
EmployeeSelection,
|
||||
OccupantSelection,
|
||||
)
|
||||
from Services.PostgresDb.Models.alchemy_response import AlchemyJsonResponse
|
||||
from ApiValidations.Response import AccountRecordResponse
|
||||
from ApiServices.Token.token_handler import AccessToken, TokenService
|
||||
from ErrorHandlers import HTTPExceptionApi
|
||||
|
||||
# Type aliases for common types
|
||||
TokenDictType = Union["EmployeeTokenObject", "OccupantTokenObject"]
|
||||
|
||||
|
||||
class LoginRequestModel(BaseRequestModel[Login]):
|
||||
"""Request model for login endpoint."""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class LogoutRequestModel(BaseRequestModel[Logout]):
|
||||
"""Request model for logout endpoint."""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class RememberRequestModel(BaseRequestModel[Remember]):
|
||||
"""Request model for remember token endpoint."""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class ForgotRequestModel(BaseRequestModel[Forgot]):
|
||||
"""Request model for forgot password endpoint."""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class ChangePasswordRequestModel(BaseRequestModel[ChangePassword]):
|
||||
"""Request model for change password endpoint."""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class CreatePasswordRequestModel(BaseRequestModel[CreatePassword]):
|
||||
"""Request model for create password endpoint."""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class EmployeeSelectionRequestModel(BaseRequestModel[EmployeeSelection]):
|
||||
"""Request model for employee selection endpoint."""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class OccupantSelectionRequestModel(BaseRequestModel[OccupantSelection]):
|
||||
"""Request model for occupant selection endpoint."""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class AuthenticationLoginEventMethods(MethodToEvent):
|
||||
event_type = "LOGIN"
|
||||
event_description = "Login via domain and access key : [email] | [phone]"
|
||||
@@ -112,7 +46,7 @@ class AuthenticationLoginEventMethods(MethodToEvent):
|
||||
|
||||
@classmethod
|
||||
async def authentication_login_with_domain_and_creds(
|
||||
cls, request: "Request", data: LoginRequestModel
|
||||
cls, request: "Request", data: Login
|
||||
):
|
||||
"""
|
||||
Authenticate user with domain and credentials.
|
||||
@@ -129,11 +63,9 @@ class AuthenticationLoginEventMethods(MethodToEvent):
|
||||
Returns:
|
||||
SuccessResponse containing authentication token and user info
|
||||
"""
|
||||
# Create login module instance
|
||||
login_module = UserLoginModule(request=request)
|
||||
|
||||
# Get token from login module
|
||||
token = await login_module.login_user_via_credentials(access_data=data)
|
||||
user_login_module = UserLoginModule(request=request)
|
||||
token = await user_login_module.login_user_via_credentials(access_data=data)
|
||||
|
||||
# Return response with token and headers
|
||||
return {
|
||||
@@ -157,135 +89,53 @@ class AuthenticationSelectEventMethods(MethodToEvent):
|
||||
@classmethod
|
||||
def _handle_employee_selection(
|
||||
cls,
|
||||
data: EmployeeSelectionRequestModel,
|
||||
data: SelectionDataEmployee,
|
||||
token_dict: TokenDictType,
|
||||
request: "Request",
|
||||
):
|
||||
return
|
||||
# """Handle employee company selection"""
|
||||
# Users.client_arrow = DateTimeLocal(is_client=True, timezone=token_dict.timezone)
|
||||
# if data.company_uu_id not in token_dict.companies_uu_id_list:
|
||||
# return ResponseHandler.unauthorized(
|
||||
# "Company not found in user's company list"
|
||||
# )
|
||||
|
||||
# selected_company = Companies.filter_one(
|
||||
# Companies.uu_id == data.company_uu_id
|
||||
# ).data
|
||||
# if not selected_company:
|
||||
# return ResponseHandler.not_found("Company not found")
|
||||
|
||||
# # Get department IDs for the company
|
||||
# department_ids = [
|
||||
# dept.id
|
||||
# for dept in Departments.filter_all(
|
||||
# Departments.company_id == selected_company.id
|
||||
# ).data
|
||||
# ]
|
||||
|
||||
# # Get duties IDs for the company
|
||||
# duties_ids = [
|
||||
# duty.id
|
||||
# for duty in Duties.filter_all(Duties.company_id == selected_company.id).data
|
||||
# ]
|
||||
|
||||
# # Get staff IDs
|
||||
# staff_ids = [
|
||||
# staff.id for staff in Staff.filter_all(Staff.duties_id.in_(duties_ids)).data
|
||||
# ]
|
||||
|
||||
# # Get employee
|
||||
# employee = Employees.filter_one(
|
||||
# Employees.people_id == token_dict.person_id,
|
||||
# Employees.staff_id.in_(staff_ids),
|
||||
# ).data
|
||||
|
||||
# if not employee:
|
||||
# return ResponseHandler.not_found("Employee not found")
|
||||
|
||||
# # Get reachable events
|
||||
# reachable_event_list_id = Event2Employee.get_event_id_by_employee_id(
|
||||
# employee_id=employee.id
|
||||
# )
|
||||
|
||||
# # Get staff and duties
|
||||
# staff = Staff.filter_one(Staff.id == employee.staff_id).data
|
||||
# duties = Duties.filter_one(Duties.id == staff.duties_id).data
|
||||
# department = Departments.filter_one(Departments.id == duties.department_id).data
|
||||
|
||||
# # Get bulk duty
|
||||
# bulk_id = Duty.filter_by_one(system=True, duty_code="BULK").data
|
||||
# bulk_duty_id = Duties.filter_by_one(
|
||||
# company_id=selected_company.id,
|
||||
# duties_id=bulk_id.id,
|
||||
# **Duties.valid_record_dict,
|
||||
# ).data
|
||||
|
||||
# # Create company token
|
||||
# company_token = CompanyToken(
|
||||
# company_uu_id=selected_company.uu_id.__str__(),
|
||||
# company_id=selected_company.id,
|
||||
# department_id=department.id,
|
||||
# department_uu_id=department.uu_id.__str__(),
|
||||
# duty_id=duties.id,
|
||||
# duty_uu_id=duties.uu_id.__str__(),
|
||||
# bulk_duties_id=bulk_duty_id.id,
|
||||
# staff_id=staff.id,
|
||||
# staff_uu_id=staff.uu_id.__str__(),
|
||||
# employee_id=employee.id,
|
||||
# employee_uu_id=employee.uu_id.__str__(),
|
||||
# reachable_event_list_id=reachable_event_list_id,
|
||||
# )
|
||||
|
||||
# # Update Redis
|
||||
# AuthActions.update_selected_to_redis(request=request, add_payload=company_token)
|
||||
# return ResponseHandler.success("Company selected successfully")
|
||||
raise HTTPExceptionApi(
|
||||
error_code="", lang="en", loc=get_line_number_for_error()
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def _handle_occupant_selection(
|
||||
cls,
|
||||
data: OccupantSelectionRequestModel,
|
||||
data: SelectionDataOccupant,
|
||||
token_dict: TokenDictType,
|
||||
request: "Request",
|
||||
):
|
||||
"""Handle occupant type selection"""
|
||||
raise HTTPExceptionApi(
|
||||
error_code="HTTP_400_BAD_REQUEST",
|
||||
lang=token_dict.lang,
|
||||
loc=get_line_number_for_error(),
|
||||
sys_msg="Occupant selection not implemented",
|
||||
)
|
||||
|
||||
@classmethod
|
||||
async def authentication_select_company_or_occupant_type(
|
||||
cls,
|
||||
request: "Request",
|
||||
data: Union[EmployeeSelectionValidation, OccupantSelectionValidation],
|
||||
token_dict: TokenDictType,
|
||||
):
|
||||
"""Handle selection of company or occupant type"""
|
||||
try:
|
||||
if isinstance(token_dict, EmployeeTokenObject):
|
||||
return cls._handle_employee_selection(data, token_dict, request)
|
||||
elif isinstance(token_dict, OccupantTokenObject):
|
||||
return cls._handle_occupant_selection(data, token_dict, request)
|
||||
raise HTTPExceptionApi(
|
||||
error_code="HTTP_400_BAD_REQUEST",
|
||||
lang=token_dict.lang,
|
||||
loc=get_line_number_for_error(),
|
||||
print(
|
||||
dict(
|
||||
data=data,
|
||||
token_dict=token_dict.model_dump(),
|
||||
request=dict(request.headers)
|
||||
)
|
||||
)
|
||||
except Exception as e:
|
||||
return ResponseHandler.error(
|
||||
str(e), status_code=status.HTTP_500_INTERNAL_SERVER_ERROR
|
||||
raise HTTPExceptionApi(
|
||||
error_code="HTTP_500_INTERNAL_SERVER_ERROR",
|
||||
lang="en",
|
||||
loc=get_line_number_for_error(),
|
||||
sys_msg=str(e),
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def authentication_select_company_or_occupant_type(
|
||||
cls,
|
||||
request: "Request",
|
||||
data: Union[EmployeeSelectionRequestModel, OccupantSelectionRequestModel],
|
||||
token_dict: TokenDictType,
|
||||
):
|
||||
"""Handle selection of company or occupant type"""
|
||||
# try:
|
||||
# if isinstance(token_dict, EmployeeTokenObject):
|
||||
# return cls._handle_employee_selection(data, token_dict, request)
|
||||
# elif isinstance(token_dict, OccupantTokenObject):
|
||||
# return cls._handle_occupant_selection(data, token_dict, request)
|
||||
# return ResponseHandler.error(
|
||||
# "Invalid token type", status_code=status.HTTP_400_BAD_REQUEST
|
||||
# )
|
||||
# except Exception as e:
|
||||
# return ResponseHandler.error(
|
||||
# str(e), status_code=status.HTTP_500_INTERNAL_SERVER_ERROR
|
||||
# )
|
||||
return
|
||||
|
||||
|
||||
class AuthenticationCheckTokenEventMethods(MethodToEvent):
|
||||
event_type = "LOGIN"
|
||||
@@ -300,7 +150,7 @@ class AuthenticationCheckTokenEventMethods(MethodToEvent):
|
||||
# }
|
||||
|
||||
@classmethod
|
||||
def authentication_check_token_is_valid(
|
||||
async def authentication_check_token_is_valid(
|
||||
cls, request: "Request", data: DictRequestModel
|
||||
):
|
||||
# try:
|
||||
@@ -324,7 +174,7 @@ class AuthenticationRefreshEventMethods(MethodToEvent):
|
||||
# }
|
||||
|
||||
@classmethod
|
||||
def authentication_refresh_user_info(
|
||||
async def authentication_refresh_user_info(
|
||||
cls,
|
||||
request: "Request",
|
||||
token_dict: TokenDictType,
|
||||
@@ -371,7 +221,7 @@ class AuthenticationChangePasswordEventMethods(MethodToEvent):
|
||||
# }
|
||||
|
||||
@classmethod
|
||||
def authentication_change_password(
|
||||
async def authentication_change_password(
|
||||
cls,
|
||||
request: "Request",
|
||||
data: ChangePasswordRequestModel,
|
||||
@@ -429,7 +279,7 @@ class AuthenticationCreatePasswordEventMethods(MethodToEvent):
|
||||
# }
|
||||
|
||||
@classmethod
|
||||
def authentication_create_password(
|
||||
async def authentication_create_password(
|
||||
cls, request: "Request", data: CreatePasswordRequestModel
|
||||
):
|
||||
|
||||
@@ -475,7 +325,7 @@ class AuthenticationDisconnectUserEventMethods(MethodToEvent):
|
||||
# }
|
||||
|
||||
@classmethod
|
||||
def authentication_disconnect_user(
|
||||
async def authentication_disconnect_user(
|
||||
cls, request: "Request", data: LogoutRequestModel, token_dict: TokenDictType
|
||||
):
|
||||
# found_user = Users.filter_one(Users.uu_id == token_dict.user_uu_id).data
|
||||
@@ -514,11 +364,11 @@ class AuthenticationLogoutEventMethods(MethodToEvent):
|
||||
# }
|
||||
|
||||
@classmethod
|
||||
def authentication_logout_user(
|
||||
async def authentication_logout_user(
|
||||
cls,
|
||||
request: "Request",
|
||||
data: LogoutRequestModel,
|
||||
token_dict: TokenDictType = None,
|
||||
token_dict: TokenDictType,
|
||||
):
|
||||
# token_user = None
|
||||
# if already_tokens := RedisActions.get_object_via_access_key(request=request):
|
||||
@@ -553,7 +403,7 @@ class AuthenticationRefreshTokenEventMethods(MethodToEvent):
|
||||
# }
|
||||
|
||||
@classmethod
|
||||
def authentication_refresher_token(
|
||||
async def authentication_refresher_token(
|
||||
cls, request: "Request", data: RememberRequestModel, token_dict: TokenDictType
|
||||
):
|
||||
# token_refresher = UsersTokens.filter_by_one(
|
||||
@@ -602,7 +452,7 @@ class AuthenticationForgotPasswordEventMethods(MethodToEvent):
|
||||
# }
|
||||
|
||||
@classmethod
|
||||
def authentication_forgot_password(
|
||||
async def authentication_forgot_password(
|
||||
cls,
|
||||
request: "Request",
|
||||
data: ForgotRequestModel,
|
||||
@@ -644,7 +494,7 @@ class AuthenticationResetPasswordEventMethods(MethodToEvent):
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def authentication_reset_password(
|
||||
async def authentication_reset_password(
|
||||
cls, request: "Request", data: ForgotRequestModel
|
||||
):
|
||||
# from sqlalchemy import or_
|
||||
@@ -695,11 +545,11 @@ class AuthenticationDownloadAvatarEventMethods(MethodToEvent):
|
||||
# }
|
||||
|
||||
@classmethod
|
||||
def authentication_download_avatar(
|
||||
async def authentication_download_avatar(
|
||||
cls,
|
||||
token_dict: TokenDictType,
|
||||
request: "Request",
|
||||
data: DictRequestModel,
|
||||
token_dict: TokenDictType,
|
||||
):
|
||||
# if found_user := Users.filter_one(Users.id == token_dict.user_id).data:
|
||||
# expired_starts = str(
|
||||
@@ -725,253 +575,3 @@ class AuthenticationDownloadAvatarEventMethods(MethodToEvent):
|
||||
# return ResponseHandler.not_found("Invalid data")
|
||||
|
||||
return
|
||||
|
||||
|
||||
async def authentication_select_company_or_occupant_type(
|
||||
request: "Request",
|
||||
data: Union[EmployeeSelectionRequestModel, OccupantSelectionRequestModel],
|
||||
) -> Dict[str, Any]:
|
||||
return await AuthenticationSelectEventMethods.authentication_select_company_or_occupant_type(
|
||||
request=request, data=data
|
||||
)
|
||||
|
||||
|
||||
async def authentication_login_with_domain_and_creds(
|
||||
request: "Request", data: LoginRequestModel
|
||||
) -> SuccessResponse:
|
||||
"""
|
||||
Authenticate user with domain and credentials.
|
||||
|
||||
Args:
|
||||
request: FastAPI request object
|
||||
data: Request body containing login credentials
|
||||
{
|
||||
"domain": str,
|
||||
"username": str,
|
||||
"password": str
|
||||
}
|
||||
|
||||
Returns:
|
||||
SuccessResponse containing authentication token and user info
|
||||
"""
|
||||
return await AuthenticationLoginEventMethods.authentication_login_with_domain_and_creds(
|
||||
request=request, data=data
|
||||
)
|
||||
|
||||
|
||||
async def authentication_check_token_is_valid(
|
||||
request: "Request", data: DictRequestModel
|
||||
) -> Dict[str, Any]:
|
||||
return (
|
||||
await AuthenticationCheckTokenEventMethods.authentication_check_token_is_valid(
|
||||
request=request, data=data
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def authentication_refresh_user_info(
|
||||
request: "Request", data: DictRequestModel
|
||||
) -> Dict[str, Any]:
|
||||
return
|
||||
|
||||
|
||||
def authentication_change_password(
|
||||
request: "Request", data: ChangePasswordRequestModel
|
||||
) -> Dict[str, Any]:
|
||||
return
|
||||
|
||||
|
||||
def authentication_create_password(
|
||||
request: "Request", data: CreatePasswordRequestModel
|
||||
) -> Dict[str, Any]:
|
||||
return
|
||||
|
||||
|
||||
def authentication_forgot_password(
|
||||
request: "Request", data: ForgotRequestModel
|
||||
) -> Dict[str, Any]:
|
||||
return
|
||||
|
||||
|
||||
def authentication_reset_password(
|
||||
request: "Request", data: ForgotRequestModel
|
||||
) -> Dict[str, Any]:
|
||||
return
|
||||
|
||||
|
||||
def authentication_disconnect_user(
|
||||
request: "Request", data: LogoutRequestModel
|
||||
) -> Dict[str, Any]:
|
||||
return
|
||||
|
||||
|
||||
def authentication_logout_user(
|
||||
request: "Request", data: LogoutRequestModel
|
||||
) -> Dict[str, Any]:
|
||||
return
|
||||
|
||||
|
||||
def authentication_refresher_token(
|
||||
request: "Request", data: RememberRequestModel
|
||||
) -> Dict[str, Any]:
|
||||
return
|
||||
|
||||
|
||||
def authentication_download_avatar(
|
||||
request: "Request", data: DictRequestModel
|
||||
) -> Dict[str, Any]:
|
||||
return
|
||||
|
||||
|
||||
AUTH_CONFIG = RouteFactoryConfig(
|
||||
name="authentication",
|
||||
prefix="/authentication",
|
||||
tags=["Authentication"],
|
||||
include_in_schema=True,
|
||||
endpoints=[
|
||||
EndpointFactoryConfig(
|
||||
url_prefix="/authentication",
|
||||
url_endpoint="/select",
|
||||
url_of_endpoint="/authentication/select",
|
||||
endpoint="/select",
|
||||
method="POST",
|
||||
summary="Select company or occupant type",
|
||||
description="Select company or occupant type",
|
||||
is_auth_required=True, # Needs token_dict
|
||||
is_event_required=False,
|
||||
endpoint_function=authentication_select_company_or_occupant_type,
|
||||
),
|
||||
EndpointFactoryConfig(
|
||||
url_prefix="/authentication",
|
||||
url_endpoint="/login",
|
||||
url_of_endpoint="/authentication/login",
|
||||
endpoint="/login",
|
||||
method="POST",
|
||||
summary="Login user with domain and password",
|
||||
description="Login user with domain and password",
|
||||
is_auth_required=False, # Public endpoint
|
||||
is_event_required=False,
|
||||
endpoint_function=authentication_login_with_domain_and_creds,
|
||||
),
|
||||
EndpointFactoryConfig(
|
||||
url_prefix="/authentication",
|
||||
url_endpoint="/valid",
|
||||
url_of_endpoint="/authentication/valid",
|
||||
endpoint="/valid",
|
||||
method="GET",
|
||||
summary="Check access token is valid",
|
||||
description="Check access token is valid",
|
||||
is_auth_required=True, # Needs token validation
|
||||
is_event_required=False,
|
||||
endpoint_function=authentication_check_token_is_valid,
|
||||
),
|
||||
EndpointFactoryConfig(
|
||||
url_prefix="/authentication",
|
||||
url_endpoint="/refresh",
|
||||
url_of_endpoint="/authentication/refresh",
|
||||
endpoint="/refresh",
|
||||
method="GET",
|
||||
summary="Refresh credentials with access token",
|
||||
description="Refresh credentials with access token",
|
||||
is_auth_required=True, # Needs token_dict
|
||||
is_event_required=False,
|
||||
endpoint_function=authentication_refresh_user_info,
|
||||
),
|
||||
EndpointFactoryConfig(
|
||||
url_prefix="/authentication",
|
||||
url_endpoint="/change_password",
|
||||
url_of_endpoint="/authentication/change_password",
|
||||
endpoint="/change_password",
|
||||
method="POST",
|
||||
summary="Change password with access token",
|
||||
description="Change password with access token",
|
||||
is_auth_required=True, # Needs token_dict
|
||||
is_event_required=False,
|
||||
endpoint_function=authentication_change_password,
|
||||
),
|
||||
EndpointFactoryConfig(
|
||||
url_prefix="/authentication",
|
||||
url_endpoint="/create_password",
|
||||
url_of_endpoint="/authentication/create_password",
|
||||
endpoint="/create_password",
|
||||
method="POST",
|
||||
summary="Create password with password token",
|
||||
description="Create password with password token",
|
||||
is_auth_required=False, # Public endpoint
|
||||
is_event_required=False,
|
||||
endpoint_function=authentication_create_password,
|
||||
),
|
||||
EndpointFactoryConfig(
|
||||
url_prefix="/authentication",
|
||||
url_endpoint="/reset_password",
|
||||
url_of_endpoint="/authentication/reset_password",
|
||||
endpoint="/reset_password",
|
||||
method="POST",
|
||||
summary="Create password with password token",
|
||||
description="Create password with password token",
|
||||
is_auth_required=False, # Public endpoint
|
||||
is_event_required=False,
|
||||
endpoint_function=authentication_reset_password,
|
||||
),
|
||||
EndpointFactoryConfig(
|
||||
url_prefix="/authentication",
|
||||
url_endpoint="/disconnect",
|
||||
url_of_endpoint="/authentication/disconnect",
|
||||
endpoint="/disconnect",
|
||||
method="POST",
|
||||
summary="Disconnect user with access token",
|
||||
description="Disconnect user with access token",
|
||||
is_auth_required=True, # Needs token_dict
|
||||
is_event_required=False,
|
||||
endpoint_function=authentication_disconnect_user,
|
||||
),
|
||||
EndpointFactoryConfig(
|
||||
url_prefix="/authentication",
|
||||
url_endpoint="/logout",
|
||||
url_of_endpoint="/authentication/logout",
|
||||
endpoint="/logout",
|
||||
method="POST",
|
||||
summary="Logout user with access token",
|
||||
description="Logout user with access token",
|
||||
is_auth_required=True, # Needs token_dict
|
||||
is_event_required=False,
|
||||
endpoint_function=authentication_logout_user,
|
||||
),
|
||||
EndpointFactoryConfig(
|
||||
url_prefix="/authentication",
|
||||
url_endpoint="/refresher",
|
||||
url_of_endpoint="/authentication/refresher",
|
||||
endpoint="/refresher",
|
||||
method="POST",
|
||||
summary="Refresh token with refresh token",
|
||||
description="Refresh token with refresh token",
|
||||
is_auth_required=True, # Needs token_dict
|
||||
is_event_required=False,
|
||||
endpoint_function=authentication_refresher_token,
|
||||
),
|
||||
EndpointFactoryConfig(
|
||||
url_prefix="/authentication",
|
||||
url_endpoint="/forgot",
|
||||
url_of_endpoint="/authentication/forgot",
|
||||
endpoint="/forgot",
|
||||
method="POST",
|
||||
summary="Forgot password with email or phone number",
|
||||
description="Forgot password with email or phone number",
|
||||
is_auth_required=False, # Public endpoint
|
||||
is_event_required=False,
|
||||
endpoint_function=authentication_forgot_password,
|
||||
),
|
||||
EndpointFactoryConfig(
|
||||
url_prefix="/authentication",
|
||||
url_endpoint="/avatar",
|
||||
url_of_endpoint="/authentication/avatar",
|
||||
endpoint="/avatar",
|
||||
method="POST",
|
||||
summary="Get link of avatar with credentials",
|
||||
description="Get link of avatar with credentials",
|
||||
is_auth_required=True, # Needs token_dict
|
||||
is_event_required=False,
|
||||
endpoint_function=authentication_download_avatar,
|
||||
),
|
||||
],
|
||||
).as_dict()
|
||||
|
||||
371
ApiEvents/AuthServiceApi/auth/endpoints.py
Normal file
371
ApiEvents/AuthServiceApi/auth/endpoints.py
Normal file
@@ -0,0 +1,371 @@
|
||||
"""
|
||||
Authentication endpoint configurations.
|
||||
"""
|
||||
|
||||
from typing import TYPE_CHECKING, Dict, Any, Union, Annotated
|
||||
from fastapi import HTTPException, status, Body
|
||||
|
||||
from ApiValidations.Request.authentication import Login
|
||||
|
||||
from .auth import (
|
||||
AuthenticationChangePasswordEventMethods,
|
||||
AuthenticationCheckTokenEventMethods,
|
||||
AuthenticationCreatePasswordEventMethods,
|
||||
AuthenticationDisconnectUserEventMethods,
|
||||
AuthenticationDownloadAvatarEventMethods,
|
||||
AuthenticationForgotPasswordEventMethods,
|
||||
AuthenticationLoginEventMethods,
|
||||
AuthenticationLogoutEventMethods,
|
||||
AuthenticationRefreshEventMethods,
|
||||
AuthenticationRefreshTokenEventMethods,
|
||||
AuthenticationResetPasswordEventMethods,
|
||||
AuthenticationSelectEventMethods,
|
||||
)
|
||||
from .models import (
|
||||
ChangePasswordRequestModel,
|
||||
CreatePasswordRequestModel,
|
||||
ForgotRequestModel,
|
||||
LoginData,
|
||||
LoginRequestModel,
|
||||
LogoutRequestModel,
|
||||
SelectionDataEmployee,
|
||||
SelectionDataOccupant,
|
||||
RememberRequestModel,
|
||||
)
|
||||
from ApiEvents.base_request_model import DictRequestModel
|
||||
from ApiEvents.abstract_class import RouteFactoryConfig, EndpointFactoryConfig, endpoint_wrapper
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from fastapi import Request
|
||||
from ApiValidations.Custom.token_objects import EmployeeTokenObject, OccupantTokenObject
|
||||
|
||||
|
||||
# Type aliases for common types
|
||||
TokenDictType = Union[EmployeeTokenObject, OccupantTokenObject]
|
||||
|
||||
|
||||
@endpoint_wrapper("/authentication/select")
|
||||
async def authentication_select_company_or_occupant_type(
|
||||
request: "Request",
|
||||
data: Union[SelectionDataEmployee, SelectionDataOccupant],
|
||||
token_dict: TokenDictType = None
|
||||
) -> Dict[str, Any]:
|
||||
"""
|
||||
Handle selection of company or occupant type.
|
||||
|
||||
Args:
|
||||
request: The FastAPI request object
|
||||
data: Selection request data
|
||||
|
||||
Returns:
|
||||
Dict containing the response data
|
||||
"""
|
||||
return {
|
||||
"headers": dict(request.headers),
|
||||
"data": data,
|
||||
"token": token_dict
|
||||
}
|
||||
|
||||
|
||||
@endpoint_wrapper("/authentication/login")
|
||||
async def authentication_login_with_domain_and_creds(
|
||||
request: "Request",
|
||||
data: Login,
|
||||
) -> Dict[str, Any]:
|
||||
"""
|
||||
Authenticate user with domain and credentials.
|
||||
"""
|
||||
return AuthenticationLoginEventMethods.authentication_login_with_domain_and_creds(
|
||||
request=request, data=data
|
||||
)
|
||||
|
||||
|
||||
@endpoint_wrapper("/authentication/check")
|
||||
async def authentication_check_token_is_valid(
|
||||
request: "Request",
|
||||
data: DictRequestModel,
|
||||
) -> Dict[str, Any]:
|
||||
"""
|
||||
Check if a token is valid.
|
||||
"""
|
||||
return {
|
||||
"status": "OK",
|
||||
}
|
||||
|
||||
|
||||
|
||||
@endpoint_wrapper("/authentication/refresh")
|
||||
async def authentication_refresh_user_info(
|
||||
request: "Request",
|
||||
data: DictRequestModel,
|
||||
token_dict: TokenDictType = None,
|
||||
) -> Dict[str, Any]:
|
||||
"""
|
||||
Refresh user information.
|
||||
"""
|
||||
return {
|
||||
"status": "OK",
|
||||
}
|
||||
|
||||
|
||||
@endpoint_wrapper("/authentication/change-password")
|
||||
async def authentication_change_password(
|
||||
request: "Request",
|
||||
data: ChangePasswordRequestModel,
|
||||
token_dict: TokenDictType = None,
|
||||
) -> Dict[str, Any]:
|
||||
"""
|
||||
Change user password.
|
||||
"""
|
||||
return {
|
||||
"status": "OK",
|
||||
}
|
||||
|
||||
|
||||
@endpoint_wrapper("/authentication/create-password")
|
||||
async def authentication_create_password(
|
||||
request: "Request",
|
||||
data: CreatePasswordRequestModel,
|
||||
) -> Dict[str, Any]:
|
||||
"""
|
||||
Create new password.
|
||||
"""
|
||||
return {
|
||||
"status": "OK",
|
||||
}
|
||||
|
||||
@endpoint_wrapper("/authentication/forgot-password")
|
||||
async def authentication_forgot_password(
|
||||
request: "Request",
|
||||
data: ForgotRequestModel,
|
||||
) -> Dict[str, Any]:
|
||||
"""
|
||||
Handle forgot password request.
|
||||
"""
|
||||
return {
|
||||
"status": "OK",
|
||||
}
|
||||
|
||||
@endpoint_wrapper("/authentication/reset-password")
|
||||
async def authentication_reset_password(
|
||||
request: "Request",
|
||||
data: ForgotRequestModel,
|
||||
) -> Dict[str, Any]:
|
||||
"""
|
||||
Reset password.
|
||||
"""
|
||||
return {
|
||||
"status": "OK",
|
||||
}
|
||||
|
||||
@endpoint_wrapper("/authentication/disconnect")
|
||||
async def authentication_disconnect_user(
|
||||
request: "Request",
|
||||
data: LogoutRequestModel,
|
||||
token_dict: TokenDictType = None,
|
||||
) -> Dict[str, Any]:
|
||||
"""
|
||||
Disconnect user.
|
||||
"""
|
||||
return {
|
||||
"status": "OK",
|
||||
}
|
||||
|
||||
|
||||
@endpoint_wrapper("/authentication/logout")
|
||||
async def authentication_logout_user(
|
||||
request: "Request",
|
||||
data: LogoutRequestModel,
|
||||
token_dict: TokenDictType = None,
|
||||
) -> Dict[str, Any]:
|
||||
"""
|
||||
Logout user.
|
||||
"""
|
||||
return {
|
||||
"status": "OK",
|
||||
}
|
||||
|
||||
|
||||
@endpoint_wrapper("/authentication/remember")
|
||||
async def authentication_refresher_token(
|
||||
request: "Request",
|
||||
data: RememberRequestModel,
|
||||
token_dict: TokenDictType = None,
|
||||
) -> Dict[str, Any]:
|
||||
"""
|
||||
Refresh remember token.
|
||||
"""
|
||||
return {
|
||||
"status": "OK",
|
||||
}
|
||||
|
||||
|
||||
@endpoint_wrapper("/authentication/avatar")
|
||||
async def authentication_download_avatar(
|
||||
request: "Request",
|
||||
data: DictRequestModel,
|
||||
token_dict: TokenDictType = None,
|
||||
) -> Dict[str, Any]:
|
||||
"""
|
||||
Download user avatar.
|
||||
"""
|
||||
return {
|
||||
"status": "OK",
|
||||
}
|
||||
|
||||
|
||||
prefix = "/authentication"
|
||||
|
||||
|
||||
AUTH_CONFIG = RouteFactoryConfig(
|
||||
name="authentication",
|
||||
prefix=prefix,
|
||||
tags=["Authentication"],
|
||||
include_in_schema=True,
|
||||
endpoints=[
|
||||
EndpointFactoryConfig(
|
||||
url_prefix=prefix,
|
||||
url_endpoint="/select",
|
||||
url_of_endpoint="/authentication/select",
|
||||
endpoint="/select",
|
||||
method="POST",
|
||||
summary="Select company or occupant type",
|
||||
description="Select company or occupant type",
|
||||
is_auth_required=True, # Needs token_dict
|
||||
is_event_required=False,
|
||||
endpoint_function=authentication_select_company_or_occupant_type,
|
||||
),
|
||||
EndpointFactoryConfig(
|
||||
url_prefix=prefix,
|
||||
url_endpoint="/login",
|
||||
url_of_endpoint="/authentication/login",
|
||||
endpoint="/login",
|
||||
method="POST",
|
||||
summary="Login user with domain and password",
|
||||
description="Login user with domain and password",
|
||||
is_auth_required=False, # Public endpoint
|
||||
is_event_required=False,
|
||||
endpoint_function=authentication_login_with_domain_and_creds,
|
||||
),
|
||||
EndpointFactoryConfig(
|
||||
url_prefix=prefix,
|
||||
url_endpoint="/check",
|
||||
url_of_endpoint="/authentication/check",
|
||||
endpoint="/check",
|
||||
method="GET",
|
||||
summary="Check access token is valid",
|
||||
description="Check access token is valid",
|
||||
is_auth_required=True, # Needs token validation
|
||||
is_event_required=False,
|
||||
endpoint_function=authentication_check_token_is_valid,
|
||||
),
|
||||
EndpointFactoryConfig(
|
||||
url_prefix=prefix,
|
||||
url_endpoint="/refresh",
|
||||
url_of_endpoint="/authentication/refresh",
|
||||
endpoint="/refresh",
|
||||
method="GET",
|
||||
summary="Refresh credentials with access token",
|
||||
description="Refresh credentials with access token",
|
||||
is_auth_required=True, # Needs token_dict
|
||||
is_event_required=False,
|
||||
endpoint_function=authentication_refresh_user_info,
|
||||
),
|
||||
EndpointFactoryConfig(
|
||||
url_prefix=prefix,
|
||||
url_endpoint="/change-password",
|
||||
url_of_endpoint="/authentication/change-password",
|
||||
endpoint="/change-password",
|
||||
method="POST",
|
||||
summary="Change password with access token",
|
||||
description="Change password with access token",
|
||||
is_auth_required=True, # Needs token_dict
|
||||
is_event_required=False,
|
||||
endpoint_function=authentication_change_password,
|
||||
),
|
||||
EndpointFactoryConfig(
|
||||
url_prefix=prefix,
|
||||
url_endpoint="/create-password",
|
||||
url_of_endpoint="/authentication/create-password",
|
||||
endpoint="/create-password",
|
||||
method="POST",
|
||||
summary="Create password with password token",
|
||||
description="Create password with password token",
|
||||
is_auth_required=False, # Public endpoint
|
||||
is_event_required=False,
|
||||
endpoint_function=authentication_create_password,
|
||||
),
|
||||
EndpointFactoryConfig(
|
||||
url_prefix=prefix,
|
||||
url_endpoint="/reset-password",
|
||||
url_of_endpoint="/authentication/reset-password",
|
||||
endpoint="/reset-password",
|
||||
method="POST",
|
||||
summary="Reset password with token",
|
||||
description="Reset password with token",
|
||||
is_auth_required=False, # Public endpoint
|
||||
is_event_required=False,
|
||||
endpoint_function=authentication_reset_password,
|
||||
),
|
||||
EndpointFactoryConfig(
|
||||
url_prefix=prefix,
|
||||
url_endpoint="/disconnect",
|
||||
url_of_endpoint="/authentication/disconnect",
|
||||
endpoint="/disconnect",
|
||||
method="POST",
|
||||
summary="Disconnect user with access token",
|
||||
description="Disconnect user with access token",
|
||||
is_auth_required=True, # Needs token_dict
|
||||
is_event_required=False,
|
||||
endpoint_function=authentication_disconnect_user,
|
||||
),
|
||||
EndpointFactoryConfig(
|
||||
url_prefix=prefix,
|
||||
url_endpoint="/logout",
|
||||
url_of_endpoint="/authentication/logout",
|
||||
endpoint="/logout",
|
||||
method="POST",
|
||||
summary="Logout user with access token",
|
||||
description="Logout user with access token",
|
||||
is_auth_required=True, # Needs token_dict
|
||||
is_event_required=False,
|
||||
endpoint_function=authentication_logout_user,
|
||||
),
|
||||
EndpointFactoryConfig(
|
||||
url_prefix=prefix,
|
||||
url_endpoint="/remember",
|
||||
url_of_endpoint="/authentication/remember",
|
||||
endpoint="/remember",
|
||||
method="POST",
|
||||
summary="Refresh token with refresh token",
|
||||
description="Refresh token with refresh token",
|
||||
is_auth_required=True, # Needs token_dict
|
||||
is_event_required=False,
|
||||
endpoint_function=authentication_refresher_token,
|
||||
),
|
||||
EndpointFactoryConfig(
|
||||
url_prefix=prefix,
|
||||
url_endpoint="/forgot-password",
|
||||
url_of_endpoint="/authentication/forgot-password",
|
||||
endpoint="/forgot-password",
|
||||
method="POST",
|
||||
summary="Request password reset via email",
|
||||
description="Request password reset via email",
|
||||
is_auth_required=False, # Public endpoint
|
||||
is_event_required=False,
|
||||
endpoint_function=authentication_forgot_password,
|
||||
),
|
||||
EndpointFactoryConfig(
|
||||
url_prefix=prefix,
|
||||
url_endpoint="/avatar",
|
||||
url_of_endpoint="/authentication/avatar",
|
||||
endpoint="/avatar",
|
||||
method="POST",
|
||||
summary="Get user avatar with credentials",
|
||||
description="Get user avatar with credentials",
|
||||
is_auth_required=True, # Needs token_dict
|
||||
is_event_required=False,
|
||||
endpoint_function=authentication_download_avatar,
|
||||
),
|
||||
],
|
||||
).as_dict()
|
||||
138
ApiEvents/AuthServiceApi/auth/models.py
Normal file
138
ApiEvents/AuthServiceApi/auth/models.py
Normal file
@@ -0,0 +1,138 @@
|
||||
"""
|
||||
Authentication request models.
|
||||
"""
|
||||
|
||||
from typing import TYPE_CHECKING, Dict, Any, Literal, Optional, TypedDict
|
||||
from pydantic import BaseModel, Field, model_validator, RootModel, ConfigDict
|
||||
from ApiEvents.base_request_model import BaseRequestModel, DictRequestModel
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from fastapi import Request
|
||||
|
||||
|
||||
class TokenObjectBase(BaseModel):
|
||||
"""Base model for token objects."""
|
||||
user_type: str = Field(..., description="Type of user")
|
||||
user_id: str = Field(..., description="User ID")
|
||||
token: str = Field(..., description="Authentication token")
|
||||
permissions: Dict[str, Any] = Field(default_factory=dict, description="User permissions")
|
||||
|
||||
|
||||
|
||||
class LoginData(TypedDict):
|
||||
"""Type for login data."""
|
||||
domain: str
|
||||
access_key: str
|
||||
password: str
|
||||
remember_me: bool
|
||||
|
||||
|
||||
class LoginRequestModel(BaseRequestModel[LoginData]):
|
||||
"""Request model for login endpoint."""
|
||||
model_config = ConfigDict(
|
||||
json_schema_extra={
|
||||
"example": {
|
||||
"domain": "example.com",
|
||||
"access_key": "user@example",
|
||||
"password": "password",
|
||||
"remember_me": False
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
class LogoutData(TypedDict):
|
||||
"""Type for logout data."""
|
||||
token: str
|
||||
|
||||
|
||||
class LogoutRequestModel(BaseRequestModel[LogoutData]):
|
||||
"""Request model for logout endpoint."""
|
||||
model_config = ConfigDict(
|
||||
json_schema_extra={
|
||||
"example": {
|
||||
"token": "your-token-here"
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
class RememberData(TypedDict):
|
||||
"""Type for remember token data."""
|
||||
remember_token: str
|
||||
|
||||
|
||||
class RememberRequestModel(BaseRequestModel[RememberData]):
|
||||
"""Request model for remember token endpoint."""
|
||||
model_config = ConfigDict(
|
||||
json_schema_extra={
|
||||
"example": {
|
||||
"remember_token": "your-remember-token-here"
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
class ForgotData(TypedDict):
|
||||
"""Type for forgot password data."""
|
||||
email: str
|
||||
domain: str
|
||||
|
||||
|
||||
class ForgotRequestModel(BaseRequestModel[ForgotData]):
|
||||
"""Request model for forgot password endpoint."""
|
||||
model_config = ConfigDict(
|
||||
json_schema_extra={
|
||||
"example": {
|
||||
"email": "user@example.com",
|
||||
"domain": "example.com"
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
class ChangePasswordData(TypedDict):
|
||||
"""Type for change password data."""
|
||||
old_password: str
|
||||
new_password: str
|
||||
|
||||
|
||||
class ChangePasswordRequestModel(BaseRequestModel[ChangePasswordData]):
|
||||
"""Request model for change password endpoint."""
|
||||
model_config = ConfigDict(
|
||||
json_schema_extra={
|
||||
"example": {
|
||||
"old_password": "old-pass",
|
||||
"new_password": "new-pass"
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
class CreatePasswordData(TypedDict):
|
||||
"""Type for create password data."""
|
||||
token: str
|
||||
password: str
|
||||
|
||||
|
||||
class CreatePasswordRequestModel(BaseRequestModel[CreatePasswordData]):
|
||||
"""Request model for create password endpoint."""
|
||||
model_config = ConfigDict(
|
||||
json_schema_extra={
|
||||
"example": {
|
||||
"token": "password-creation-token",
|
||||
"password": "new-password"
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
class SelectionDataOccupant(TypedDict):
|
||||
"""Type for selection data."""
|
||||
build_living_space_uu_id: Optional[str]
|
||||
|
||||
|
||||
class SelectionDataEmployee(TypedDict):
|
||||
"""Type for selection data."""
|
||||
company_uu_id: Optional[str]
|
||||
|
||||
@@ -6,7 +6,7 @@ to be used by the dynamic route creation system.
|
||||
"""
|
||||
|
||||
from typing import Dict, List, Any
|
||||
from .auth.auth import AUTH_CONFIG
|
||||
from .auth.endpoints import AUTH_CONFIG
|
||||
|
||||
|
||||
# Registry of all route configurations
|
||||
|
||||
Reference in New Issue
Block a user