mongo updated

This commit is contained in:
berkay 2025-01-10 20:52:45 +03:00
parent d8685dd496
commit cecf1e69a2
66 changed files with 3597 additions and 857 deletions

View File

@ -1,93 +0,0 @@
# Git
.git
.gitignore
.gitattributes
# CI
.codeclimate.yml
.travis.yml
.taskcluster.yml
# Docker
docker-compose.yml
service_app/Dockerfile
.docker
.dockerignore
# Byte-compiled / optimized / DLL files
**/__pycache__/
**/*.py[cod]
# C extensions
*.so
# Distribution / packaging
.Python
service_app/env/
build/
develop-eggs/
dist/
downloads/
eggs/
lib/
lib64/
parts/
sdist/
var/
*.egg-info/
.installed.cfg
*.egg
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.cache
nosetests.xml
coverage.xml
# Translations
*.mo
*.pot
# Django stuff:
*.log
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# Virtual environment
service_app/.env
.venv/
venv/
# PyCharm
.idea
# Python mode for VIM
.ropeproject
**/.ropeproject
# Vim swap files
**/*.swp
# VS Code
.vscode/
test_application/

View File

@ -29,7 +29,7 @@ error_handlers = ErrorHandlers.create(
requests=Request, requests=Request,
exceptions=HTTPException, exceptions=HTTPException,
response_model=JSONResponse, response_model=JSONResponse,
status=status status=status,
) )
# Register error handlers with bound methods # Register error handlers with bound methods

View File

@ -0,0 +1,751 @@
import json
from typing import Union
from fastapi import status
from fastapi.requests import Request
from fastapi.exceptions import HTTPException
from api_objects import OccupantTokenObject, EmployeeTokenObject
from api_objects.auth.token_objects import CompanyToken, OccupantToken
from api_services.templates.password_templates import (
password_is_changed_template,
change_your_password_template,
)
from api_services.token_service import TokenService
from api_services.redis.functions import RedisActions
from api_library.response_handlers import ResponseHandler
from api_library.date_time_actions.date_functions import system_arrow
# from api_library.user_logger import UserLogger
from api_validations.validations_request import (
Login,
Logout,
ChangePassword,
EmployeeSelection,
OccupantSelection,
CreatePassword,
Forgot,
# ResetPassword,
# RefreshToken,
)
from api_validations.validations_response import (
AuthenticationLoginResponse,
AuthenticationRefreshResponse,
AuthenticationUserInfoResponse,
)
from ApiServices.api_handlers.auth_actions.auth import AuthActions
from api_configs import Auth, ApiStatic
from api_events.events.abstract_class import MethodToEvent, ActionsSchema
from databases import (
Companies,
Staff,
Duties,
Departments,
Employees,
BuildLivingSpace,
BuildParts,
Build,
Duty,
Event2Occupant,
Event2Employee,
Users,
UsersTokens,
OccupantTypes,
RelationshipEmployee2Build,
)
from api_services import (
send_email,
)
class AuthenticationLoginEventMethods(MethodToEvent):
event_type = "LOGIN"
event_description = "Login via domain and access key : [email] | [phone]"
event_category = "AUTHENTICATION"
__event_keys__ = {
"e672846d-cc45-4d97-85d5-6f96747fac67": "authentication_login_with_domain_and_creds",
}
__event_validation__ = {
"e672846d-cc45-4d97-85d5-6f96747fac67": AuthenticationLoginResponse,
}
@classmethod
def authentication_login_with_domain_and_creds(cls, data: Login, request: Request):
try:
access_dict = Users.login_user_with_credentials(data=data, request=request)
found_user = access_dict.get("user")
if not found_user:
# UserLogger.log_login_attempt(
# request,
# None,
# data.domain,
# data.access_key,
# success=False,
# error="Invalid credentials",
# )
return ResponseHandler.unauthorized("Invalid credentials")
# UserLogger.log_login_attempt(
# request, found_user.id, data.domain, data.access_key, success=True
# )
response_data = {
"access_token": access_dict.get("access_token"),
"refresh_token": access_dict.get("refresher_token"),
"access_object": access_dict.get("access_object"),
"user": found_user.get_dict(),
}
return ResponseHandler.success(
message="User logged in successfully",
data=response_data,
)
except Exception as e:
# UserLogger.log_login_attempt(
# request, None, data.domain, data.access_key, success=False, error=str(e)
# )
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail=str(e))
class AuthenticationSelectEventMethods(MethodToEvent):
event_type = "LOGIN"
event_description = "Select Employee Duty or Occupant Type"
event_category = "AUTHENTICATION"
__event_keys__ = {
"cee96b9b-8487-4e9f-aaed-2e8c79687bf9": "authentication_select_company_or_occupant_type",
}
__event_validation__ = {
"cee96b9b-8487-4e9f-aaed-2e8c79687bf9": "authentication_select_company_or_occupant_type",
}
@classmethod
def _handle_employee_selection(
cls, data: EmployeeSelection, token_dict: EmployeeTokenObject, request: Request
):
"""Handle employee company selection"""
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")
@classmethod
def _handle_occupant_selection(
cls, data: OccupantSelection, token_dict: OccupantTokenObject, request: Request
):
"""Handle occupant type selection"""
# Get occupant type
occupant_type = OccupantTypes.filter_by_one(
system=True, uu_id=data.occupant_uu_id
).data
if not occupant_type:
return ResponseHandler.not_found("Occupant Type not found")
# Get build part
build_part = BuildParts.filter_by_one(
system=True, uu_id=data.build_part_uu_id
).data
if not build_part:
return ResponseHandler.not_found("Build Part not found")
# Get build and company info
build = Build.filter_one(Build.id == build_part.build_id).data
related_company = RelationshipEmployee2Build.filter_one(
RelationshipEmployee2Build.member_id == build.id
).data
company_related = Companies.filter_one(
Companies.id == related_company.company_id
).data
responsible_employee = Employees.filter_one(
Employees.id == related_company.employee_id
).data
# Get selected occupant type
selected_occupant_type = BuildLivingSpace.filter_one(
BuildLivingSpace.occupant_type == occupant_type.id,
BuildLivingSpace.person_id == token_dict.person_id,
BuildLivingSpace.build_parts_id == build_part.id,
).data
if not selected_occupant_type:
return ResponseHandler.not_found("Selected occupant type not found")
# Get reachable events
reachable_event_list_id = Event2Occupant.get_event_id_by_build_living_space_id(
build_living_space_id=selected_occupant_type.id
)
# Create occupant token
occupant_token = OccupantToken(
living_space_id=selected_occupant_type.id,
living_space_uu_id=selected_occupant_type.uu_id.__str__(),
occupant_type_id=occupant_type.id,
occupant_type_uu_id=occupant_type.uu_id.__str__(),
occupant_type=occupant_type.occupant_type,
build_id=build.id,
build_uuid=build.uu_id.__str__(),
build_part_id=build_part.id,
build_part_uuid=build_part.uu_id.__str__(),
responsible_employee_id=responsible_employee.id,
responsible_employee_uuid=responsible_employee.uu_id.__str__(),
responsible_company_id=company_related.id,
responsible_company_uuid=company_related.uu_id.__str__(),
reachable_event_list_id=reachable_event_list_id,
)
# Update Redis
AuthActions.update_selected_to_redis(
request=request, add_payload=occupant_token
)
return ResponseHandler.success("Occupant selected successfully")
@classmethod
def authentication_select_company_or_occupant_type(
cls,
request: Request,
data: Union[EmployeeSelection, OccupantSelection],
token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
):
"""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
)
class AuthenticationCheckTokenEventMethods(MethodToEvent):
event_type = "LOGIN"
event_description = "Check Token is valid for user"
event_category = "AUTHENTICATION"
__event_keys__ = {
"73d77e45-a33f-4f12-909e-3b56f00d8a12": "authentication_check_token_is_valid",
}
__event_validation__ = {
"73d77e45-a33f-4f12-909e-3b56f00d8a12": "authentication_check_token_is_valid",
}
@classmethod
def authentication_check_token_is_valid(cls, request: Request):
try:
if RedisActions.get_object_via_access_key(request=request):
return ResponseHandler.success("Access Token is valid")
except HTTPException:
return ResponseHandler.unauthorized("Access Token is NOT valid")
class AuthenticationRefreshEventMethods(MethodToEvent):
event_type = "LOGIN"
event_description = "Refresh user info using access token"
event_category = "AUTHENTICATION"
__event_keys__ = {
"48379bb2-ba81-4d8e-a9dd-58837cfcbf67": "authentication_refresh_user_info",
}
__event_validation__ = {
"48379bb2-ba81-4d8e-a9dd-58837cfcbf67": AuthenticationRefreshResponse,
}
@classmethod
def authentication_refresh_user_info(
cls,
request: Request,
token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
):
try:
access_token = request.headers.get(Auth.ACCESS_TOKEN_TAG)
if not access_token:
return ResponseHandler.unauthorized()
# Get user and token info
found_user = Users.filter_one(Users.uu_id == token_dict.user_uu_id).data
if not found_user:
return ResponseHandler.not_found("User not found")
user_token = UsersTokens.filter_one(
UsersTokens.domain == found_user.domain_name,
UsersTokens.user_id == found_user.id,
UsersTokens.token_type == "RememberMe",
).data
response_data = {
"access_token": access_token,
"refresh_token": getattr(user_token, "token", None),
"user": found_user.get_dict(),
}
return ResponseHandler.success(
"User info refreshed successfully",
data=response_data,
)
except Exception as e:
return ResponseHandler.error(str(e))
class AuthenticationChangePasswordEventMethods(MethodToEvent):
event_type = "LOGIN"
event_description = "Change password with access token"
event_category = "AUTHENTICATION"
__event_keys__ = {
"f09f7c1a-bee6-4e32-8444-962ec8f39091": "authentication_change_password",
}
__event_validation__ = {
"f09f7c1a-bee6-4e32-8444-962ec8f39091": "authentication_change_password",
}
@classmethod
def authentication_change_password(
cls,
request: Request,
data: ChangePassword,
token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
):
try:
if not isinstance(token_dict, EmployeeTokenObject):
return ResponseHandler.unauthorized(
"Only employees can change password"
)
found_user = Users.filter_one(Users.uu_id == token_dict.user_uu_id).data
if not found_user:
return ResponseHandler.not_found("User not found")
if not found_user.check_password(data.old_password):
# UserLogger.log_password_change(
# request,
# found_user.id,
# "change",
# success=False,
# error="Invalid old password",
# )
return ResponseHandler.unauthorized("Old password is incorrect")
found_user.set_password(data.new_password)
# UserLogger.log_password_change(
# request, found_user.id, "change", success=True
# )
return ResponseHandler.success("Password changed successfully")
except Exception as e:
# UserLogger.log_password_change(
# request,
# found_user.id if found_user else None,
# "change",
# success=False,
# error=str(e),
# )
return ResponseHandler.error(str(e))
class AuthenticationCreatePasswordEventMethods(MethodToEvent):
event_type = "LOGIN"
event_description = "Create password with password reset token requested via email"
event_category = "AUTHENTICATION"
__event_keys__ = {
"c519f9af-92e1-47b2-abf7-5a3316d075f7": "authentication_create_password",
}
__event_validation__ = {
"c519f9af-92e1-47b2-abf7-5a3316d075f7": "authentication_create_password",
}
@classmethod
def authentication_create_password(cls, data: CreatePassword):
if not data.re_password == data.password:
raise HTTPException(
status_code=status.HTTP_406_NOT_ACCEPTABLE, detail="Password must match"
)
if found_user := Users.filter_one(
Users.password_token == data.password_token
).data:
found_user: Users = found_user
found_user.create_password(found_user=found_user, password=data.password)
found_user.password_token = ""
found_user.save()
# send_email_completed = send_email(
# subject=f"Dear {found_user.user_tag}, your password has been changed.",
# receivers=[str(found_user.email)],
# html=password_is_changed_template(user_name=found_user.user_tag),
# )
# if not send_email_completed:
# raise HTTPException(
# status_code=400, detail="Email can not be sent. Try again later"
# )
return ResponseHandler.success(
"Password is created successfully",
data=found_user.get_dict(),
)
return ResponseHandler.not_found("Record not found")
class AuthenticationDisconnectUserEventMethods(MethodToEvent):
event_type = "LOGIN"
event_description = "Disconnect all sessions of user in access token"
event_category = "AUTHENTICATION"
__event_keys__ = {
"8b586848-2fb3-4161-abbe-642157eec7ce": "authentication_disconnect_user",
}
__event_validation__ = {
"8b586848-2fb3-4161-abbe-642157eec7ce": "authentication_disconnect_user",
}
@classmethod
def authentication_disconnect_user(
cls, data: Logout, token_dict: Union[EmployeeTokenObject, OccupantTokenObject]
):
found_user = Users.filter_one(Users.uu_id == token_dict.user_uu_id).data
if not found_user:
return ResponseHandler.not_found("User not found")
if already_tokens := RedisActions.get_object_via_user_uu_id(
user_id=str(found_user.uu_id)
):
for key, token_user in already_tokens.items():
RedisActions.delete(key)
selected_user = Users.filter_one(
Users.uu_id == token_user.get("uu_id"),
).data
selected_user.remove_refresher_token(
domain=data.domain, disconnect=True
)
return ResponseHandler.success(
"All sessions are disconnected",
data=selected_user.get_dict(),
)
return ResponseHandler.not_found("Invalid data")
class AuthenticationLogoutEventMethods(MethodToEvent):
event_type = "LOGIN"
event_description = "Logout only single session of user which domain is provided"
event_category = "AUTHENTICATION"
__event_keys__ = {
"5cc22e4e-a0f7-4077-be41-1871feb3dfd1": "authentication_logout_user",
}
__event_validation__ = {
"5cc22e4e-a0f7-4077-be41-1871feb3dfd1": "authentication_logout_user",
}
@classmethod
def authentication_logout_user(
cls, request: Request, data: Logout, token_dict: dict = None
):
token_user = None
if already_tokens := RedisActions.get_object_via_access_key(request=request):
for key in already_tokens:
token_user = RedisActions.get_json(key)
if token_user.get("domain") == data.domain:
RedisActions.delete(key)
selected_user = Users.filter_one(
Users.uu_id == token_user.get("uu_id"),
).data
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")
class AuthenticationRefreshTokenEventMethods(MethodToEvent):
event_type = "LOGIN"
event_description = "Refresh access token with refresher token"
event_category = "AUTHENTICATION"
__event_keys__ = {
"c90f3334-10c9-4181-b5ff-90d98a0287b2": "authentication_refresher_token",
}
__event_validation__ = {
"c90f3334-10c9-4181-b5ff-90d98a0287b2": AuthenticationRefreshResponse,
}
@classmethod
def authentication_refresher_token(
# cls, request: Request, data: RefreshToken, token_dict: dict = None
cls,
request: Request,
data,
token_dict: dict = None,
):
token_refresher = UsersTokens.filter_by_one(
token=data.refresh_token,
domain=data.domain,
**UsersTokens.valid_record_dict,
).data
if not token_refresher:
return ResponseHandler.not_found("Invalid data")
if found_user := Users.filter_one(
Users.id == token_refresher.user_id,
).data:
found_user: Users = found_user
access_key = AuthActions.save_access_token_to_redis(
request=request, found_user=found_user, domain=data.domain
)
found_user.last_agent = request.headers.get("User-Agent", None)
found_user.last_platform = request.headers.get("Origin", None)
found_user.last_remote_addr = getattr(
request, "remote_addr", None
) or request.headers.get("X-Forwarded-For", None)
found_user.last_seen = str(system_arrow.now())
response_data = {
"access_token": access_key,
"refresh_token": data.refresh_token,
}
return ResponseHandler.success(
"User is logged in successfully via refresher token",
data=response_data,
)
return ResponseHandler.not_found("Invalid data")
class AuthenticationForgotPasswordEventMethods(MethodToEvent):
event_type = "LOGIN"
event_description = "Send an email to user for a valid password reset token"
event_category = "AUTHENTICATION"
__event_keys__ = {
"e3ca6e24-b9f8-4127-949c-3bfa364e3513": "authentication_forgot_password",
}
__event_validation__ = {
"e3ca6e24-b9f8-4127-949c-3bfa364e3513": "authentication_forgot_password",
}
@classmethod
def authentication_forgot_password(
cls,
request: Request,
data: Forgot,
):
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
)
forgot_link = ApiStatic.forgot_link(forgot_key=forgot_key)
send_email_completed = send_email(
subject=f"Dear {found_user.user_tag}, your forgot password link has been sent.",
receivers=[str(found_user.email)],
html=change_your_password_template(
user_name=found_user.user_tag, forgot_link=forgot_link
),
)
if not send_email_completed:
raise HTTPException(
status_code=400, detail="Email can not be sent. Try again later"
)
found_user.password_token = forgot_key
found_user.password_token_is_valid = str(system_arrow.shift(days=1))
found_user.save()
return ResponseHandler.success(
"Password is change link is sent to your email or phone",
data={},
)
class AuthenticationResetPasswordEventMethods(MethodToEvent):
event_type = "UPDATE"
__event_keys__ = {
"af9e121e-24bb-44ac-a616-471d5754360e": "authentication_reset_password",
}
@classmethod
def authentication_reset_password(cls, data: Forgot):
from sqlalchemy import or_
found_user = Users.query.filter(
or_(
Users.email == str(data.access_key).lower(),
Users.phone_number == str(data.access_key).replace(" ", ""),
),
).first()
if not found_user:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Given access key or domain is not matching with the any user record.",
)
reset_password_token = found_user.reset_password_token(found_user=found_user)
send_email_completed = send_email(
subject=f"Dear {found_user.user_tag}, a password reset request has been received.",
receivers=[str(found_user.email)],
html=change_your_password_template(
user_name=found_user.user_tag,
forgot_link=ApiStatic.forgot_link(forgot_key=reset_password_token),
),
)
if not send_email_completed:
raise found_user.raise_http_exception(
status_code=400, message="Email can not be sent. Try again later"
)
return ResponseHandler.success(
"Password change link is sent to your email or phone",
data=found_user.get_dict(),
)
class AuthenticationDownloadAvatarEventMethods(MethodToEvent):
event_type = "LOGIN"
event_description = "Download avatar icon and profile info of user"
event_category = "AUTHENTICATION"
__event_keys__ = {
"c140cd5f-307f-4046-a93e-3ade032a57a7": "authentication_download_avatar",
}
__event_validation__ = {
"c140cd5f-307f-4046-a93e-3ade032a57a7": AuthenticationUserInfoResponse,
}
@classmethod
def authentication_download_avatar(
cls, token_dict: Union[EmployeeTokenObject, OccupantTokenObject]
):
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))
)
expired_int = (
system_arrow.now() - system_arrow.get(str(found_user.expiry_ends))
).days
user_info = {
"lang": token_dict.lang,
"full_name": found_user.person.full_name,
"avatar": found_user.avatar,
"remember_me": found_user.remember_me,
"expiry_ends": str(found_user.expiry_ends),
"expired_str": expired_starts,
"expired_int": int(expired_int),
}
return ResponseHandler.success(
"Avatar and profile is shared via user credentials",
data=user_info,
)
return ResponseHandler.not_found("Invalid data")
AuthenticationLoginEventMethod = AuthenticationLoginEventMethods(
action=ActionsSchema(endpoint="/authentication/login")
)
AuthenticationSelectEventMethod = AuthenticationSelectEventMethods(
action=ActionsSchema(endpoint="/authentication/select")
)
AuthenticationCheckTokenEventMethod = AuthenticationCheckTokenEventMethods(
action=ActionsSchema(endpoint="/authentication/valid")
)
AuthenticationRefreshEventMethod = AuthenticationRefreshEventMethods(
action=ActionsSchema(endpoint="/authentication/refresh")
)
AuthenticationChangePasswordEventMethod = AuthenticationChangePasswordEventMethods(
action=ActionsSchema(endpoint="/authentication/change_password")
)
AuthenticationCreatePasswordEventMethod = AuthenticationCreatePasswordEventMethods(
action=ActionsSchema(endpoint="/authentication/create_password")
)
AuthenticationDisconnectUserEventMethod = AuthenticationDisconnectUserEventMethods(
action=ActionsSchema(endpoint="/authentication/disconnect")
)
AuthenticationLogoutEventMethod = AuthenticationLogoutEventMethods(
action=ActionsSchema(endpoint="/authentication/logout")
)
AuthenticationRefreshTokenEventMethod = AuthenticationRefreshTokenEventMethods(
action=ActionsSchema(endpoint="/authentication/refresher")
)
AuthenticationForgotPasswordEventMethod = AuthenticationForgotPasswordEventMethods(
action=ActionsSchema(endpoint="/authentication/forgot")
)
AuthenticationDownloadAvatarEventMethod = AuthenticationDownloadAvatarEventMethods(
action=ActionsSchema(endpoint="/authentication/avatar")
)
AuthenticationResetPasswordEventMethod = AuthenticationResetPasswordEventMethods(
action=ActionsSchema(endpoint="/authentication/reset_password")
)

View File

@ -15,8 +15,8 @@ class MiddlewareLogs:
def log_middlewares_exception(endpoint, token_user, message, request): def log_middlewares_exception(endpoint, token_user, message, request):
MiddlewareLogs.log_error( MiddlewareLogs().log_error(
str( log_message=json.dumps(
{ {
"log_type": "Authentication", "log_type": "Authentication",
"log_message": message, "log_message": message,
@ -29,7 +29,7 @@ def log_middlewares_exception(endpoint, token_user, message, request):
} }
), ),
} }
) ),
) )
@ -72,9 +72,9 @@ def check_if_path_secure(request, insecure_paths) -> bool:
def check_if_token_is_not_valid(request, endpoint_name): def check_if_token_is_not_valid(request, endpoint_name):
from api_services.redis.functions import get_object_via_access_key from api_services.redis.functions import RedisActions
token_user = get_object_via_access_key(request) token_user = RedisActions.get_object_via_access_key(request)
if not token_user: if not token_user:
return "Session geçerli değil. Lütfen tekrar giriş yapınız.", token_user return "Session geçerli değil. Lütfen tekrar giriş yapınız.", token_user

View File

@ -1,5 +1,5 @@
[project] [project]
name = "wag-managment-api-service-version-3" name = "wag-managment-api-service-version-3-auth-service"
version = "0.1.0" version = "0.1.0"
description = "Wag Python API Service" description = "Wag Python API Service"
readme = "README.md" readme = "README.md"

View File

@ -12,7 +12,7 @@ from api_validations.validations_request import (
OccupantSelection, OccupantSelection,
EmployeeSelection, EmployeeSelection,
) )
from api_events.events import ( from ApiServices.AuthService.application.authentication import (
AuthenticationLoginEventMethod, AuthenticationLoginEventMethod,
AuthenticationSelectEventMethod, AuthenticationSelectEventMethod,
AuthenticationCheckTokenEventMethod, AuthenticationCheckTokenEventMethod,

View File

@ -2,35 +2,35 @@ FROM python:3.12-slim-bookworm
ENV PYTHONDONTWRITEBYTECODE 1 ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1 ENV PYTHONUNBUFFERED 1
ENV PYTHONPATH=/service_app
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/ COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/
WORKDIR /service_app
# Create logs directory # Create logs directory
RUN mkdir -p /service_app/logs RUN mkdir -p /service_app/logs
COPY ApiServices/EventService/pyproject.toml . COPY ApiServices/EventService/pyproject.toml .
RUN uv venv RUN uv venv .venv
RUN uv pip install -r pyproject.toml RUN . .venv/bin/activate && uv pip install -r pyproject.toml
COPY ApiServices/EventService ./service_app COPY ApiServices ./ApiServices
COPY ApiServices/api_handlers ./service_app/api_handlers COPY databases ./databases
COPY api_services ./api_services
COPY api_objects ./api_objects
COPY api_configs ./api_configs
COPY api_events ./api_events
COPY api_library ./api_library
COPY api_validations ./api_validations
COPY databases ./service_app/databases WORKDIR /service_app/ApiServices/EventService
COPY api_services ./service_app/api_services
COPY api_objects ./service_app/api_objects
COPY api_configs ./service_app/api_configs
COPY api_events ./service_app/api_events
COPY api_library ./service_app/api_library
COPY api_validations ./service_app/api_validations
WORKDIR /service_app # Create startup script
RUN echo '#!/bin/bash\n\
source /service_app/.venv/bin/activate\n\
exec python app.py' > /service_app/start.sh && \
chmod +x /service_app/start.sh
CMD ["uv", "run", "app.py"] CMD ["/service_app/start.sh"]
# Old File
#FROM python:3.10
#RUN pip install --upgrade pip
#RUN pip install --no-cache-dir --upgrade -r requirements.txt
#CMD ["python", "-m", "app"]

View File

@ -2,7 +2,8 @@ import uvicorn
import routers import routers
from fastapi.middleware.cors import CORSMiddleware from fastapi.middleware.cors import CORSMiddleware
from fastapi.exceptions import HTTPException from fastapi import Request, HTTPException, status
from fastapi.responses import JSONResponse
from middlewares.token_middleware import AuthHeaderMiddleware from middlewares.token_middleware import AuthHeaderMiddleware
from application.create_file import create_app from application.create_file import create_app
@ -23,8 +24,17 @@ app.add_middleware(
) )
app.add_middleware(AuthHeaderMiddleware) app.add_middleware(AuthHeaderMiddleware)
app.add_exception_handler(HTTPException, ErrorHandlers.exception_handler_http) # Initialize error handlers
app.add_exception_handler(Exception, ErrorHandlers.exception_handler_exception) error_handlers = ErrorHandlers.create(
requests=Request,
exceptions=HTTPException,
response_model=JSONResponse,
status=status,
)
# Register error handlers with bound methods
app.add_exception_handler(HTTPException, error_handlers.exception_handler_http)
app.add_exception_handler(Exception, error_handlers.exception_handler_exception)
if __name__ == "__main__": if __name__ == "__main__":
uvicorn_config = { uvicorn_config = {

View File

@ -72,9 +72,9 @@ def check_if_path_secure(request, insecure_paths) -> bool:
def check_if_token_is_not_valid(request, endpoint_name): def check_if_token_is_not_valid(request, endpoint_name):
from api_services.redis.functions import get_object_via_access_key from api_services.redis.functions import RedisActions
token_user = get_object_via_access_key(request) token_user = RedisActions.get_object_via_access_key(request)
if not token_user: if not token_user:
return "Session geçerli değil. Lütfen tekrar giriş yapınız.", token_user return "Session geçerli değil. Lütfen tekrar giriş yapınız.", token_user

View File

@ -1,5 +1,5 @@
[project] [project]
name = "wag-managment-api-service-version-3" name = "wag-managment-api-service-version-3-event-service"
version = "0.1.0" version = "0.1.0"
description = "Wag Python API Service" description = "Wag Python API Service"
readme = "README.md" readme = "README.md"

View File

@ -1 +1,101 @@
__all__ = [] from .account.router import account_records_router
from .people.router import people_router
from .users.router import user_route
from .company.company.router import company_route
from .company.department.router import department_route
from .company.duty.router import duty_route
from .company.duties.router import duties_route
from .building.build.router import build_route
from .building.buildparts.router import build_parts_route
from .building.buildarea.router import build_area_route
from .building.buildsites.router import build_sites_route
from .building.buildtypes.router import build_types_route
from .building.livingspaces.router import build_living_space
from .decision_book.decision_book.router import build_decision_book_route
from .decision_book.decision_book_person.router import (
build_decision_book_people_route,
)
from .decision_book.decision_book_items.router import (
build_decision_book_items_route,
)
from .project_decision_book.project_decision_book.router import (
build_project_decision_book_route,
)
from .project_decision_book.project_decision_book_person.router import (
build_project_decision_book_person_route,
)
from .api.router import internal_route
from .events.events.router import event_route
from .company.staff.router import staff_route
from .company.employee.router import employee_route
from .events.events.bind_events_router import bind_events_route
from .events.modules.router import modules_route
from .events.modules.bind_events_router import bind_modules_route
from .events.services.bind_services_router import bind_services_route
from .events.services.router import services_route
from .rules.router import endpoint_restriction_route
from .address.address.router import address_router
from .address.post_code.router import post_code_router
from .application.enums_and_drops.router import enums_route
from .application.occupants.router import occupant_types_route
from .decision_book.decision_book_invitations.router import (
build_decision_book_invitations,
)
from .decision_book.project_decision_book.router import (
build_decision_book_project_route,
)
from .decision_book.project_decision_book_items.router import (
build_decision_book_project_items_route,
)
from .decision_book.project_decision_book_person.router import (
build_decision_book_project_people_route,
)
from .validations.router import validations_route
__all__ = [
"account_records_router",
"enums_route",
"occupant_types_route",
"internal_route",
"address_router",
"post_code_router",
"duty_route",
"duties_route",
"people_router",
"user_route",
"company_route",
"department_route",
"build_route",
"build_parts_route",
"build_sites_route",
"build_area_route",
"build_living_space",
"build_decision_book_route",
"build_decision_book_people_route",
"build_decision_book_items_route",
"build_project_decision_book_route",
"staff_route",
"employee_route",
"build_types_route",
"bind_events_route",
"event_route",
"modules_route",
"bind_services_route",
"bind_modules_route",
"services_route",
"build_project_decision_book_person_route",
"endpoint_restriction_route",
"build_decision_book_invitations",
"build_decision_book_project_route",
"build_decision_book_project_items_route",
"build_decision_book_project_people_route",
"validations_route",
]

View File

@ -0,0 +1,57 @@
from fastapi.routing import APIRouter
from fastapi.requests import Request
from api_validations.validations_request import (
InsertAccountRecord,
UpdateAccountRecord,
SearchAddress,
ListOptions,
PatchRecord,
)
from ApiServices.api_handlers.auth_actions.token import parse_token_object_to_dict
account_records_router = APIRouter(prefix="/account/records", tags=["Account Records"])
account_records_router.include_router(account_records_router, include_in_schema=True)
@account_records_router.post(path="/list", summary="List Active/Delete/Confirm Address")
def address_list(request: Request, list_options: ListOptions):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(list_options=list_options, token_dict=token_dict)
@account_records_router.post(
path="/create", summary="Create Address with given auth levels"
)
def address_create(request: Request, data: InsertAccountRecord):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(data=data, token_dict=token_dict)
@account_records_router.post(
path="/search", summary="Search Address with given auth levels"
)
def address_search(request: Request, data: SearchAddress):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(data=data, token_dict=token_dict)
@account_records_router.post(
path="/update/{address_uu_id}", summary="Update Address with given auth levels"
)
def address_update(request: Request, address_uu_id: str, data: UpdateAccountRecord):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(
data=data, address_uu_id=address_uu_id, token_dict=token_dict
)
@account_records_router.patch(
path="/patch/{address_uu_id}", summary="Update Address Active/Delete/Confirm"
)
def address_patch(request: Request, address_uu_id: str, data: PatchRecord):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(
data=data, address_uu_id=address_uu_id, token_dict=token_dict
)

View File

@ -0,0 +1,54 @@
from fastapi.routing import APIRouter
from fastapi.requests import Request
from api_validations.validations_request import (
InsertAddress,
UpdateAddress,
SearchAddress,
ListOptions,
PatchRecord,
)
from ApiServices.api_handlers.auth_actions.token import parse_token_object_to_dict
address_router = APIRouter(prefix="/address", tags=["Address"])
address_router.include_router(address_router, include_in_schema=True)
@address_router.post(path="/list", summary="List Active/Delete/Confirm Address")
def address_list(request: Request, list_options: ListOptions):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(list_options=list_options, token_dict=token_dict)
@address_router.post(path="/create", summary="Create Address with given auth levels")
def address_create(request: Request, data: InsertAddress):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(data=data, token_dict=token_dict)
@address_router.post(path="/search", summary="Search Address with given auth levels")
def address_search(request: Request, data: SearchAddress):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(data=data, token_dict=token_dict)
@address_router.post(
path="/update/{address_uu_id}", summary="Update Address with given auth levels"
)
def address_update(request: Request, address_uu_id: str, data: UpdateAddress):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(
data=data, address_uu_id=address_uu_id, token_dict=token_dict
)
@address_router.patch(
path="/patch/{address_uu_id}", summary="Update Address Active/Delete/Confirm"
)
def address_patch(request: Request, address_uu_id: str, data: PatchRecord):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(
data=data, address_uu_id=address_uu_id, token_dict=token_dict
)

View File

@ -0,0 +1,46 @@
from fastapi.routing import APIRouter
from fastapi.requests import Request
from api_validations.validations_request import (
InsertPostCode,
UpdatePostCode,
ListOptions,
PatchRecord,
)
from ApiServices.api_handlers.auth_actions.token import parse_token_object_to_dict
post_code_router = APIRouter(prefix="/postcode", tags=["Post Code"])
post_code_router.include_router(post_code_router, include_in_schema=True)
@post_code_router.post(path="/list", summary="List Active/Delete/Confirm PostCode")
def post_code_list(request: Request, list_options: ListOptions):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(list_options=list_options, token_dict=token_dict)
@post_code_router.post(path="/create", summary="Create PostCode with given auth levels")
def post_code_create(request: Request, data: InsertPostCode):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(data=data, token_dict=token_dict)
@post_code_router.post(
path="/update/{post_code_uu_id}", summary="Update PostCode with given auth levels"
)
def post_code_update(request: Request, post_code_uu_id: str, data: UpdatePostCode):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(
data=data, post_code_uu_id=post_code_uu_id, token_dict=token_dict
)
@post_code_router.patch(
path="/patch/{post_code_uu_id}", summary="Update PostCode Active/Delete/Confirm"
)
def post_code_patch(request: Request, post_code_uu_id: str, data: PatchRecord):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(
data=data, post_code_uu_id=post_code_uu_id, token_dict=token_dict
)

View File

@ -0,0 +1,74 @@
import json
import typing
import zlib
from base64 import b64decode
from fastapi import status
from fastapi.routing import APIRouter
from fastapi.responses import JSONResponse
from fastapi.requests import Request
from pydantic import BaseModel
internal_route = APIRouter(prefix="/internal", tags=["Internal"])
internal_route.include_router(internal_route, include_in_schema=False)
# class ApiReceive(BaseModel):
# data: str
#
#
# class BankReceive(BaseModel):
# import_file_name: str
# iban: str
# bank_date: str
# channel_branch: str
# currency: typing.Optional[str] = "TL"
# currency_value: float
# bank_balance: float
# additional_balance: float
# process_name: str
# process_type: str
# process_comment: str
# bank_reference_code: str
# #
#
# @internal_route.post(
# path="/isbank/retreive",
# summary="Receive isbank xls service from mail reader service",
# )
# def is_bank_retrieve_account_records(request: Request, bank_data: ApiReceive):
# from databases import AccountRecords
#
# data_dict = bank_data.model_dump()
# data_bulk = json.loads(zlib.decompress(b64decode(data_dict["data"])))
# print("data_bulk", data_bulk)
# new_record_list = []
# for data_keys in data_bulk: # data_bulk is a dict
# for data_dict in data_bulk[data_keys]: # data_bulk[data_keys] is a list
# data_dict["bank_balance"] = data_dict.pop("balance")
# data_dict["import_file_name"] = str(data_keys)
# print("data_dict before pyd", data_dict)
# data_dict = BankReceive(**data_dict).model_dump()
# print("data_dict after pyd", data_dict)
# if new_account_record := AccountRecords.find_or_create(**data_dict):
# print("new_account_record.is_found", new_account_record.is_found)
# if not new_account_record.is_found:
# new_record_list.append(new_account_record.get_dict())
# if new_record_list:
# return JSONResponse(
# content={
# "completed": True,
# "message": "Create Bank Record",
# "data": new_record_list,
# },
# status_code=status.HTTP_200_OK,
# )
# return JSONResponse(
# content={
# "completed": False,
# "message": "Record already exist or can not be created",
# },
# status_code=status.HTTP_406_NOT_ACCEPTABLE,
# )

View File

@ -0,0 +1,98 @@
from fastapi import status
from fastapi.routing import APIRouter
from fastapi.exceptions import HTTPException
from fastapi.responses import JSONResponse
from databases import ApiEnumDropdown
from api_validations.validations_request import (
SingleEnumClassKey,
SingleEnumUUID,
SingleEnumOnlyClass,
)
enums_route = APIRouter(prefix="/enums", tags=["Enums and Dropdowns of API"])
enums_route.include_router(enums_route, include_in_schema=False)
@enums_route.post(path="/get/key", summary="Get single enum via key")
def get_single_enum_via_key_and_class(data: SingleEnumClassKey):
enum = ApiEnumDropdown.query.filter(
ApiEnumDropdown.enum_class.ilike(data.class_name),
ApiEnumDropdown.key.ilike(data.key_name),
).populate_existing()
if record := enum.first():
return JSONResponse(
content={
"completed": True,
"message": "Get single enum via key",
"data": record.get_enum_dict() if enum else None,
},
status_code=status.HTTP_200_OK,
)
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Enum not found",
)
@enums_route.post(path="/get/uu_id", summary="Get single enum via uu_id")
def get_single_enum_via_uuid(data: SingleEnumUUID):
enum = ApiEnumDropdown.query.filter(
ApiEnumDropdown.uu_id == data.uu_id
).populate_existing()
if records := enum.first():
return JSONResponse(
content={
"completed": True,
"message": "Get single enum via uu_id",
"data": records.get_enum_dict(),
},
status_code=status.HTTP_200_OK,
)
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Enum not found",
)
@enums_route.post(path="/list/class", summary="Get all enums via class")
def list_all_enums_with_class(data: SingleEnumOnlyClass):
enums = ApiEnumDropdown.query.filter(
ApiEnumDropdown.enum_class.ilike(data.class_name or "")
).populate_existing()
if records := enums.all():
records_list = [record.get_enum_dict() for record in records]
return JSONResponse(
content={
"completed": True,
"message": "Get all enums via class",
"count": len(records_list),
"data": records_list,
},
status_code=status.HTTP_200_OK,
)
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Enums not found",
)
@enums_route.post(path="/list/all", summary="Get all enums")
def list_all_enums():
enums = ApiEnumDropdown.query.filter().populate_existing()
if records := enums.all():
records_list = [record.get_enum_dict() for record in records]
return JSONResponse(
content={
"completed": True,
"count": len(records_list),
"message": "Get all enums",
"data": records_list,
},
status_code=status.HTTP_200_OK,
)
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Enums can not be listed",
)

View File

@ -0,0 +1,58 @@
from fastapi import status
from fastapi.routing import APIRouter
from fastapi.exceptions import HTTPException
from fastapi.responses import JSONResponse
from databases import OccupantTypes
from api_validations.validations_request import (
SingleOccupantTypeClassKey,
SingleOccupantTypeUUID,
)
occupant_types_route = APIRouter(prefix="/occupant_types", tags=["Occupant Types"])
occupant_types_route.include_router(occupant_types_route, include_in_schema=False)
@occupant_types_route.post(
path="/get/code", summary="Get single occupant type via code"
)
def get_single_occupant_type_via_code(data: SingleOccupantTypeClassKey):
occupant_type = OccupantTypes.query.filter(
OccupantTypes.occupant_code.ilike(data.type_code)
).populate_existing()
if record := occupant_type.first():
return JSONResponse(
content={
"completed": True,
"message": "Get single occupant type via code",
"data": record.get_dict() if record else None,
},
status_code=status.HTTP_200_OK,
)
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Occupant type not found",
)
@occupant_types_route.post(
path="/get/uu_id", summary="Get single occupant type via uu_id"
)
def get_single_occupant_type_via_uuid(data: SingleOccupantTypeUUID):
occupant_type = OccupantTypes.query.filter(
OccupantTypes.uu_id == data.uu_id
).populate_existing()
if records := occupant_type.first():
return JSONResponse(
content={
"completed": True,
"message": "Get single occupant type via uu_id",
"data": records.get_dict(),
},
status_code=status.HTTP_200_OK,
)
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Occupant type not found",
)

View File

@ -0,0 +1,49 @@
from fastapi.routing import APIRouter
from fastapi.requests import Request
from api_validations.validations_request import (
InsertBuildArea,
UpdateBuildArea,
PatchRecord,
ListOptions,
)
from ApiServices.api_handlers.auth_actions.token import parse_token_object_to_dict
build_area_route = APIRouter(prefix="/building/area", tags=["Building Area"])
build_area_route.include_router(build_area_route, include_in_schema=True)
@build_area_route.post(path="/list", summary="List Active/Delete/Confirm Build Parts")
def build_area_list(request: Request, list_options: ListOptions):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(list_options=list_options, token_dict=token_dict)
@build_area_route.post(
path="/create", summary="Create BuildParts with given auth levels"
)
def build_area_create(request: Request, data: InsertBuildArea):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(data=data, token_dict=token_dict)
@build_area_route.post(
path="/update/{build_uu_id}", summary="Update BuildParts with given auth levels"
)
def build_area_update(request: Request, build_uu_id: str, data: UpdateBuildArea):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(
data=data, build_uu_id=build_uu_id, token_dict=token_dict
)
@build_area_route.patch(
path="/patch/{build_uu_id}", summary="Update Active/Delete/Confirm"
)
def build_area_patch(request: Request, build_uu_id: str, data: PatchRecord):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(
data=data, build_uu_id=build_uu_id, token_dict=token_dict
)

View File

@ -0,0 +1,50 @@
from fastapi.routing import APIRouter
from fastapi.requests import Request
from api_validations.validations_request import (
InsertBuildParts,
UpdateBuildParts,
PatchRecord,
ListOptions,
)
from ApiServices.api_handlers.auth_actions.token import parse_token_object_to_dict
build_parts_route = APIRouter(prefix="/building/parts", tags=["Building Parts"])
build_parts_route.include_router(build_parts_route, include_in_schema=True)
@build_parts_route.post(path="/list", summary="List Active/Delete/Confirm Build Parts")
def building_build_part_list(request: Request, list_options: ListOptions):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(list_options=list_options, token_dict=token_dict)
@build_parts_route.post(
path="/create", summary="Create Build Parts with given auth levels"
)
def building_build_part_create(request: Request, data: InsertBuildParts):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(data=data, token_dict=token_dict)
@build_parts_route.post(
path="/update/{build_uu_id}", summary="Update Build Parts with given auth levels"
)
def building_build_part_update(
request: Request, build_uu_id: str, data: UpdateBuildParts
):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(
data=data, build_uu_id=build_uu_id, token_dict=token_dict
)
@build_parts_route.patch(
path="/patch/{build_uu_id}", summary="Update Active/Delete/Confirm"
)
def building_build_part_patch(request: Request, build_uu_id: str, data: PatchRecord):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(
data=data, build_uu_id=build_uu_id, token_dict=token_dict
)

View File

@ -0,0 +1,48 @@
from fastapi.routing import APIRouter
from fastapi.requests import Request
from api_validations.validations_request import (
PatchRecord,
ListOptions,
InsertBuildSites,
UpdateBuildSites,
)
from ApiServices.api_handlers.auth_actions.token import parse_token_object_to_dict
build_sites_route = APIRouter(prefix="/building/sites", tags=["Building Sites"])
build_sites_route.include_router(build_sites_route, include_in_schema=True)
@build_sites_route.post(path="/list", summary="List Active/Delete/Confirm Build Parts")
def building_sites_list(request: Request, list_options: ListOptions):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(list_options=list_options, token_dict=token_dict)
@build_sites_route.post(
path="/create", summary="Create Build Sites with given auth levels"
)
def building_sites_create(request: Request, data: InsertBuildSites):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(data=data, token_dict=token_dict)
@build_sites_route.post(
path="/update/{build_uu_id}", summary="Update Build Sites with given auth levels"
)
def building_sites_update(request: Request, build_uu_id: str, data: UpdateBuildSites):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(
data=data, build_uu_id=build_uu_id, token_dict=token_dict
)
@build_sites_route.patch(
path="/patch/{build_uu_id}", summary="Update Active/Delete/Confirm"
)
def building_sites_patch(request: Request, build_uu_id: str, data: PatchRecord):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(
data=data, build_uu_id=build_uu_id, token_dict=token_dict
)

View File

@ -0,0 +1,48 @@
from fastapi.routing import APIRouter
from fastapi.requests import Request
from api_validations.validations_request import (
InsertBuildTypes,
UpdateBuildTypes,
PatchRecord,
ListOptions,
)
from ApiServices.api_handlers.auth_actions.token import parse_token_object_to_dict
build_types_route = APIRouter(prefix="/building/types", tags=["Types"])
build_types_route.include_router(build_types_route, include_in_schema=True)
@build_types_route.post(path="/list", summary="List Active/Delete/Confirm Build Parts")
def building_types_list(request: Request, list_options: ListOptions):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(list_options=list_options, token_dict=token_dict)
@build_types_route.post(
path="/create", summary="Create BuildParts with given auth levels"
)
def building_types_create(request: Request, data: InsertBuildTypes):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(data=data, token_dict=token_dict)
@build_types_route.post(
path="/update/{build_uu_id}", summary="Update BuildParts with given auth levels"
)
def building_types_update(request: Request, build_uu_id: str, data: UpdateBuildTypes):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(
data=data, build_uu_id=build_uu_id, token_dict=token_dict
)
@build_types_route.patch(
path="/patch/{build_uu_id}", summary="Update Active/Delete/Confirm"
)
def building_types_patch(request: Request, build_uu_id: str, data: PatchRecord):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(
data=data, build_uu_id=build_uu_id, token_dict=token_dict
)

View File

@ -0,0 +1,53 @@
from fastapi.routing import APIRouter
from fastapi.requests import Request
from api_validations.validations_request import (
InsertBuildLivingSpace,
UpdateBuildLivingSpace,
PatchRecord,
ListOptions,
)
from ApiServices.api_handlers.auth_actions.token import parse_token_object_to_dict
build_living_space = APIRouter(prefix="/building/living_space", tags=["Living Space"])
build_living_space.include_router(build_living_space, include_in_schema=True)
@build_living_space.post(
path="/list", summary="List Active/Delete/Confirm Build Living Space"
)
def building_living_space_list(request: Request, list_options: ListOptions):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(list_options=list_options, token_dict=token_dict)
@build_living_space.post(
path="/create", summary="Create Build Living Space with given auth levels"
)
def building_living_space_create(request: Request, data: InsertBuildLivingSpace):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(data=data, token_dict=token_dict)
@build_living_space.post(
path="/update/{build_uu_id}",
summary="Update Build Living Space with given auth levels",
)
def building_living_space_update(
request: Request, build_uu_id: str, data: UpdateBuildLivingSpace
):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(
data=data, build_uu_id=build_uu_id, token_dict=token_dict
)
@build_living_space.patch(
path="/patch/{build_uu_id}",
summary="Update Build Living Space with given auth levels",
)
def building_living_space_patch(request: Request, build_uu_id: str, data: PatchRecord):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(
data=data, build_uu_id=build_uu_id, token_dict=token_dict
)

View File

@ -0,0 +1,46 @@
from fastapi.routing import APIRouter
from fastapi.requests import Request
from api_validations.validations_request import (
InsertCompany,
UpdateCompany,
PatchRecord,
ListOptions,
)
from ApiServices.api_handlers.auth_actions.token import parse_token_object_to_dict
company_route = APIRouter(prefix="/company", tags=["Company"])
company_route.include_router(company_route, include_in_schema=True)
@company_route.post(path="/list", summary="List Active/Delete/Confirm Companies")
def company_company_list(request: Request, list_options: ListOptions):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(list_options=list_options, token_dict=token_dict)
@company_route.post(path="/create", summary="Create Company with given auth levels")
def company_company_create(request: Request, data: InsertCompany):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(data=data, token_dict=token_dict)
@company_route.post(
path="/update/{company_uu_id}", summary="Update Company with given auth levels"
)
def company_company_update(request: Request, company_uu_id: str, data: UpdateCompany):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(
data=data, company_uu_id=company_uu_id, token_dict=token_dict
)
@company_route.patch(
path="/patch/{company_uu_id}", summary="Update Active/Delete/Confirm"
)
def company_company_patch(request: Request, company_uu_id: str, data: PatchRecord):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(
data=data, company_uu_id=company_uu_id, token_dict=token_dict
)

View File

@ -0,0 +1,47 @@
from fastapi.routing import APIRouter
from fastapi.requests import Request
from api_validations.validations_request import (
DepartmentsPydantic,
PatchRecord,
ListOptions,
)
from ApiServices.api_handlers.auth_actions.token import parse_token_object_to_dict
department_route = APIRouter(prefix="/department", tags=["Departments"])
department_route.include_router(department_route, include_in_schema=True)
@department_route.post(path="/list", summary="List Active/Delete/Confirm Departments")
def company_department_list(request: Request, list_options: ListOptions):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(list_options=list_options, token_dict=token_dict)
@department_route.post(path="/create", summary="Create Company with given auth levels")
def company_department_create(request: Request, data: DepartmentsPydantic):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(data=data, token_dict=token_dict)
@department_route.post(
path="/update/{company_uu_id}", summary="Update Company with given auth levels"
)
def company_department_update(
request: Request, company_uu_id: str, data: DepartmentsPydantic
):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(
company_uu_id=company_uu_id, data=data, token_dict=token_dict
)
@department_route.patch(
path="/patch/{company_uu_id}", summary="Patch Company with given auth levels"
)
def company_department_patch(request: Request, company_uu_id: str, data: PatchRecord):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(
company_uu_id=company_uu_id, data=data, token_dict=token_dict
)

View File

@ -0,0 +1,54 @@
from fastapi.routing import APIRouter
from fastapi.requests import Request
from api_validations.validations_request import (
InsertDuties,
UpdateDuties,
SelectDuties,
PatchRecord,
ListOptions,
)
from ApiServices.api_handlers.auth_actions.token import parse_token_object_to_dict
duties_route = APIRouter(prefix="/duties", tags=["Duties"])
duties_route.include_router(duties_route, include_in_schema=True)
@duties_route.post(path="/list", summary="List Active/Delete/Confirm Duties")
def company_duties_list(request: Request, list_options: ListOptions):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(list_options=list_options, token_dict=token_dict)
@duties_route.post(path="/get_by_duty_uuid", summary="Get Single Duty by Duty UUID")
def company_duties_get_by_duty_uuid(request: Request, data: SelectDuties):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(data=data, token_dict=token_dict)
@duties_route.post(path="/create", summary="Create Duties with given auth levels")
def company_duties_create(request: Request, data: InsertDuties):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(data=data, token_dict=token_dict)
@duties_route.post(
path="/update/{duties_uu_id}", summary="Update Duties with given auth levels"
)
def company_duties_update(request: Request, duties_uu_id: str, data: UpdateDuties):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(
data=data, duties_uu_id=duties_uu_id, token_dict=token_dict
)
@duties_route.patch(
path="/patch/{duties_uu_id}", summary="Patch Duties with given auth levels"
)
def company_duties_patch(request: Request, duties_uu_id: str, data: PatchRecord):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(
data=data, duties_uu_id=duties_uu_id, token_dict=token_dict
)

View File

@ -0,0 +1,44 @@
from fastapi.routing import APIRouter
from fastapi.requests import Request
from api_validations.validations_request import (
InsertCompanyDuty,
PatchRecord,
ListOptions,
)
from ApiServices.api_handlers.auth_actions.token import parse_token_object_to_dict
duty_route = APIRouter(prefix="/duty", tags=["Duty"])
duty_route.include_router(duty_route, include_in_schema=True)
@duty_route.post(path="/list", summary="List Active/Delete/Confirm Duty")
def company_duty_list(request: Request, list_options: ListOptions):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(list_options=list_options, token_dict=token_dict)
@duty_route.post(path="/create", summary="Create Company with given auth levels")
def company_duty_create(request: Request, data: InsertCompanyDuty):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(data=data, token_dict=token_dict)
@duty_route.post(
path="/update/{company_uu_id}", summary="Update Company with given auth levels"
)
def company_duty_update(request: Request, company_uu_id: str, data):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(
data=data, company_uu_id=company_uu_id, token_dict=token_dict
)
@duty_route.patch(path="/patch/{company_uu_id}", summary="Update Active/Delete/Confirm")
def company_duty_patch(request: Request, company_uu_id: str, data: PatchRecord):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(
data=data, company_uu_id=company_uu_id, token_dict=token_dict
)

View File

@ -0,0 +1,59 @@
from fastapi.routing import APIRouter
from fastapi.requests import Request
from api_validations.validations_request import (
InsertEmployees,
UnBindEmployees2People,
BindEmployees2People,
PatchRecord,
ListOptions,
)
from ApiServices.api_handlers.auth_actions.token import parse_token_object_to_dict
employee_route = APIRouter(prefix="/employee", tags=["Employee"])
employee_route.include_router(employee_route, include_in_schema=True)
@employee_route.post(path="/list", summary="List Active/Delete/Confirm Staff")
def company_employee_list(request: Request, list_options: ListOptions):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(list_options=list_options, token_dict=token_dict)
@employee_route.post(path="/create", summary="Create Employee with given auth levels")
def company_employee_create(request: Request, data: InsertEmployees):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(data=data, token_dict=token_dict)
@employee_route.post(
path="/update/{employee_uu_id}", summary="Update Employee with given auth levels"
)
def company_employee_update(request: Request, employee_uu_id: str, data: PatchRecord):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(
data=data, employee_uu_id=employee_uu_id, token_dict=token_dict
)
@employee_route.patch(
path="/patch/{employee_uu_id}", summary="Update Active/Delete/Confirm"
)
def company_employee_patch(request: Request, employee_uu_id: str, data: PatchRecord):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(
data=data, employee_uu_id=employee_uu_id, token_dict=token_dict
)
@employee_route.post(path="/employ", summary="Employ Employee with given auth levels")
def company_employee_employ(request: Request, data: BindEmployees2People):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(data=data, token_dict=token_dict)
@employee_route.post(path="/fire", summary="UnEmploy Employee with given auth levels")
def company_employee_fire(request: Request, data: UnBindEmployees2People):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(data=data, token_dict=token_dict)

View File

@ -0,0 +1,50 @@
from fastapi.routing import APIRouter
from fastapi.requests import Request
from api_validations.validations_request import (
InsertStaff,
SelectStaff,
PatchRecord,
ListOptions,
)
from ApiServices.api_handlers.auth_actions.token import parse_token_object_to_dict
staff_route = APIRouter(prefix="/staff", tags=["Staff"])
staff_route.include_router(staff_route, include_in_schema=True)
@staff_route.post(path="/list", summary="List Active/Delete/Confirm Staff")
def company_staff_list(request: Request, list_options: ListOptions):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(list_options=list_options, token_dict=token_dict)
@staff_route.post(path="/get_by_duties_uu_id", summary="Get Staff by UUID")
def company_staff_get_by_uu_id(request: Request, data: SelectStaff):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(data=data, token_dict=token_dict)
@staff_route.post(path="/create", summary="Create Staff with given auth levels")
def company_staff_create(request: Request, data: InsertStaff):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(data=data, token_dict=token_dict)
@staff_route.post(
path="/update/{staff_uu_id}", summary="Update Staff with given auth levels"
)
def company_staff_update(request: Request, staff_uu_id: str, data):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(
data=data, staff_uu_id=staff_uu_id, token_dict=token_dict
)
@staff_route.patch(path="/patch/{staff_uu_id}", summary="Update Active/Delete/Confirm")
def company_staff_patch(request: Request, staff_uu_id: str, data: PatchRecord):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(
data=data, staff_uu_id=staff_uu_id, token_dict=token_dict
)

View File

@ -0,0 +1,88 @@
from fastapi.routing import APIRouter
from fastapi.requests import Request
from api_validations.validations_request import (
InsertDecisionBook,
UpdateDecisionBook,
DecisionBookDecisionBookInvitations,
PatchRecord,
ListOptions,
)
from ApiServices.api_handlers.auth_actions.token import parse_token_object_to_dict
build_decision_book_route = APIRouter(
prefix="/build/decision_book", tags=["Decision Book"]
)
build_decision_book_route.include_router(
build_decision_book_route, include_in_schema=True
)
@build_decision_book_route.post(
path="/list", summary="List Active/Delete/Confirm Build Decision Book"
)
def build_decision_book_list(request: Request, list_options: ListOptions):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(list_options=list_options, token_dict=token_dict)
@build_decision_book_route.post(
path="/create", summary="Create Build Decision Book with given auth levels"
)
def build_decision_book_create(request: Request, data: InsertDecisionBook):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(data=data, token_dict=token_dict)
@build_decision_book_route.post(
path="/approval", summary="Approve Build Decision Book with given auth levels"
)
def build_decision_book_approval(request: Request, data):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(data=data, token_dict=token_dict)
@build_decision_book_route.post(
path="/update/{book_uu_id}",
summary="Update Build Decision Book with given auth levels",
)
def build_decision_book_update(
request: Request, book_uu_id: str, data: UpdateDecisionBook
):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(data=data, token_dict=token_dict)
@build_decision_book_route.patch(
path="/patch/{book_uu_id}", summary="Update Active/Delete/Confirm"
)
def build_decision_book_patch(request: Request, book_uu_id: str, data: PatchRecord):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(data=data, token_dict=token_dict)
@build_decision_book_route.post(
path="/invite/list", summary="List Build Decision Book Invitations"
)
def build_decision_book_invite(request: Request, data: ListOptions):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(list_options=data, token_dict=token_dict)
@build_decision_book_route.post(
path="/invite/create", summary="Create Build Decision Book Invitations"
)
def build_decision_book_invite_create(
request: Request, data: DecisionBookDecisionBookInvitations
):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(data=data, token_dict=token_dict)
@build_decision_book_route.post(
path="/invite/update", summary="Update Build Decision Book Invitations"
)
def build_decision_book_invite_update(request: Request, data):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(data=data, token_dict=token_dict)

View File

@ -0,0 +1,37 @@
from fastapi.routing import APIRouter
from fastapi.requests import Request
from api_validations.validations_request import (
DecisionBookDecisionBookInvitationsAttend,
DecisionBookDecisionBookInvitationsAssign,
PatchRecord,
)
from ApiServices.api_handlers.auth_actions.token import parse_token_object_to_dict
build_decision_book_invitations = APIRouter(
prefix="/build/decision_book/invitations", tags=["Decision Book Invitations"]
)
build_decision_book_invitations.include_router(
build_decision_book_invitations, include_in_schema=True
)
@build_decision_book_invitations.post(
path="/attend", summary="Decision Book Invitations Attend"
)
def build_decision_book_invitations_attend(
request: Request, data: DecisionBookDecisionBookInvitationsAttend
):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(data=data, token_dict=token_dict)
@build_decision_book_invitations.post(
path="/assign", summary="Decision Book Invitations Assign"
)
def build_decision_book_invitations_assign(
request: Request, data: DecisionBookDecisionBookInvitationsAssign
):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(data=data, token_dict=token_dict)

View File

@ -0,0 +1,61 @@
from fastapi.routing import APIRouter
from fastapi.requests import Request
from api_validations.validations_request import (
InsertBuildDecisionBookItems,
UpdateBuildDecisionBookItems,
ListDecisionBook,
PatchRecord,
)
from ApiServices.api_handlers.auth_actions.token import parse_token_object_to_dict
build_decision_book_items_route = APIRouter(
prefix="/build/decision_book/items", tags=["Decision Book Items"]
)
build_decision_book_items_route.include_router(
build_decision_book_items_route, include_in_schema=True
)
@build_decision_book_items_route.post(
path="/list", summary="List Active/Delete/Confirm Build Decision Book Items"
)
def build_decision_book_items_list(request: Request, data: ListDecisionBook):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(data=data, token_dict=token_dict)
@build_decision_book_items_route.post(
path="/create", summary="Create Build Items Decision Book with given auth levels"
)
def build_decision_book_items_create(
request: Request, data: InsertBuildDecisionBookItems
):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(data=data, token_dict=token_dict)
@build_decision_book_items_route.post(
path="/update/{book_uu_id}",
summary="Update Build Decision Book Items with given auth levels",
)
def build_decision_book_items_update(
request: Request, book_uu_id: str, data: UpdateBuildDecisionBookItems
):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(
data=data, book_uu_id=book_uu_id, token_dict=token_dict
)
@build_decision_book_items_route.patch(
path="/patch/{book_uu_id}", summary="Update Active/Delete/Confirm"
)
def build_decision_book_items_patch(
request: Request, book_uu_id: str, data: PatchRecord
):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(
data=data, book_uu_id=book_uu_id, token_dict=token_dict
)

View File

@ -0,0 +1,54 @@
from fastapi.routing import APIRouter
from fastapi.requests import Request
from api_validations.validations_request import (
InsertDecisionBook,
UpdateDecisionBook,
DecisionBookDecisionBookInvitationsAttend,
ListOptions,
)
from ApiServices.api_handlers.auth_actions.token import parse_token_object_to_dict
build_decision_book_people_route = APIRouter(
prefix="/build/decision_book/people", tags=["Decision Book People"]
)
build_decision_book_people_route.include_router(
build_decision_book_people_route, include_in_schema=True
)
@build_decision_book_people_route.post(
path="/list", summary="List Active/Delete/Confirm Build Decision Book People"
)
def build_decision_book_people_list(request: Request, list_options: ListOptions):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(list_options=list_options, token_dict=token_dict)
@build_decision_book_people_route.post(
path="/add",
summary="Add people to Build Decision People Book with given auth levels",
)
def build_decision_book_people_add(request: Request, data: InsertDecisionBook):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(data=data, token_dict=token_dict)
@build_decision_book_people_route.post(
path="/remove",
summary="Remove people from Build Decision Book People with given auth levels",
)
def build_decision_book_people_remove(request: Request, data: UpdateDecisionBook):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(data=data, token_dict=token_dict)
@build_decision_book_people_route.post(
path="/attend",
summary="Attend to Build Decision Book Invitations with given auth levels",
)
def build_decision_book_invite_attend(
request: Request, data: DecisionBookDecisionBookInvitationsAttend
):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(data=data, token_dict=token_dict)

View File

@ -0,0 +1,60 @@
from fastapi.routing import APIRouter
from fastapi.requests import Request
from api_validations.validations_request import (
InsertBuildDecisionBookProjects,
UpdateBuildDecisionBookProjects,
ApprovalsBuildDecisionBookProjects,
ListOptions,
)
from ApiServices.api_handlers.auth_actions.token import parse_token_object_to_dict
build_decision_book_project_route = APIRouter(
prefix="/build/decision_book/project", tags=["Decision Book Project"]
)
build_decision_book_project_route.include_router(
build_decision_book_project_route, include_in_schema=True
)
@build_decision_book_project_route.post(
path="/list", summary="List Active/Delete/Confirm Build Decision Book People"
)
def build_decision_book_project_people_list(
request: Request, list_options: ListOptions
):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(list_options=list_options, token_dict=token_dict)
@build_decision_book_project_route.post(
path="/create",
summary="Create Build Decision Book Project People with given auth levels",
)
def build_decision_book_project_people_create(
request: Request, data: InsertBuildDecisionBookProjects
):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(data=data, token_dict=token_dict)
@build_decision_book_project_route.post(
path="/update/{build_decision_book_project_id}",
summary="Add people to Build Decision People Book with given auth levels",
)
def build_decision_book_project_people_update(
request: Request, data: UpdateBuildDecisionBookProjects
):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(data=data, token_dict=token_dict)
@build_decision_book_project_route.post(
path="/approval",
summary="Approval people from Build Decision Book Project People with given auth levels",
)
def build_decision_book_project_invite_approval(
request: Request, data: ApprovalsBuildDecisionBookProjects
):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(data=data, token_dict=token_dict)

View File

@ -0,0 +1,71 @@
from fastapi.routing import APIRouter
from fastapi.requests import Request
from api_validations.validations_request import (
InsertBuildDecisionBookProjectItems,
UpdateBuildDecisionBookProjectItems,
ListOptions,
)
from ApiServices.api_handlers.auth_actions.token import parse_token_object_to_dict
build_decision_book_project_items_route = APIRouter(
prefix="/build/decision_book/project/items",
tags=["Decision Project Book Project Items"],
)
build_decision_book_project_items_route.include_router(
build_decision_book_project_items_route, include_in_schema=True
)
@build_decision_book_project_items_route.post(
path="/list",
summary="List Active/Delete/Confirm Decision Project Book Project Items",
)
def build_decision_book_project_people_items_list(
request: Request, list_options: ListOptions
):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(list_options=list_options, token_dict=token_dict)
@build_decision_book_project_items_route.post(
path="/create",
summary="Create Build Decision Book Project People with given auth levels",
)
def build_decision_book_project_people_items_create(
request: Request, data: InsertBuildDecisionBookProjectItems
):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(data=data, token_dict=token_dict)
@build_decision_book_project_items_route.post(
path="/update/{build_decision_book_project_item_uu_id}",
summary="Add people to Decision Project Book Project Items with given auth levels",
)
def build_decision_book_project_people_items_update(
request: Request,
build_decision_book_project_item_uu_id: str,
data: UpdateBuildDecisionBookProjectItems,
):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(
data=data,
build_decision_book_project_item_uu_id=build_decision_book_project_item_uu_id,
token_dict=token_dict,
)
@build_decision_book_project_items_route.post(
path="/patch/{build_decision_book_project_item_uu_id}",
summary="Patch people from Decision Project Book Project Items with given auth levels",
)
def build_decision_book_project_people_items_patch(
request: Request, build_decision_book_project_item_uu_id: str, data
):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(
data=data,
build_decision_book_project_item_uu_id=build_decision_book_project_item_uu_id,
token_dict=token_dict,
)

View File

@ -0,0 +1,71 @@
from fastapi.routing import APIRouter
from fastapi.requests import Request
from api_validations.validations_request import (
InsertBuildDecisionBookProjectPerson,
UpdateBuildDecisionBookProjectPerson,
ListOptions,
)
from ApiServices.api_handlers.auth_actions.token import parse_token_object_to_dict
build_decision_book_project_people_route = APIRouter(
prefix="/build/decision_book/project/people", tags=["Decision Book Project People"]
)
build_decision_book_project_people_route.include_router(
build_decision_book_project_people_route, include_in_schema=True
)
@build_decision_book_project_people_route.post(
path="/list", summary="List Active/Delete/Confirm Build Decision Book People"
)
def build_decision_book_project_people_list(
request: Request, list_options: ListOptions
):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(list_options=list_options, token_dict=token_dict)
@build_decision_book_project_people_route.post(
path="/create",
summary="Create Build Decision Book Project People with given auth levels",
)
def build_decision_book_project_people_create(
request: Request, data: InsertBuildDecisionBookProjectPerson
):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(data=data, token_dict=token_dict)
@build_decision_book_project_people_route.post(
path="/update/{build_decision_book_project_person_uu_id}",
summary="Add people to Build Decision People Book with given auth levels",
)
def build_decision_book_project_people_update(
request: Request,
build_decision_book_project_person_uu_id: str,
data: UpdateBuildDecisionBookProjectPerson,
):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(
data=data,
build_decision_book_project_person_uu_id=build_decision_book_project_person_uu_id,
token_dict=token_dict,
)
@build_decision_book_project_people_route.post(
path="/patch/{build_decision_book_project_person_uu_id}",
summary="Patch people from Build Decision Book Project People with given auth levels",
)
def build_decision_book_project_people_patch(
request: Request,
build_decision_book_project_person_uu_id: str,
data: UpdateBuildDecisionBookProjectPerson,
):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(
data=data,
build_decision_book_project_person_uu_id=build_decision_book_project_person_uu_id,
token_dict=token_dict,
)

View File

@ -0,0 +1,35 @@
from fastapi.routing import APIRouter
from fastapi.requests import Request
from ApiServices.api_handlers.auth_actions.token import parse_token_object_to_dict
from api_validations.validations_request import (
RegisterEvents2Employee,
RegisterEvents2Occupant,
PatchRecord,
)
bind_events_route = APIRouter(prefix="/bind/events", tags=["Binds"])
bind_events_route.include_router(bind_events_route, include_in_schema=True)
@bind_events_route.post(path="/occupant", summary="Register Event to Occupant")
def bind_events_occupant(request: Request, data: RegisterEvents2Occupant):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(data=data, token_dict=token_dict)
@bind_events_route.post(path="/employee", summary="Register Event to Employee")
def bind_events_employee(request: Request, data: RegisterEvents2Employee):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(data=data, token_dict=token_dict)
@bind_events_route.patch(
path="/patch/{event_uu_id}", summary="Patch Bind Events with given auth levels"
)
def bind_events_patch(request: Request, event_uu_id: str, data: PatchRecord):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(
data=data, event_uu_id=event_uu_id, token_dict=token_dict
)

View File

@ -0,0 +1,18 @@
from fastapi import Request
from fastapi.routing import APIRouter
from api_validations.validations_request import (
# CreateEvents,
ListOptions,
)
from ApiServices.api_handlers.auth_actions.token import parse_token_object_to_dict
event_route = APIRouter(prefix="/event", tags=["Events"])
event_route.include_router(event_route, include_in_schema=True)
@event_route.post(path="/list", summary="List Events")
def events_list(request: Request, data: ListOptions):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(data=data, token_dict=token_dict)

View File

@ -0,0 +1,35 @@
from fastapi.routing import APIRouter
from fastapi.requests import Request
from ApiServices.api_handlers.auth_actions.token import parse_token_object_to_dict
from api_validations.validations_request import (
RegisterModules2Occupant,
RegisterModules2Employee,
PatchRecord,
)
bind_modules_route = APIRouter(prefix="/bind/modules", tags=["Binds"])
bind_modules_route.include_router(bind_modules_route, include_in_schema=True)
@bind_modules_route.post(path="/occupant", summary="Register Event to Occupant")
def bind_events_occupant(request: Request, data: RegisterModules2Occupant):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(data=data, token_dict=token_dict)
@bind_modules_route.post(path="/employee", summary="Register Event to Employee")
def bind_events_employee(request: Request, data: RegisterModules2Employee):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(data=data, token_dict=token_dict)
@bind_modules_route.patch(
path="/patch/{event_uu_id}", summary="Patch Bind Events with given auth levels"
)
def bind_events_patch(request: Request, event_uu_id: str, data: PatchRecord):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(
data=data, event_uu_id=event_uu_id, token_dict=token_dict
)

View File

@ -0,0 +1,47 @@
from fastapi.routing import APIRouter
from fastapi.requests import Request
from api_validations.validations_request import (
DepartmentsPydantic,
PatchRecord,
ListOptions,
)
from ApiServices.api_handlers.auth_actions.token import parse_token_object_to_dict
modules_route = APIRouter(prefix="/modules", tags=["Modules"])
modules_route.include_router(modules_route, include_in_schema=True)
@modules_route.post(path="/list", summary="List Active/Delete/Confirm Modules")
def modules_list(request: Request, list_options: ListOptions):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(list_options=list_options, token_dict=token_dict)
@modules_route.post(path="/create", summary="Create Modules with given auth levels")
def modules_create(request: Request, data: DepartmentsPydantic):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(data=data, token_dict=token_dict)
@modules_route.post(
path="/update/{module_uu_id}", summary="Update Modules with given auth levels"
)
def modules_update(request: Request, module_uu_id: str, data: DepartmentsPydantic):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(
data=data, module_uu_id=module_uu_id, token_dict=token_dict
)
@modules_route.patch(
path="/patch/{module_uu_id}", summary="Patch Modules with given auth levels"
)
def modules_patch(request: Request, module_uu_id: str, data: PatchRecord):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(
data=data, module_uu_id=module_uu_id, token_dict=token_dict
)

View File

@ -0,0 +1,24 @@
from fastapi.routing import APIRouter
from fastapi.requests import Request
from api_validations.validations_request import (
RegisterServices2Employee,
RegisterServices2Occupant,
)
from ApiServices.api_handlers.auth_actions.token import parse_token_object_to_dict
bind_services_route = APIRouter(prefix="/bind/services", tags=["Binds"])
bind_services_route.include_router(bind_services_route, include_in_schema=True)
@bind_services_route.post(path="/occupant", summary="Bind Services to Occupant")
def bind_services_occupant(request: Request, data: RegisterServices2Occupant):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(data=data, token_dict=token_dict)
@bind_services_route.post(path="/employee", summary="Bind Services to Employee")
def bind_services_employee(request: Request, data: RegisterServices2Employee):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(data=data, token_dict=token_dict)

View File

@ -0,0 +1,44 @@
from fastapi.routing import APIRouter
from fastapi.requests import Request
from api_validations.validations_request import (
PatchRecord,
ListOptions,
)
from ApiServices.api_handlers.auth_actions.token import parse_token_object_to_dict
services_route = APIRouter(prefix="/services", tags=["Services"])
services_route.include_router(services_route, include_in_schema=True)
@services_route.post(path="/list", summary="List Active/Delete/Confirm Modules")
def services_list(request: Request, list_options: ListOptions):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(list_options=list_options, token_dict=token_dict)
@services_route.post(path="/create", summary="Create Modules with given auth levels")
def services_create(request: Request, data):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(data=data, token_dict=token_dict)
@services_route.post(
path="/update/{service_uu_id}", summary="Update Modules with given auth levels"
)
def services_update(request: Request, service_uu_id: str, data):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(
data=data, service_uu_id=service_uu_id, token_dict=token_dict
)
@services_route.patch(
path="/patch/{service_uu_id}", summary="Patch Modules with given auth levels"
)
def services_patch(request: Request, service_uu_id: str, data: PatchRecord):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(
data=data, service_uu_id=service_uu_id, token_dict=token_dict
)

View File

@ -0,0 +1,44 @@
from fastapi.routing import APIRouter
from fastapi.requests import Request
from api_validations.validations_request import (
InsertPerson,
UpdateUsers,
PatchRecord,
ListOptions,
)
from ApiServices.api_handlers.auth_actions.token import parse_token_object_to_dict
people_router = APIRouter(prefix="/people", tags=["People"])
people_router.include_router(people_router, include_in_schema=True)
@people_router.post(path="/list", summary="List Active/Delete/Confirm People")
def people_list(request: Request, list_options: ListOptions):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(list_options=list_options, token_dict=token_dict)
@people_router.post(path="/create", summary="Create People with given auth levels")
def people_create(request: Request, data: InsertPerson):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(data=data, token_dict=token_dict)
@people_router.post(
path="/update/{user_uu_id}", summary="Update People with given auth levels"
)
def people_update(request: Request, user_uu_id: str, data: UpdateUsers):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(
data=data, user_uu_id=user_uu_id, token_dict=token_dict
)
@people_router.patch(path="/patch/{user_uu_id}", summary="Update Active/Delete/Confirm")
def people_patch(request: Request, user_uu_id: str, data: PatchRecord):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(
data=data, user_uu_id=user_uu_id, token_dict=token_dict
)

View File

@ -0,0 +1,58 @@
from fastapi.routing import APIRouter
from fastapi.requests import Request
from api_validations.validations_request import (
InsertBuildDecisionBookProjects,
UpdateBuildDecisionBookProjects,
PatchRecord,
ListOptions,
)
from ApiServices.api_handlers.auth_actions.token import parse_token_object_to_dict
build_project_decision_book_route = APIRouter(
prefix="/build/project/decision_book", tags=["Project Decision Book"]
)
build_project_decision_book_route.include_router(
build_project_decision_book_route, include_in_schema=True
)
@build_project_decision_book_route.post(
path="/list", summary="List Active/Delete/Confirm Project Build Decision Book"
)
def project_decision_book_list(request: Request, list_options: ListOptions):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(list_options=list_options, token_dict=token_dict)
@build_project_decision_book_route.post(
path="/create", summary="Create Build Project Decision Book with given auth levels"
)
def project_decision_book_create(
request: Request, data: InsertBuildDecisionBookProjects
):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(data=data, token_dict=token_dict)
@build_project_decision_book_route.post(
path="/update/{book_uu_id}",
summary="Update Project Build Decision Book with given auth levels",
)
def project_decision_book_update(
request: Request, book_uu_id: str, data: UpdateBuildDecisionBookProjects
):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(
data=data, book_uu_id=book_uu_id, token_dict=token_dict
)
@build_project_decision_book_route.patch(
path="/patch/{book_uu_id}", summary="Update Active/Delete/Confirm"
)
def project_decision_book_patch(request: Request, book_uu_id: str, data: PatchRecord):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(
data=data, book_uu_id=book_uu_id, token_dict=token_dict
)

View File

@ -0,0 +1,58 @@
from fastapi.routing import APIRouter
from fastapi.requests import Request
from api_validations.validations_request import (
InsertDecisionBook,
UpdateDecisionBook,
PatchRecord,
ListOptions,
)
from ApiServices.api_handlers.auth_actions.token import parse_token_object_to_dict
build_project_decision_book_person_route = APIRouter(
prefix="/build/decision_book/person", tags=["Decision Book Person"]
)
build_project_decision_book_person_route.include_router(
build_project_decision_book_person_route, include_in_schema=True
)
@build_project_decision_book_person_route.post(
path="/list", summary="List Active/Delete/Confirm Build Decision Book"
)
def project_decision_book_person_list(request: Request, list_options: ListOptions):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(list_options=list_options, token_dict=token_dict)
@build_project_decision_book_person_route.post(
path="/create", summary="Create Build Decision Book with given auth levels"
)
def project_decision_book_person_create(request: Request, data: InsertDecisionBook):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(data=data, token_dict=token_dict)
@build_project_decision_book_person_route.post(
path="/update/{book_uu_id}",
summary="Update Build Decision Book with given auth levels",
)
def project_decision_book_person_update(
request: Request, book_uu_id: str, data: UpdateDecisionBook
):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(
data=data, book_uu_id=book_uu_id, token_dict=token_dict
)
@build_project_decision_book_person_route.patch(
path="/patch/{book_uu_id}", summary="Update Active/Delete/Confirm"
)
def project_decision_book_person_patch(
request: Request, book_uu_id: str, data: PatchRecord
):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(
data=data, book_uu_id=book_uu_id, token_dict=token_dict
)

View File

@ -0,0 +1,130 @@
from fastapi.routing import APIRouter
from fastapi.requests import Request
from api_objects import OccupantTokenObject, EmployeeTokenObject
from api_validations.validations_request import (
UpdateEndpointAccessList,
InsertEndpointAccess,
CheckEndpointAccess,
)
from databases import (
EndpointRestriction,
Event2Occupant,
Event2Employee,
Events,
)
from databases.sql_models.event.event import Services, Service2Events
from ApiServices.api_handlers.auth_actions.token import parse_token_object_to_dict
endpoint_restriction_route = APIRouter(prefix="/access", tags=["Endpoint Access"])
endpoint_restriction_route.include_router(
endpoint_restriction_route, include_in_schema=True
)
@endpoint_restriction_route.post(
path="/endpoint/restriction/create",
summary="Add extra restriction to endpoints list",
)
def endpoint_restriction_create(request: Request, data: InsertEndpointAccess):
token_dict = parse_token_object_to_dict(request=request)
return
@endpoint_restriction_route.post(
path="/endpoint/update", summary="Update extra restriction to endpoints list"
)
def endpoint_restriction_update(request: Request, data: UpdateEndpointAccessList):
token_dict = parse_token_object_to_dict(request=request)
return
@endpoint_restriction_route.post(
path="/endpoints/available", summary="List extra restriction to endpoints list"
)
def endpoint_restriction_list(request: Request):
token_dict, records = parse_token_object_to_dict(request=request), []
if isinstance(token_dict, OccupantTokenObject):
occupant_events = Event2Occupant.get_event_id_by_build_living_space_id(
build_living_space_id=token_dict.selected_occupant.living_space_id
)
events_list = Events.filter_all(Events.id.in_(occupant_events)).data
records = EndpointRestriction.filter_all(
EndpointRestriction.id.in_([event.endpoint_id for event in events_list])
).data
elif isinstance(token_dict, EmployeeTokenObject):
employee_events = Event2Employee.get_event_id_by_employee_id(
employee_id=token_dict.selected_company.employee_id
)
events_list = Events.filter_all(Events.id.in_(employee_events)).data
records = EndpointRestriction.filter_all(
EndpointRestriction.id.in_([event.endpoint_id for event in events_list])
).data
return dict(
completed=True,
message="Available endpoints are listed successfully",
result=[str(record.endpoint_name) for record in records],
)
@endpoint_restriction_route.post(
path="/endpoint/available", summary="Check extra restriction to endpoint available"
)
def endpoint_restriction_available(request: Request, data: CheckEndpointAccess):
token_dict, records = parse_token_object_to_dict(request=request), []
endpoint = EndpointRestriction.filter_one(
EndpointRestriction.endpoint_name.ilike(f"%{data.endpoint}%"),
system=True,
).data
if not endpoint:
EndpointRestriction.raise_http_exception(
status_code="HTTP_404_NOT_FOUND",
error_case="UNAUTHORIZED",
message="Only Occupant can see this data",
data={},
)
event = Events.filter_one(Events.endpoint_id == endpoint.id).data
service = Service2Events.filter_one(Service2Events.event_id == event.id).data
if isinstance(token_dict, OccupantTokenObject):
event_occupant = Event2Occupant.filter_one(
Event2Occupant.event_service_id == service.service_id,
Event2Occupant.build_living_space_id
== token_dict.selected_occupant.living_space_id,
).data
if not event_occupant:
EndpointRestriction.raise_http_exception(
status_code="HTTP_404_NOT_FOUND",
error_case="UNAUTHORIZED",
message="This endpoint is not available for this occupant",
data={},
)
return dict(
completed=True,
message="Endpoint is available for this occupant",
)
elif isinstance(token_dict, EmployeeTokenObject):
event_employee = Event2Employee.filter_one(
Event2Employee.event_service_id == service.service_id,
Event2Employee.employee_id == token_dict.selected_company.employee_id,
).data
if not event_employee:
EndpointRestriction.raise_http_exception(
status_code="HTTP_404_NOT_FOUND",
error_case="UNAUTHORIZED",
message="This endpoint is not available for this employee",
data={},
)
return dict(
completed=True,
message="Endpoint is available for this occupant",
)
@endpoint_restriction_route.patch(
path="/endpoint/bind/patch", summary="Patch extra restriction to endpoints list"
)
def endpoint_restriction_patch(request: Request):
token_dict = parse_token_object_to_dict(request=request)
return

View File

@ -0,0 +1,45 @@
from fastapi.routing import APIRouter
from fastapi.requests import Request
from api_validations.validations_request import (
InsertUsers,
UpdateUsers,
PatchRecord,
ListOptions,
)
from ApiServices.api_handlers.auth_actions.token import parse_token_object_to_dict
user_route = APIRouter(prefix="/user", tags=["User"])
user_route.include_router(user_route, include_in_schema=True)
@user_route.post(path="/list", summary="List Active/Delete/Confirm Users")
def user_list(request: Request, list_options: ListOptions):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(list_options=list_options, token_dict=token_dict)
@user_route.post(path="/create", summary="Create User with given auth levels")
def user_create(request: Request, data: InsertUsers):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(data=data, token_dict=token_dict)
@user_route.post(
path="/update/{user_uu_id}", summary="Update User with given auth levels"
)
def user_update(request: Request, user_uu_id: str, data: UpdateUsers):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(
data=data, user_uu_id=user_uu_id, token_dict=token_dict
)
@user_route.patch(path="/patch/{user_uu_id}", summary="Update Active/Delete/Confirm")
def user_patch(request: Request, user_uu_id: str, data: PatchRecord):
token_dict = parse_token_object_to_dict(request=request)
return token_dict.available_event(
data=data, user_uu_id=user_uu_id, token_dict=token_dict
)

View File

@ -0,0 +1,123 @@
from fastapi import status
from fastapi.routing import APIRouter
from fastapi.requests import Request
from fastapi.exceptions import HTTPException
from api_validations.validations_request import (
EndpointValidation,
)
from pydantic import BaseModel
validations_route = APIRouter(prefix="/validations", tags=["Validations"])
validations_route.include_router(validations_route, include_in_schema=True)
class EndpointValidationResponse(BaseModel):
language: str
headers: dict
validation: dict
class ValidationParser:
def __init__(self, active_validation):
self.annotations = (
active_validation.__annotations__.items() if active_validation else None
)
self.schema = {}
self.parse()
def parse(self):
for key, value in self.annotations or {}:
field_type, required = "string", False
if str(value) == "<class 'str'>" or str(value) == "typing.Optional[str]":
field_type = "string"
required = not str(value) == "typing.Optional[str]"
elif str(value) == "<class 'int'>" or str(value) == "typing.Optional[int]":
field_type = "integer"
required = not str(value) == "typing.Optional[int]"
elif (
str(value) == "<class 'bool'>" or str(value) == "typing.Optional[bool]"
):
field_type = "boolean"
required = not str(value) == "typing.Optional[bool]"
elif (
str(value) == "<class 'float'>"
or str(value) == "typing.Optional[float]"
):
field_type = "float"
required = not str(value) == "typing.Optional[bool]"
elif (
str(value) == "<class 'datetime.datetime'>"
or str(value) == "typing.Optional[datetime.datetime]"
):
field_type = "datetime"
required = not str(value) == "typing.Optional[datetime.datetime]"
self.schema[key] = {"type": field_type, "required": required}
def retrieve_validation_from_class(selected_event, events):
event_function_class = getattr(selected_event, "function_class", None)
event_function_code = getattr(selected_event, "function_code", None)
function_class = getattr(events, event_function_class, None)
return function_class.__event_validation__.get(event_function_code, None)
@validations_route.post(path="/endpoint", summary="Retrieve validation of endpoint")
def user_list(request: Request, validation: EndpointValidation):
import api_events.events as events
from api_services.redis.functions import get_object_via_access_key
from databases import (
EndpointRestriction,
Events,
)
valid_token = get_object_via_access_key(request=request)
if not valid_token:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail=f"No valid token found in the request.",
)
endpoint_active = EndpointRestriction.filter_one(
EndpointRestriction.endpoint_name.ilike(f"%{str(validation.endpoint)}%"),
system=True,
).data
if not endpoint_active:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail=f"This endpoint {str(validation.endpoint)} is not active for this user, please contact your responsible company for further information.",
)
if valid_token.user_type == 1 and not valid_token.selected_company:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Selected company is not found in the token object.",
)
elif valid_token.user_type == 2 and not valid_token.selected_occupant:
raise HTTPException(
status_code=status.HTTP_418_IM_A_TEAPOT,
detail="Selected occupant is not found in the token object.",
)
selected_event = Events.filter_one(
Events.endpoint_id == endpoint_active.id,
Events.id.in_(valid_token.selected_company.reachable_event_list_id),
).data
if not selected_event:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="This endpoint requires event validation. Please contact your responsible company to use this event.",
)
active_validation = retrieve_validation_from_class(selected_event, events)
if not active_validation:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="No validation found for this endpoint.",
)
headers = getattr(
active_validation, str(valid_token.lang).lower(), active_validation.tr
)
validation_parse = ValidationParser(active_validation=active_validation)
return EndpointValidationResponse(
language=valid_token.lang,
headers=headers,
validation=validation_parse.schema,
)

View File

@ -2,35 +2,35 @@ FROM python:3.12-slim-bookworm
ENV PYTHONDONTWRITEBYTECODE 1 ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1 ENV PYTHONUNBUFFERED 1
ENV PYTHONPATH=/service_app
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/ COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/
WORKDIR /service_app
# Create logs directory # Create logs directory
RUN mkdir -p /service_app/logs RUN mkdir -p /service_app/logs
COPY ApiServices/ValidationService/pyproject.toml . COPY ApiServices/ValidationService/pyproject.toml .
RUN uv venv RUN uv venv .venv
RUN uv pip install -r pyproject.toml RUN . .venv/bin/activate && uv pip install -r pyproject.toml
COPY ApiServices/ValidationService ./service_app COPY ApiServices ./ApiServices
COPY ApiServices/api_handlers ./service_app/api_handlers COPY databases ./databases
COPY api_services ./api_services
COPY api_objects ./api_objects
COPY api_configs ./api_configs
COPY api_events ./api_events
COPY api_library ./api_library
COPY api_validations ./api_validations
COPY databases ./service_app/databases WORKDIR /service_app/ApiServices/ValidationService
COPY api_services ./service_app/api_services
COPY api_objects ./service_app/api_objects
COPY api_configs ./service_app/api_configs
COPY api_events ./service_app/api_events
COPY api_library ./service_app/api_library
COPY api_validations ./service_app/api_validations
WORKDIR /service_app # Create startup script
RUN echo '#!/bin/bash\n\
source /service_app/.venv/bin/activate\n\
exec python app.py' > /service_app/start.sh && \
chmod +x /service_app/start.sh
CMD ["uv", "run", "app.py"] CMD ["/service_app/start.sh"]
# Old File
#FROM python:3.10
#RUN pip install --upgrade pip
#RUN pip install --no-cache-dir --upgrade -r requirements.txt
#CMD ["python", "-m", "app"]

View File

@ -2,7 +2,8 @@ import uvicorn
import routers import routers
from fastapi.middleware.cors import CORSMiddleware from fastapi.middleware.cors import CORSMiddleware
from fastapi.exceptions import HTTPException from fastapi import Request, HTTPException, status
from fastapi.responses import JSONResponse
from middlewares.token_middleware import AuthHeaderMiddleware from middlewares.token_middleware import AuthHeaderMiddleware
from application.create_file import create_app from application.create_file import create_app
@ -23,8 +24,17 @@ app.add_middleware(
) )
app.add_middleware(AuthHeaderMiddleware) app.add_middleware(AuthHeaderMiddleware)
app.add_exception_handler(HTTPException, ErrorHandlers.exception_handler_http) # Initialize error handlers
app.add_exception_handler(Exception, ErrorHandlers.exception_handler_exception) error_handlers = ErrorHandlers.create(
requests=Request,
exceptions=HTTPException,
response_model=JSONResponse,
status=status,
)
# Register error handlers with bound methods
app.add_exception_handler(HTTPException, error_handlers.exception_handler_http)
app.add_exception_handler(Exception, error_handlers.exception_handler_exception)
if __name__ == "__main__": if __name__ == "__main__":
uvicorn_config = { uvicorn_config = {

View File

@ -72,9 +72,9 @@ def check_if_path_secure(request, insecure_paths) -> bool:
def check_if_token_is_not_valid(request, endpoint_name): def check_if_token_is_not_valid(request, endpoint_name):
from api_services.redis.functions import get_object_via_access_key from api_services.redis.functions import RedisActions
token_user = get_object_via_access_key(request) token_user = RedisActions.get_object_via_access_key(request)
if not token_user: if not token_user:
return "Session geçerli değil. Lütfen tekrar giriş yapınız.", token_user return "Session geçerli değil. Lütfen tekrar giriş yapınız.", token_user

View File

@ -1,5 +1,5 @@
[project] [project]
name = "wag-managment-api-service-version-3" name = "wag-managment-api-service-version-3-validation-service"
version = "0.1.0" version = "0.1.0"
description = "Wag Python API Service" description = "Wag Python API Service"
readme = "README.md" readme = "README.md"

View File

@ -5,45 +5,18 @@ from api_objects import (
EmployeeTokenObject, EmployeeTokenObject,
UserType, UserType,
) )
from api_services.redis.conn import redis_cli from api_services import RedisActions
from ApiServices.api_handlers.auth_actions.token import AccessObjectActions from ApiServices.api_handlers.auth_actions.token import AccessObjectActions
def save_access_token_to_redis( class AuthActions:
request, found_user, domain: str, access_token: str = None
):
from databases import (
BuildLivingSpace,
BuildParts,
Companies,
Duties,
Departments,
Duty,
Employees,
Staff,
Addresses,
OccupantTypes,
)
if not found_user: @classmethod
raise HTTPException( def do_occupant_login_token(
status_code=400, cls, request, found_user, domain, access_token: str = None
detail=dict(message="User is not found."), ):
) from databases import BuildLivingSpace, BuildParts, OccupantTypes
# Check user is already logged in or has a previous session
already_tokens = AccessObjectActions.get_object_via_user_uu_id(
user_id=found_user.uu_id
)
for key, token_user in already_tokens.items():
if token_user.get("domain", "") == domain:
redis_cli.delete(key)
access_token = (
found_user.generate_access_token() if not access_token else access_token
)
# Prepare the user's details to save in Redis Session
if found_user.is_occupant: # Check if user is NOT an occupant
living_spaces: list[BuildLivingSpace] = BuildLivingSpace.filter_all( living_spaces: list[BuildLivingSpace] = BuildLivingSpace.filter_all(
BuildLivingSpace.person_id == found_user.person_id BuildLivingSpace.person_id == found_user.person_id
).data ).data
@ -118,108 +91,155 @@ def save_access_token_to_redis(
available_occupants=occupants_selection_dict, available_occupants=occupants_selection_dict,
) )
list_employee = Employees.filter_all( @classmethod
Employees.people_id == found_user.person_id, def do_employee_login_token(
).data cls, request, found_user, domain, access_token: str = None
companies_uu_id_list, companies_id_list, companies_list = [], [], [] ):
duty_uu_id_list, duty_id_list = [], [] from databases import (
for employee in list_employee: Companies,
staff = Staff.filter_one(Staff.id == employee.staff_id).data Duties,
if duties := Duties.filter_one(Duties.id == staff.duties_id).data: Departments,
if duty_found := Duty.filter_by_one(id=duties.duties_id).data: Duty,
duty_uu_id_list.append(str(duty_found.uu_id)) Employees,
duty_id_list.append(duty_found.id) Staff,
Addresses,
)
department = Departments.filter_one( list_employee = Employees.filter_all(
Departments.id == duties.department_id, Employees.people_id == found_user.person_id,
).data ).data
if company := Companies.filter_one( companies_uu_id_list, companies_id_list, companies_list = [], [], []
Companies.id == department.company_id, duty_uu_id_list, duty_id_list = [], []
).data: for employee in list_employee:
companies_uu_id_list.append(str(company.uu_id)) staff = Staff.filter_one(Staff.id == employee.staff_id).data
companies_id_list.append(company.id) if duties := Duties.filter_one(Duties.id == staff.duties_id).data:
company_address = Addresses.filter_by_one( if duty_found := Duty.filter_by_one(id=duties.duties_id).data:
id=company.official_address_id duty_uu_id_list.append(str(duty_found.uu_id))
duty_id_list.append(duty_found.id)
department = Departments.filter_one(
Departments.id == duties.department_id,
).data ).data
companies_list.append( if company := Companies.filter_one(
dict( Companies.id == department.company_id,
uu_id=str(company.uu_id), ).data:
public_name=company.public_name, companies_uu_id_list.append(str(company.uu_id))
company_type=company.company_type, companies_id_list.append(company.id)
company_address=company_address, company_address = Addresses.filter_by_one(
id=company.official_address_id
).data
companies_list.append(
dict(
uu_id=str(company.uu_id),
public_name=company.public_name,
company_type=company.company_type,
company_address=company_address,
)
) )
AccessObjectActions.save_object_to_redis(
access_token=access_token,
model_object=EmployeeTokenObject(
domain=domain,
user_type=UserType.employee.value,
user_uu_id=str(found_user.uu_id),
credentials=found_user.credentials(),
user_id=found_user.id,
person_id=found_user.person_id,
person_uu_id=str(found_user.person.uu_id),
request=dict(request.headers),
companies_uu_id_list=companies_uu_id_list,
companies_id_list=companies_id_list,
duty_uu_id_list=duty_uu_id_list,
duty_id_list=duty_id_list,
),
)
return dict(
user_type=UserType.employee.name,
companies_list=companies_list,
)
@classmethod
def check_user_and_delete_tokens_from_redis(cls, domain: str, found_user=None):
# Check user is already logged in or has a previous session
if not found_user:
raise HTTPException(
status_code=400,
detail=dict(message="User is not found."),
) )
AccessObjectActions.save_object_to_redis( already_tokens = AccessObjectActions.get_object_via_user_uu_id(
access_token=access_token, user_id=found_user.uu_id
model_object=EmployeeTokenObject( )
domain=domain, for key, token_user in already_tokens.items():
user_type=UserType.employee.value, if token_user.get("domain", "") == domain:
user_uu_id=str(found_user.uu_id), RedisActions.delete(key)
credentials=found_user.credentials(),
user_id=found_user.id,
person_id=found_user.person_id,
person_uu_id=str(found_user.person.uu_id),
request=dict(request.headers),
companies_uu_id_list=companies_uu_id_list,
companies_id_list=companies_id_list,
duty_uu_id_list=duty_uu_id_list,
duty_id_list=duty_id_list,
),
)
return dict(
user_type=UserType.employee.name,
companies_list=companies_list,
)
@classmethod
def save_access_token_to_redis(
cls, request, found_user, domain: str, access_token: str = None
):
from databases.sql_models.identity.identity import Users
def update_selected_to_redis(request, add_payload): found_user: Users = found_user
already_tokens = AccessObjectActions.get_object_via_access_key(request=request) cls.check_user_and_delete_tokens_from_redis(domain, found_user)
if not hasattr(request, "headers"): access_token = (
found_user.generate_access_token() if not access_token else access_token
)
# Prepare the user's details to save in Redis Session
if found_user.is_occupant: # Check if user is NOT an occupant
return cls.do_occupant_login_token(
request, found_user, domain, access_token
)
return cls.do_employee_login_token(request, found_user, domain, access_token)
@classmethod
def update_selected_to_redis(cls, request, add_payload):
already_tokens = AccessObjectActions.get_object_via_access_key(request=request)
if not hasattr(request, "headers"):
raise HTTPException(
status_code=401,
detail=dict(
message="Headers are not found in request. Invalid request object."
),
)
access_token = request.headers.get(Auth.ACCESS_TOKEN_TAG)
if already_tokens.user_type == UserType.occupant.value:
already_tokens.selected_occupant = add_payload.model_dump()
return AccessObjectActions.save_object_to_redis(
access_token=access_token,
model_object=OccupantTokenObject(**already_tokens.model_dump()),
)
elif already_tokens.user_type == UserType.employee.value:
already_tokens.selected_company = add_payload.model_dump()
return AccessObjectActions.save_object_to_redis(
access_token=access_token,
model_object=EmployeeTokenObject(**already_tokens.model_dump()),
)
raise HTTPException( raise HTTPException(
status_code=401, status_code=401,
detail=dict( detail=dict(
message="Headers are not found in request. Invalid request object." message="User type is not found in the token object. Please reach to your administrator."
), ),
) )
access_token = request.headers.get(Auth.ACCESS_TOKEN_TAG)
if already_tokens.user_type == UserType.occupant.value: @classmethod
already_tokens.selected_occupant = add_payload.model_dump() def update_access_token_to_redis(cls, request, add_payload):
already_tokens = AccessObjectActions.get_object_via_access_key(request=request)
if not hasattr(request, "headers"):
raise HTTPException(
status_code=401,
detail=dict(
message="Headers are not found in request. Invalid request object."
),
)
payload = {**add_payload, **already_tokens}
access_token = request.headers.get(Auth.ACCESS_TOKEN_TAG)
if payload.get("user_type") == str(UserType.occupant.value):
return AccessObjectActions.save_object_to_redis(
access_token=access_token,
model_object=OccupantTokenObject(**payload),
)
return AccessObjectActions.save_object_to_redis( return AccessObjectActions.save_object_to_redis(
access_token=access_token, access_token=access_token,
model_object=OccupantTokenObject(**already_tokens.model_dump()), model_object=EmployeeTokenObject(**payload),
) )
elif already_tokens.user_type == UserType.employee.value:
already_tokens.selected_company = add_payload.model_dump()
return AccessObjectActions.save_object_to_redis(
access_token=access_token,
model_object=EmployeeTokenObject(**already_tokens.model_dump()),
)
raise HTTPException(
status_code=401,
detail=dict(
message="User type is not found in the token object. Please reach to your administrator."
),
)
def update_access_token_to_redis(request, add_payload):
already_tokens = AccessObjectActions.get_object_via_access_key(request=request)
if not hasattr(request, "headers"):
raise HTTPException(
status_code=401,
detail=dict(
message="Headers are not found in request. Invalid request object."
),
)
payload = {**add_payload, **already_tokens}
access_token = request.headers.get(Auth.ACCESS_TOKEN_TAG)
if payload.get("user_type") == str(UserType.occupant.value):
return AccessObjectActions.save_object_to_redis(
access_token=access_token,
model_object=OccupantTokenObject(**payload),
)
return AccessObjectActions.save_object_to_redis(
access_token=access_token,
model_object=EmployeeTokenObject(**payload),
)

View File

@ -33,3 +33,6 @@ On Linux
> docker compose -f ./api-docker-compose.yml up --build -d > docker compose -f ./api-docker-compose.yml up --build -d
pytest -v testers/authentication/test_login.py

View File

@ -1,8 +1,7 @@
services: services:
wag_management_auth_service: wag_management_auth_service:
container_name: wag_management_auth_service container_name: wag_management_auth_service
# restart: on-failure # restart: on-failure
build: build:
context: . context: .
dockerfile: ApiServices/AuthService/Dockerfile dockerfile: ApiServices/AuthService/Dockerfile
@ -14,39 +13,39 @@ services:
- auth_venv:/service_app/.venv - auth_venv:/service_app/.venv
- auth_logs:/service_app/logs - auth_logs:/service_app/logs
wag_management_event_service: # wag_management_event_service:
container_name: wag_management_event_service # container_name: wag_management_event_service
# restart: on-failure # # restart: on-failure
build: # build:
context: . # context: .
dockerfile: ApiServices/EventService/Dockerfile # dockerfile: ApiServices/EventService/Dockerfile
ports: # ports:
- "1112:41575" # - "1112:41575"
environment: # environment:
- PYTHONPATH=/service_app # - PYTHONPATH=/service_app
volumes: # volumes:
- event_venv:/service_app/.venv # - event_venv:/service_app/.venv
- event_logs:/service_app/logs # - event_logs:/service_app/logs
wag_management_validation_service: # wag_management_validation_service:
container_name: wag_management_validation_service # container_name: wag_management_validation_service
# restart: on-failure # # restart: on-failure
build: # build:
context: . # context: .
dockerfile: ApiServices/ValidationService/Dockerfile # dockerfile: ApiServices/ValidationService/Dockerfile
ports: # ports:
- "1113:41575" # - "1113:41575"
environment: # environment:
- PYTHONPATH=/service_app # - PYTHONPATH=/service_app
volumes: # volumes:
- validation_venv:/service_app/.venv # - validation_venv:/service_app/.venv
- validation_logs:/service_app/logs # - validation_logs:/service_app/logs
# wag_management_init_service: # wag_management_init_service:
# container_name: wag_management_init_service # container_name: wag_management_init_service
# build: # build:
# context: . # context: .
# dockerfile: service_app_init/Dockerfile # dockerfile: service_app_init/Dockerfile
volumes: volumes:
auth_venv: auth_venv:

View File

@ -1,14 +1,39 @@
import typing import json
from typing import Union from typing import Union
from fastapi import status from fastapi import status
from fastapi.requests import Request from fastapi.requests import Request
from fastapi.exceptions import HTTPException from fastapi.exceptions import HTTPException
from api_objects import OccupantTokenObject, EmployeeTokenObject from api_objects import OccupantTokenObject, EmployeeTokenObject
from api_objects.auth.token_objects import CompanyToken, OccupantToken
from api_services.templates.password_templates import (
password_is_changed_template,
change_your_password_template,
)
from api_services.token_service import TokenService from api_services.token_service import TokenService
from api_services.redis.functions import RedisActions from api_services.redis.functions import RedisActions
from api_library.response_handlers import ResponseHandler from api_library.response_handlers import ResponseHandler
from api_library.logger import user_logger from api_library.date_time_actions.date_functions import system_arrow
# from api_library.user_logger import UserLogger
from api_validations.validations_request import (
Login,
Logout,
ChangePassword,
EmployeeSelection,
OccupantSelection,
CreatePassword,
Forgot,
# ResetPassword,
# RefreshToken,
)
from api_validations.validations_response import (
AuthenticationLoginResponse,
AuthenticationRefreshResponse,
AuthenticationUserInfoResponse,
)
from ApiServices.api_handlers.auth_actions.auth import AuthActions
from api_configs import Auth, ApiStatic from api_configs import Auth, ApiStatic
from api_events.events.abstract_class import MethodToEvent, ActionsSchema from api_events.events.abstract_class import MethodToEvent, ActionsSchema
@ -32,27 +57,6 @@ from databases import (
from api_services import ( from api_services import (
send_email, send_email,
save_access_token_to_redis,
update_selected_to_redis,
password_is_changed_template,
change_your_password_template,
)
from api_validations.validations_request import (
Login,
Logout,
ChangePassword,
Remember,
Forgot,
CreatePassword,
OccupantSelection,
EmployeeSelection,
)
from api_validations.validations_response import (
AuthenticationLoginResponse,
AuthenticationRefreshResponse,
AuthenticationUserInfoResponse,
) )
@ -73,22 +77,20 @@ class AuthenticationLoginEventMethods(MethodToEvent):
try: try:
access_dict = Users.login_user_with_credentials(data=data, request=request) access_dict = Users.login_user_with_credentials(data=data, request=request)
found_user = access_dict.get("user") found_user = access_dict.get("user")
if not found_user: if not found_user:
user_logger.log_login_attempt( # UserLogger.log_login_attempt(
request, # request,
None, # None,
data.domain, # data.domain,
data.access_key, # data.access_key,
success=False, # success=False,
error="Invalid credentials", # error="Invalid credentials",
) # )
return ResponseHandler.unauthorized("Invalid credentials") return ResponseHandler.unauthorized("Invalid credentials")
user_logger.log_login_attempt( # UserLogger.log_login_attempt(
request, found_user.id, data.domain, data.access_key, success=True # request, found_user.id, data.domain, data.access_key, success=True
) # )
response_data = { response_data = {
"access_token": access_dict.get("access_token"), "access_token": access_dict.get("access_token"),
"refresh_token": access_dict.get("refresher_token"), "refresh_token": access_dict.get("refresher_token"),
@ -98,12 +100,11 @@ class AuthenticationLoginEventMethods(MethodToEvent):
return ResponseHandler.success( return ResponseHandler.success(
message="User logged in successfully", message="User logged in successfully",
data=response_data, data=response_data,
response_model=AuthenticationLoginResponse,
) )
except Exception as e: except Exception as e:
user_logger.log_login_attempt( # UserLogger.log_login_attempt(
request, None, data.domain, data.access_key, success=False, error=str(e) # request, None, data.domain, data.access_key, success=False, error=str(e)
) # )
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail=str(e)) raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail=str(e))
@ -198,7 +199,7 @@ class AuthenticationSelectEventMethods(MethodToEvent):
) )
# Update Redis # Update Redis
update_selected_to_redis(request=request, add_payload=company_token) AuthActions.update_selected_to_redis(request=request, add_payload=company_token)
return ResponseHandler.success("Company selected successfully") return ResponseHandler.success("Company selected successfully")
@classmethod @classmethod
@ -265,7 +266,9 @@ class AuthenticationSelectEventMethods(MethodToEvent):
) )
# Update Redis # Update Redis
update_selected_to_redis(request=request, add_payload=occupant_token) AuthActions.update_selected_to_redis(
request=request, add_payload=occupant_token
)
return ResponseHandler.success("Occupant selected successfully") return ResponseHandler.success("Occupant selected successfully")
@classmethod @classmethod
@ -305,8 +308,8 @@ class AuthenticationCheckTokenEventMethods(MethodToEvent):
@classmethod @classmethod
def authentication_check_token_is_valid(cls, request: Request): def authentication_check_token_is_valid(cls, request: Request):
try: try:
TokenService.validate_token(request) if RedisActions.get_object_via_access_key(request=request):
return ResponseHandler.success("Access Token is valid") return ResponseHandler.success("Access Token is valid")
except HTTPException: except HTTPException:
return ResponseHandler.unauthorized("Access Token is NOT valid") return ResponseHandler.unauthorized("Access Token is NOT valid")
@ -338,16 +341,11 @@ class AuthenticationRefreshEventMethods(MethodToEvent):
found_user = Users.filter_one(Users.uu_id == token_dict.user_uu_id).data found_user = Users.filter_one(Users.uu_id == token_dict.user_uu_id).data
if not found_user: if not found_user:
return ResponseHandler.not_found("User not found") return ResponseHandler.not_found("User not found")
user_token = UsersTokens.filter_one( user_token = UsersTokens.filter_one(
UsersTokens.domain == found_user.domain_name, UsersTokens.domain == found_user.domain_name,
UsersTokens.user_id == found_user.id, UsersTokens.user_id == found_user.id,
UsersTokens.token_type == "RememberMe", UsersTokens.token_type == "RememberMe",
).data ).data
# Update user metadata
TokenService.update_user_metadata(found_user, request)
response_data = { response_data = {
"access_token": access_token, "access_token": access_token,
"refresh_token": getattr(user_token, "token", None), "refresh_token": getattr(user_token, "token", None),
@ -356,7 +354,6 @@ class AuthenticationRefreshEventMethods(MethodToEvent):
return ResponseHandler.success( return ResponseHandler.success(
"User info refreshed successfully", "User info refreshed successfully",
data=response_data, data=response_data,
response_model=AuthenticationRefreshResponse,
) )
except Exception as e: except Exception as e:
return ResponseHandler.error(str(e)) return ResponseHandler.error(str(e))
@ -392,29 +389,29 @@ class AuthenticationChangePasswordEventMethods(MethodToEvent):
return ResponseHandler.not_found("User not found") return ResponseHandler.not_found("User not found")
if not found_user.check_password(data.old_password): if not found_user.check_password(data.old_password):
user_logger.log_password_change( # UserLogger.log_password_change(
request, # request,
found_user.id, # found_user.id,
"change", # "change",
success=False, # success=False,
error="Invalid old password", # error="Invalid old password",
) # )
return ResponseHandler.unauthorized("Old password is incorrect") return ResponseHandler.unauthorized("Old password is incorrect")
found_user.set_password(data.new_password) found_user.set_password(data.new_password)
user_logger.log_password_change( # UserLogger.log_password_change(
request, found_user.id, "change", success=True # request, found_user.id, "change", success=True
) # )
return ResponseHandler.success("Password changed successfully") return ResponseHandler.success("Password changed successfully")
except Exception as e: except Exception as e:
user_logger.log_password_change( # UserLogger.log_password_change(
request, # request,
found_user.id if found_user else None, # found_user.id if found_user else None,
"change", # "change",
success=False, # success=False,
error=str(e), # error=str(e),
) # )
return ResponseHandler.error(str(e)) return ResponseHandler.error(str(e))
@ -484,7 +481,7 @@ class AuthenticationDisconnectUserEventMethods(MethodToEvent):
user_id=str(found_user.uu_id) user_id=str(found_user.uu_id)
): ):
for key, token_user in already_tokens.items(): for key, token_user in already_tokens.items():
RedisActions.delete_key(key) RedisActions.delete(key)
selected_user = Users.filter_one( selected_user = Users.filter_one(
Users.uu_id == token_user.get("uu_id"), Users.uu_id == token_user.get("uu_id"),
).data ).data
@ -518,9 +515,9 @@ class AuthenticationLogoutEventMethods(MethodToEvent):
token_user = None token_user = None
if already_tokens := RedisActions.get_object_via_access_key(request=request): if already_tokens := RedisActions.get_object_via_access_key(request=request):
for key in already_tokens: for key in already_tokens:
token_user = json.loads(RedisActions.get_key(key) or {}) token_user = RedisActions.get_json(key)
if token_user.get("domain") == data.domain: if token_user.get("domain") == data.domain:
RedisActions.delete_key(key) RedisActions.delete(key)
selected_user = Users.filter_one( selected_user = Users.filter_one(
Users.uu_id == token_user.get("uu_id"), Users.uu_id == token_user.get("uu_id"),
).data ).data
@ -548,7 +545,11 @@ class AuthenticationRefreshTokenEventMethods(MethodToEvent):
@classmethod @classmethod
def authentication_refresher_token( def authentication_refresher_token(
cls, request: Request, data: Remember, token_dict: dict = None # cls, request: Request, data: RefreshToken, token_dict: dict = None
cls,
request: Request,
data,
token_dict: dict = None,
): ):
token_refresher = UsersTokens.filter_by_one( token_refresher = UsersTokens.filter_by_one(
token=data.refresh_token, token=data.refresh_token,
@ -561,7 +562,7 @@ class AuthenticationRefreshTokenEventMethods(MethodToEvent):
Users.id == token_refresher.user_id, Users.id == token_refresher.user_id,
).data: ).data:
found_user: Users = found_user found_user: Users = found_user
access_key = save_access_token_to_redis( access_key = AuthActions.save_access_token_to_redis(
request=request, found_user=found_user, domain=data.domain request=request, found_user=found_user, domain=data.domain
) )
found_user.last_agent = request.headers.get("User-Agent", None) found_user.last_agent = request.headers.get("User-Agent", None)
@ -577,7 +578,6 @@ class AuthenticationRefreshTokenEventMethods(MethodToEvent):
return ResponseHandler.success( return ResponseHandler.success(
"User is logged in successfully via refresher token", "User is logged in successfully via refresher token",
data=response_data, data=response_data,
response_model=AuthenticationRefreshResponse,
) )
return ResponseHandler.not_found("Invalid data") return ResponseHandler.not_found("Invalid data")
@ -604,7 +604,7 @@ class AuthenticationForgotPasswordEventMethods(MethodToEvent):
found_user: Users = Users.check_user_exits( found_user: Users = Users.check_user_exits(
access_key=data.access_key, domain=data.domain access_key=data.access_key, domain=data.domain
) )
forgot_key = save_access_token_to_redis( forgot_key = AuthActions.save_access_token_to_redis(
request=request, found_user=found_user, domain=data.domain request=request, found_user=found_user, domain=data.domain
) )
forgot_link = ApiStatic.forgot_link(forgot_key=forgot_key) forgot_link = ApiStatic.forgot_link(forgot_key=forgot_key)
@ -708,7 +708,6 @@ class AuthenticationDownloadAvatarEventMethods(MethodToEvent):
return ResponseHandler.success( return ResponseHandler.success(
"Avatar and profile is shared via user credentials", "Avatar and profile is shared via user credentials",
data=user_info, data=user_info,
response_model=AuthenticationUserInfoResponse,
) )
return ResponseHandler.not_found("Invalid data") return ResponseHandler.not_found("Invalid data")

View File

@ -1,11 +1,13 @@
from .email.service import send_email from .email.service import send_email
from .redis.old_functions import (
save_object_to_redis as save_access_token_to_redis,
)
from .redis.functions import RedisActions from .redis.functions import RedisActions
from .templates.password_templates import ( from .templates.password_templates import (
password_is_changed_template, password_is_changed_template,
change_your_password_template, change_your_password_template,
) )
update_selected_to_redis = RedisActions.set_json _all__ = [
"send_email",
"RedisActions",
"password_is_changed_template",
"change_your_password_template",
]

View File

@ -1,7 +1,8 @@
import json import json
import typing import typing
from api_services.redis.conn import redis_cli from api_services.redis.conn import redis_cli
from api_library.date_time_actions.date_functions import system_arrow from api_library.date_time_actions.date_functions import system_arrow, DateTimeLocal
from api_objects import OccupantTokenObject, EmployeeTokenObject from api_objects import OccupantTokenObject, EmployeeTokenObject

View File

@ -1,40 +1,28 @@
import uuid
import secrets
import hashlib import hashlib
import uuid
import requests import requests
from sqlalchemy import or_
from datetime import timedelta from datetime import timedelta
from fastapi.exceptions import HTTPException from fastapi.exceptions import HTTPException
from fastapi import status
from databases.no_sql_models.validations import ( from databases.no_sql_models.validations import (
PasswordHistoryViaUser, PasswordHistoryViaUser,
AccessHistoryViaUser, AccessHistoryViaUser,
) )
from api_library.date_time_actions.date_functions import system_arrow, client_arrow from api_library.date_time_actions.date_functions import system_arrow, client_arrow
from api_configs import ApiStatic, Auth from api_configs import ApiStatic, Auth
class PasswordModule: class PasswordModule:
@staticmethod
def generate_token(length=32):
return uuid.uuid4().__str__()[:length]
@staticmethod
def create_hashed_password(domain: str, id_: str, password: str):
return hashlib.sha256(f"{domain}:{id_}:{password}".encode("utf-8")).hexdigest()
@classmethod @classmethod
def generate_token(cls, length): def check_password(cls, domain, id_, password, password_hashed):
return secrets.token_urlsafe(length)
@classmethod
def create_hashed_password(cls, domain, id_, password):
salted_password = f"{domain}-{id_}-{password}"
return hashlib.sha256(salted_password.encode()).hexdigest()
@classmethod
def check_hashed_password(cls, domain, id_, password, password_hashed):
if not password_hashed:
raise HTTPException(
status_code=401,
detail="Password is not changed yet user has no password.",
)
return cls.create_hashed_password(domain, id_, password) == password_hashed return cls.create_hashed_password(domain, id_, password) == password_hashed
@ -43,8 +31,10 @@ class AuthModule(PasswordModule):
@classmethod @classmethod
def check_user_exits(cls, access_key, domain): def check_user_exits(cls, access_key, domain):
from databases import Users from databases import Users
from sqlalchemy import or_
from fastapi import status
found_user = Users.query.filter( found_user: Users = Users.query.filter(
or_( or_(
Users.email == str(access_key).lower(), Users.email == str(access_key).lower(),
Users.phone_number == str(access_key).replace(" ", ""), Users.phone_number == str(access_key).replace(" ", ""),
@ -70,9 +60,7 @@ class AuthModule(PasswordModule):
return self.generate_token(Auth.ACCESS_TOKEN_LENGTH) return self.generate_token(Auth.ACCESS_TOKEN_LENGTH)
def remove_refresher_token(self, domain, disconnect: bool = False): def remove_refresher_token(self, domain, disconnect: bool = False):
from databases import ( from databases import UsersTokens
UsersTokens,
)
if disconnect: if disconnect:
registered_tokens = UsersTokens.filter_all( registered_tokens = UsersTokens.filter_all(
@ -87,20 +75,6 @@ class AuthModule(PasswordModule):
registered_tokens.query.delete() registered_tokens.query.delete()
UsersTokens.save() UsersTokens.save()
def check_password(self, password):
main_domain = self.get_main_domain_and_other_domains(get_main_domain=True)
if check_password := self.check_hashed_password(
domain=main_domain,
id_=str(self.uu_id),
password_hashed=self.hash_password,
password=password,
):
return check_password
raise HTTPException(
status_code=401,
detail="Password is not correct.",
)
def check_password_is_different(self, password): def check_password_is_different(self, password):
main_domain = self.get_main_domain_and_other_domains(get_main_domain=True) main_domain = self.get_main_domain_and_other_domains(get_main_domain=True)
if self.hash_password == self.create_hashed_password( if self.hash_password == self.create_hashed_password(
@ -113,7 +87,9 @@ class AuthModule(PasswordModule):
@staticmethod @staticmethod
def create_password(found_user, password, password_token=None): def create_password(found_user, password, password_token=None):
from databases import MongoQueryIdentity from databases import MongoQueryIdentity, Users
found_user: Users = found_user
if found_user.password_token: if found_user.password_token:
replace_day = 0 replace_day = 0
@ -135,10 +111,9 @@ class AuthModule(PasswordModule):
detail="Password token is not valid. Please request a new password token.", detail="Password token is not valid. Please request a new password token.",
) )
query_engine = MongoQueryIdentity(company_uuid=found_user.related_company) query_engine = MongoQueryIdentity(company_uuid=found_user.related_company)
domain_via_user = query_engine.get_domain_via_user( domain_via_user = query_engine.get_domain_via_user(
user_uu_id=str(found_user.uu_id) user_uu_id=str(found_user.uu_id)
)["main_domain"] )[0]["main_domain"]
new_password_dict = { new_password_dict = {
"password": found_user.create_hashed_password( "password": found_user.create_hashed_password(
domain=domain_via_user, id_=str(found_user.uu_id), password=password domain=domain_via_user, id_=str(found_user.uu_id), password=password
@ -208,155 +183,133 @@ class AuthModule(PasswordModule):
class UserLoginModule(AuthModule): class UserLoginModule(AuthModule):
@classmethod @classmethod
def login_user_with_credentials(cls, data, request): def set_login_details_to_mongo_database(
from api_services.redis.functions import RedisActions cls, found_user, headers_request, access_token, record_id
):
from databases import ( from databases.no_sql_models.identity import MongoQueryIdentity
Users,
People,
MongoQueryIdentity,
)
found_user: Users = Users.check_user_exits( agent = headers_request.get("evyos-user-agent", "")
access_key=data.access_key, domain=data.domain platform = headers_request.get("evyos-platform", "")
ext_ip = headers_request.get("evyos-ip-ext")
address = requests.get(f"http://ip-api.com/json/{ext_ip}").json()
address_package = {
"city": address["city"],
"zip": address["zip"],
"country": address["country"],
"countryCode": address["countryCode"],
"region": address["region"],
"regionName": address["regionName"],
}
mongo_db = MongoQueryIdentity(
company_uuid=found_user.related_company,
storage_reasoning="AccessHistory",
) )
access_token = found_user.generate_access_token()
query_engine = MongoQueryIdentity(company_uuid=found_user.related_company) query_engine = MongoQueryIdentity(company_uuid=found_user.related_company)
if found_user.check_password(password=data.password): filter_query = {
access_object_to_redis = RedisActions.save_access_token_to_redis( "agent": agent,
request=request, "platform": platform,
found_user=found_user, "address": address_package,
domain=data.domain, "user_id": found_user.id,
access_token=access_token, }
) already_exits = mongo_db.mongo_engine.filter_by(filter_query) or None
refresher_token = found_user.generate_refresher_token( no_address_validates = mongo_db.mongo_engine.get_all()[0] == 0
domain=data.domain, remember_me=data.remember_me access_via_user = query_engine.update_access_history_via_user(
) AccessHistoryViaUser(
headers_request = request.headers **{
headers_request = dict(headers_request) "user_uu_id": found_user.uu_id.__str__(),
headers_request["evyos-user-agent"] = headers_request.get("user-agent") "access_history": {
headers_request["evyos-platform"] = headers_request.get("user-agent") "record_id": record_id,
headers_request["evyos-ip-ext"] = "94.54.68.158" "agent": agent,
# found_user.last_agent = headers_request.get("evyos-user-agent", None) "platform": platform,
# found_user.last_platform = headers_request.get("evyos-platform", None) "address": address_package,
# found_user.last_remote_addr = headers_request.get("evyos-ip-ext", None) "ip": ext_ip,
# found_user.last_seen = str(system_arrow.now()) "access_token": access_token,
if ext_ip := headers_request.get("evyos-ip-ext"): "created_at": system_arrow.now().timestamp(),
agent = headers_request.get("evyos-user-agent", "") },
platform = headers_request.get("evyos-platform", "")
address = requests.get(f"http://ip-api.com/json/{ext_ip}").json()
address_package = {
"city": address["city"],
"zip": address["zip"],
"country": address["country"],
"countryCode": address["countryCode"],
"region": address["region"],
"regionName": address["regionName"],
} }
mongo_db = MongoQueryIdentity( )
company_uuid=str(found_user.related_company).replace(" ", ""), )
storage_reasoning="AccessHistory", if already_exits:
) update_mongo = mongo_db.mongo_engine.table.update_one(
filter_query = { filter=filter_query,
update={
"$set": {
"ip": ext_ip,
"access_token": access_token,
"created_at": system_arrow.now().timestamp(),
}
},
)
print("update_mongo", update_mongo)
else:
insert_mongo = mongo_db.mongo_engine.insert(
payload={
"user_id": found_user.id,
"record_id": record_id,
"agent": agent, "agent": agent,
"platform": platform, "platform": platform,
"address": address_package, "address": address_package,
"user_id": found_user.id, "ip": ext_ip,
"access_token": access_token,
"created_at": system_arrow.now().timestamp(),
"is_confirmed": True if no_address_validates else False,
"is_first": True if no_address_validates else False,
} }
already_exits = mongo_db.mongo_engine.filter_by(filter_query) or None )
no_address_validates = mongo_db.mongo_engine.get_all()[0] == 0 print("insert_mongo", insert_mongo)
@classmethod
def login_user_with_credentials(cls, data, request):
from databases.sql_models.identity.identity import Users
from ApiServices.api_handlers.auth_actions.auth import AuthActions
found_user = Users.check_user_exits(
access_key=data.access_key, domain=data.domain
)
if not found_user:
raise HTTPException(
status_code=401,
detail="Login is not successful. Please check your credentials.",
)
if len(found_user.hash_password) < 5:
raise HTTPException(
status_code=401,
detail="This user has not set up password. Please contact support.",
)
if found_user.check_password(
domain=data.domain,
id_=found_user.uu_id,
password_hashed=found_user.hash_password,
password=data.password,
):
access_object_to_redis = AuthActions.save_access_token_to_redis(
request=request,
found_user=found_user,
domain=data.domain,
# remember_me=data.remember_me,
)
print("access_object_to_redis", access_object_to_redis)
access_token = access_object_to_redis.get("access_token")
headers_request = dict(request.headers)
headers_request["evyos-user-agent"] = headers_request.get("user-agent")
headers_request["evyos-platform"] = headers_request.get("user-agent")
headers_request["evyos-ip-ext"] = "94.54.68.158"
if headers_request.get("evyos-ip-ext"):
record_id = uuid.uuid4().__str__() record_id = uuid.uuid4().__str__()
notice_link = ApiStatic.blacklist_login(record_id=record_id) cls.set_login_details_to_mongo_database(
found_people = People.filter_one(People.id == found_user.person_id).data found_user=found_user,
access_via_user = query_engine.update_access_history_via_user( headers_request=headers_request,
AccessHistoryViaUser( access_token=access_token,
**{ record_id=record_id,
"user_uu_id": found_user.uu_id.__str__(),
"access_history": {
"record_id": record_id,
"agent": agent,
"platform": platform,
"address": address_package,
"ip": ext_ip,
"access_token": access_token,
"created_at": system_arrow.now().timestamp(),
# "is_confirmed": True if no_address_validates else False,
# "is_first": True if no_address_validates else False,
},
}
)
) )
if already_exits: notice_link = ApiStatic.blacklist_login(record_id=record_id)
update_mongo = mongo_db.mongo_engine.table.update_one(
filter=filter_query,
update={
"$set": {
"ip": ext_ip,
"access_token": access_token,
"created_at": system_arrow.now().timestamp(),
}
},
)
else:
mongo_db.mongo_engine.insert(
payload={
"user_id": found_user.id,
"record_id": record_id,
"agent": agent,
"platform": platform,
"address": address_package,
"ip": ext_ip,
"access_token": access_token,
"created_at": system_arrow.now().timestamp(),
"is_confirmed": True if no_address_validates else False,
"is_first": True if no_address_validates else False,
}
)
found_user.remember_me = bool(data.remember_me) found_user.remember_me = bool(data.remember_me)
found_user.save() found_user.save()
return { return access_object_to_redis
"access_token": access_token,
"refresher_token": refresher_token,
"user": found_user,
"access_object": access_object_to_redis,
}
raise HTTPException( raise HTTPException(
status_code=401, status_code=401,
detail="Login is not successful. Please check your credentials.", detail="Login is not successful. Please check your credentials.",
) )
# UserLogger.log_error(
# dict(
# user_id=found_user.id,
# domain=data.domain,
# access_key=data.access_key,
# agent=found_user.last_agent,
# ip=getattr(request, "remote_addr", None)
# or request.headers.get("X-Forwarded-For", None),
# platform=found_user.last_platform,
# login_date=str(DateTimeLocal.now()),
# is_login=True,
# )
# )
# if (
# not str(found_people.country_code).lower()
# == str(address_package.get("countryCode")).lower()
# ):
# send_email_completed = send_email(
# subject=f"Dear {found_user.nick_name}, your password has been changed.",
# receivers=[str(found_user.email)],
# html=invalid_ip_or_address_found(
# user_name=found_user.nick_name,
# address=address_package,
# notice_link=notice_link,
# ),
# )
# if not send_email_completed:
# raise HTTPException(
# status_code=400,
# detail="An error occured at sending email. Please contact with support team.",
# )

View File

@ -56,14 +56,41 @@ class MongoQueryIdentity:
return [self.validate_timestamp(doc) for doc in result.data] if result else None return [self.validate_timestamp(doc) for doc in result.data] if result else None
def refresh_password_history_via_user(self, payload: PasswordHistoryViaUser): def refresh_password_history_via_user(self, payload: PasswordHistoryViaUser):
self.use_collection("PasswordHistory")
password_history_item = self.mongo_engine.get_one(
match=payload.user_uu_id, field="user_uu_id"
)
if not password_history_item:
self.mongo_engine.insert(
payload={
"user_uu_id": str(payload.user_uu_id),
"password_history": [],
}
)
password_history_item = self.mongo_engine.get_one(
match=payload.user_uu_id, field="user_uu_id"
).data
password_history_list = password_history_item.get("password_history", [])
hashed_password = payload.password_add.get("password")
for password_in_history in password_history_list:
if str(password_in_history.get("password")) == str(hashed_password):
raise HTTPException(
status_code=400,
detail="Password already used. Please enter a new password that you have not used last 3 times.",
)
if len(password_history_list) > 3:
password_history_list.pop(0)
password_history_list.append(payload.password_add)
return self.mongo_engine.update( return self.mongo_engine.update(
field="user_uu_id",
match=payload.user_uu_id, match=payload.user_uu_id,
payload={ payload={
"password_history": payload.password_history, "password_history": password_history_list,
"access_history_detail": payload.access_history_detail, "access_history_detail": payload.access_history_detail,
"modified_at": system_arrow.to_timestamp(system_arrow.now()), "modified_at": system_arrow.now().timestamp(),
}, },
field="user_uu_id",
) )
def get_password_history_via_user(self, user_uu_id): def get_password_history_via_user(self, user_uu_id):
@ -99,6 +126,7 @@ class MongoQueryIdentity:
result = self.mongo_engine.filter_by(payload={"user_uu_id": user_uu_id}) result = self.mongo_engine.filter_by(payload={"user_uu_id": user_uu_id})
return [self.validate_timestamp(doc) for doc in result.data] if result else None return [self.validate_timestamp(doc) for doc in result.data] if result else None
@staticmethod
def validate_timestamp(doc): def validate_timestamp(doc):
"""Validate and fix timestamp fields in MongoDB documents""" """Validate and fix timestamp fields in MongoDB documents"""
if not doc: if not doc:

View File

@ -1,5 +1,4 @@
from datetime import timedelta from datetime import timedelta
from typing import Optional, List
from fastapi import HTTPException from fastapi import HTTPException
from sqlalchemy import ( from sqlalchemy import (
@ -106,13 +105,11 @@ class Users(CrudCollection, UserLoginModule, SelectAction):
) )
password_expires_day: Mapped[int] = mapped_column( password_expires_day: Mapped[int] = mapped_column(
"expires_day",
Integer, Integer,
server_default=str(Auth.PASSWORD_EXPIRE_DAY.days), server_default=str(Auth.PASSWORD_EXPIRE_DAY.days),
comment="Password expires in days", comment="Password expires in days",
) )
password_expiry_begins: Mapped[TIMESTAMP] = mapped_column( password_expiry_begins: Mapped[TIMESTAMP] = mapped_column(
"expiry_begins",
TIMESTAMP(timezone=True), TIMESTAMP(timezone=True),
server_default=func.now(), server_default=func.now(),
comment="Timestamp when password expiry begins", comment="Timestamp when password expiry begins",
@ -243,9 +240,15 @@ class Users(CrudCollection, UserLoginModule, SelectAction):
query_engine = MongoQueryIdentity(company_uuid=self.related_company) query_engine = MongoQueryIdentity(company_uuid=self.related_company)
domain_via_user = query_engine.get_domain_via_user(user_uu_id=str(self.uu_id)) domain_via_user = query_engine.get_domain_via_user(user_uu_id=str(self.uu_id))
if not domain_via_user:
raise HTTPException(
status_code=401,
detail="Domain not found. Please contact the admin.",
)
domain_via_user = domain_via_user[0]
if get_main_domain: if get_main_domain:
return domain_via_user.get("main_domain") return domain_via_user.get("main_domain", None)
return domain_via_user.get("other_domains_list") return domain_via_user.get("other_domains_list", None)
class RelationshipDutyPeople(CrudCollection): class RelationshipDutyPeople(CrudCollection):

View File

@ -1,7 +1,7 @@
#!/bin/bash #!/bin/bash
echo "Stopping existing containers..." echo "Stopping existing containers..."
docker compose -f api-docker-compose.yml down docker compose -f api-docker-compose.yml down --remove-orphans
echo "Building and starting auth service..." echo "Building and starting auth service..."
docker compose -f api-docker-compose.yml up --build wag_management_auth_service docker compose -f api-docker-compose.yml up --build

View File

@ -12,15 +12,17 @@ RUN uv pip install -r requirements.txt
COPY ../service_app_init ./service_app_init COPY ../service_app_init ./service_app_init
COPY ../databases ./service_app_init/databases COPY databases ./service_app_init/databases
COPY ../api_configs ./service_app_init/api_configs COPY api_configs ./service_app_init/api_configs
COPY ../api_events ./service_app_init/api_events COPY api_events ./service_app_init/api_events
COPY ../api_library ./service_app_init/api_library COPY api_library ./service_app_init/api_library
COPY ../api_validations ./service_app_init/api_validations COPY api_validations ./service_app_init/api_validations
COPY ../api_objects ./service_app_init/api_objects COPY api_objects ./service_app_init/api_objects
COPY ../api_services ./service_app_init/api_services COPY api_services ./service_app_init/api_services
COPY ApiServices ./service_app_init/ApiServices
COPY ApiServices/EventService/routers ./service_app_init/routers
#COPY ../service_app/application ./service_app_init/application #COPY ../service_app/application ./service_app_init/application
#COPY ../service_app/routers ./service_app_init/routers
WORKDIR /service_app_init WORKDIR /service_app_init

View File

@ -17,147 +17,146 @@ def do_alembic():
generate_alembic_with_session(text=text) generate_alembic_with_session(text=text)
# def create_one_address():
# def create_one_address(): from databases import (
# from databases import ( AddressCity,
# AddressCity, AddressStreet,
# AddressStreet, AddressLocality,
# AddressLocality, AddressDistrict,
# AddressDistrict, AddressNeighborhood,
# AddressNeighborhood, AddressState,
# AddressState, AddressCountry,
# AddressCountry, )
# )
# address_list = []
# address_list = [] country = AddressCountry.find_or_create(country_name="TÜRKİYE", country_code="TR")
# country = AddressCountry.find_or_create(country_name="TÜRKİYE", country_code="TR") address_list.append(country)
# address_list.append(country) state = AddressState.find_or_create(
# state = AddressState.find_or_create( state_name="TÜRKİYE",
# state_name="TÜRKİYE", state_code="TR",
# state_code="TR", phone_code="90",
# phone_code="90", country_id=country.id,
# country_id=country.id, country_uu_id=str(country.uu_id),
# country_uu_id=str(country.uu_id), )
# ) address_list.append(state)
# address_list.append(state) city = AddressCity.find_or_create(
# city = AddressCity.find_or_create( city_name="ANKARA",
# city_name="ANKARA", city_code="6",
# city_code="6", licence_plate="06",
# licence_plate="06", state_id=state.id,
# state_id=state.id, state_uu_id=str(state.uu_id),
# state_uu_id=str(state.uu_id), )
# ) address_list.append(city)
# address_list.append(city) district = AddressDistrict.find_or_create(
# district = AddressDistrict.find_or_create( district_name="ÇANKAYA",
# district_name="ÇANKAYA", district_code="1231",
# district_code="1231", city_id=city.id,
# city_id=city.id, city_uu_id=str(city.uu_id),
# city_uu_id=str(city.uu_id), )
# ) address_list.append(district)
# address_list.append(district) locality = AddressLocality.find_or_create(
# locality = AddressLocality.find_or_create( locality_name="MERKEZ",
# locality_name="MERKEZ", locality_code="2431",
# locality_code="2431", type_code="3",
# type_code="3", type_description=None,
# type_description=None, district_id=district.id,
# district_id=district.id, district_uu_id=str(district.uu_id),
# district_uu_id=str(district.uu_id), )
# ) address_list.append(locality)
# address_list.append(locality) neighborhood = AddressNeighborhood.find_or_create(
# neighborhood = AddressNeighborhood.find_or_create( neighborhood_name="AYRANCI MAHALLESİ",
# neighborhood_name="AYRANCI MAHALLESİ", neighborhood_code="1522",
# neighborhood_code="1522", type_code="1",
# type_code="1", type_description="MAHALLESİ",
# type_description="MAHALLESİ", locality_id=locality.id,
# locality_id=locality.id, locality_uu_id=str(locality.uu_id),
# locality_uu_id=str(locality.uu_id), )
# ) address_list.append(neighborhood)
# address_list.append(neighborhood) street = AddressStreet.find_or_create(
# street = AddressStreet.find_or_create( street_name="REŞAT NURİ CADDESİ",
# street_name="REŞAT NURİ CADDESİ", type_description="CADDESİ",
# type_description="CADDESİ", type_code="3",
# type_code="3", street_code="52270",
# street_code="52270", neighborhood_id=neighborhood.id,
# neighborhood_id=neighborhood.id, neighborhood_uu_id=str(neighborhood.uu_id),
# neighborhood_uu_id=str(neighborhood.uu_id), )
# ) address_list.append(street)
# address_list.append(street) for address_single in address_list:
# for address_single in address_list: address_single.save_and_confirm()
# address_single.save_and_confirm() return
# return
#
# def create_application_defaults_func(create_address=False):
# def create_application_defaults_func(create_address=False): from initialize_app import (
# from initialize_app import ( create_modules_and_services_and_actions,
# create_modules_and_services_and_actions, create_endpoints_from_api_functions,
# create_endpoints_from_api_functions, create_all_events_from_actions,
# create_all_events_from_actions, create_application_defaults,
# create_application_defaults, init_api_enums_build_types,
# init_api_enums_build_types, add_events_all_services_and_occupant_types,
# add_events_all_services_and_occupant_types, add_events_to_system_super_user,
# add_events_to_system_super_user, create_occupant_types_defaults,
# create_occupant_types_defaults, )
# ) import routers
# import routers
# try:
# try: create_endpoints_from_api_functions(routers=routers)
# create_endpoints_from_api_functions(routers=routers) except Exception as e:
# except Exception as e: print(
# print( f"{TerminalColors.WARNING} create_endpoints_from_api_functions Defaults Error",
# f"{TerminalColors.WARNING} create_endpoints_from_api_functions Defaults Error", e,
# e, )
# ) try:
# try: create_application_defaults()
# create_application_defaults() except Exception as e:
# except Exception as e: print(f"{TerminalColors.WARNING} create_application_defaults Defaults Error", e)
# print(f"{TerminalColors.WARNING} create_application_defaults Defaults Error", e) try:
# try: create_occupant_types_defaults()
# create_occupant_types_defaults() except Exception as e:
# except Exception as e: print(
# print( f"{TerminalColors.WARNING} create_occupant_types_defaults Defaults Error", e
# f"{TerminalColors.WARNING} create_occupant_types_defaults Defaults Error", e )
# ) try:
# try: create_modules_and_services_and_actions()
# create_modules_and_services_and_actions() except Exception as e:
# except Exception as e: print(
# print( f"{TerminalColors.WARNING} create_modules_and_services_and_actions Defaults Error",
# f"{TerminalColors.WARNING} create_modules_and_services_and_actions Defaults Error", e,
# e, )
# ) try:
# try: init_api_enums_build_types()
# init_api_enums_build_types() except Exception as e:
# except Exception as e: print(f"{TerminalColors.WARNING} init_api_enums_build_types Defaults Error", e)
# print(f"{TerminalColors.WARNING} init_api_enums_build_types Defaults Error", e) try:
# try: create_all_events_from_actions()
# create_all_events_from_actions() except Exception as e:
# except Exception as e: print(
# print( f"{TerminalColors.WARNING} create_all_events_from_actions Defaults Error", e
# f"{TerminalColors.WARNING} create_all_events_from_actions Defaults Error", e )
# ) try:
# try: add_events_all_services_and_occupant_types()
# add_events_all_services_and_occupant_types() except Exception as e:
# except Exception as e: print(
# print( f"{TerminalColors.WARNING} add_events_all_services_and_occupant_types Defaults Error",
# f"{TerminalColors.WARNING} add_events_all_services_and_occupant_types Defaults Error", e,
# e, )
# ) try:
# try: add_events_to_system_super_user()
# add_events_to_system_super_user() except Exception as e:
# except Exception as e: print(
# print( f"{TerminalColors.WARNING} add_events_to_system_super_user Defaults Error",
# f"{TerminalColors.WARNING} add_events_to_system_super_user Defaults Error", e,
# e, )
# ) try:
# try: if not create_address:
# if not create_address: return
# return create_one_address()
# create_one_address() except Exception as e:
# except Exception as e: print(f"{TerminalColors.WARNING} create_one_address Defaults Error", e)
# print(f"{TerminalColors.WARNING} create_one_address Defaults Error", e)
#
if __name__ == "__main__": if __name__ == "__main__":
print("Service App Initial Default Runner is running") print("Service App Initial Default Runner is running")
do_alembic() # do_alembic()
# create_application_defaults_func(create_address=True) create_application_defaults_func(create_address=True)
print("Service App Initial Default Runner is completed") print("Service App Initial Default Runner is completed")

View File

@ -8,28 +8,32 @@ LOGIN_ENDPOINT = f"{BASE_URL}/authentication/login"
# Load test data # Load test data
current_dir = os.path.dirname(os.path.abspath(__file__)) current_dir = os.path.dirname(os.path.abspath(__file__))
with open(os.path.join(current_dir, 'test_data.json'), 'r') as f: with open(os.path.join(current_dir, "test_data.json"), "r") as f:
TEST_DATA = json.load(f) TEST_DATA = json.load(f)
@pytest.fixture @pytest.fixture
def test_credentials(): def test_credentials():
return TEST_DATA['test_credentials'] return TEST_DATA["test_credentials"]
@pytest.fixture @pytest.fixture
def headers(): def headers():
return { return {"Content-Type": "application/json", "Accept": "application/json"}
"Content-Type": "application/json",
"Accept": "application/json"
}
class TestLogin: class TestLogin:
def test_successful_login(self, test_credentials, headers): def test_successful_login(self, test_credentials, headers):
"""Test successful login with provided credentials""" """Test successful login with provided credentials"""
response = requests.post(LOGIN_ENDPOINT, json=test_credentials, headers=headers) response = requests.post(LOGIN_ENDPOINT, json=test_credentials, headers=headers)
assert response.status_code == 200, f"Login failed with status {response.status_code}. Response: {response.text}" assert (
response.status_code == 200
), f"Login failed with status {response.status_code}. Response: {response.text}"
data = response.json() data = response.json()
assert "token" in data, f"Token not found in response. Response: {data}" assert "token" in data, f"Token not found in response. Response: {data}"
assert data.get("status") == "success", f"Status is not success. Response: {data}" assert (
data.get("status") == "success"
), f"Status is not success. Response: {data}"
def test_invalid_credentials(self, headers): def test_invalid_credentials(self, headers):
"""Test login with invalid credentials""" """Test login with invalid credentials"""
@ -37,20 +41,29 @@ class TestLogin:
"domain": "evyos.com.tr", "domain": "evyos.com.tr",
"access_key": "invalid@evyos.com.tr", "access_key": "invalid@evyos.com.tr",
"password": "wrongpassword", "password": "wrongpassword",
"remember_me": False "remember_me": False,
} }
response = requests.post(LOGIN_ENDPOINT, json=invalid_credentials, headers=headers) response = requests.post(
assert response.status_code in [401, 403], f"Expected 401 or 403, got {response.status_code}. Response: {response.text}" LOGIN_ENDPOINT, json=invalid_credentials, headers=headers
)
assert response.status_code in [
401,
403,
], f"Expected 401 or 403, got {response.status_code}. Response: {response.text}"
def test_missing_fields(self, headers): def test_missing_fields(self, headers):
"""Test login with missing required fields""" """Test login with missing required fields"""
incomplete_credentials = { incomplete_credentials = {
"domain": "evyos.com.tr", "domain": "evyos.com.tr",
"access_key": "test@evyos.com.tr" "access_key": "test@evyos.com.tr",
# missing password # missing password
} }
response = requests.post(LOGIN_ENDPOINT, json=incomplete_credentials, headers=headers) response = requests.post(
assert response.status_code == 422, f"Expected 422, got {response.status_code}. Response: {response.text}" LOGIN_ENDPOINT, json=incomplete_credentials, headers=headers
)
assert (
response.status_code == 422
), f"Expected 422, got {response.status_code}. Response: {response.text}"
def test_invalid_domain(self, headers): def test_invalid_domain(self, headers):
"""Test login with invalid domain""" """Test login with invalid domain"""
@ -58,17 +71,26 @@ class TestLogin:
"domain": "invalid-domain.com", "domain": "invalid-domain.com",
"access_key": "test@evyos.com.tr", "access_key": "test@evyos.com.tr",
"password": "string", "password": "string",
"remember_me": False "remember_me": False,
} }
response = requests.post(LOGIN_ENDPOINT, json=invalid_domain_credentials, headers=headers) response = requests.post(
assert response.status_code in [400, 401], f"Expected 400 or 401, got {response.status_code}. Response: {response.text}" LOGIN_ENDPOINT, json=invalid_domain_credentials, headers=headers
)
assert response.status_code in [
400,
401,
], f"Expected 400 or 401, got {response.status_code}. Response: {response.text}"
def test_malformed_json(self, headers): def test_malformed_json(self, headers):
"""Test login with malformed JSON""" """Test login with malformed JSON"""
response = requests.post(LOGIN_ENDPOINT, data="invalid json", headers=headers) response = requests.post(LOGIN_ENDPOINT, data="invalid json", headers=headers)
assert response.status_code == 422, f"Expected 422, got {response.status_code}. Response: {response.text}" assert (
response.status_code == 422
), f"Expected 422, got {response.status_code}. Response: {response.text}"
def test_empty_request(self, headers): def test_empty_request(self, headers):
"""Test login with empty request body""" """Test login with empty request body"""
response = requests.post(LOGIN_ENDPOINT, json={}, headers=headers) response = requests.post(LOGIN_ENDPOINT, json={}, headers=headers)
assert response.status_code == 422, f"Expected 422, got {response.status_code}. Response: {response.text}" assert (
response.status_code == 422
), f"Expected 422, got {response.status_code}. Response: {response.text}"

View File

@ -3,113 +3,6 @@ from databases.no_sql_models.mongo_database import MongoQuery
from databases.no_sql_models.identity import MongoQueryIdentity from databases.no_sql_models.identity import MongoQueryIdentity
"""
found_user: Users = Users.check_user_exits(
access_key=data.access_key, domain=data.domain
)
access_token = found_user.generate_access_token()
query_engine = MongoQueryIdentity(company_uuid=found_user.related_company)
if found_user.check_password(password=data.password):
access_object_to_redis = RedisActions.save_access_token_to_redis(
request=request,
found_user=found_user,
domain=data.domain,
access_token=access_token,
)
refresher_token = found_user.generate_refresher_token(
domain=data.domain, remember_me=data.remember_me
)
headers_request = request.headers
headers_request = dict(headers_request)
headers_request["evyos-user-agent"] = headers_request.get("user-agent")
headers_request["evyos-platform"] = headers_request.get("user-agent")
headers_request["evyos-ip-ext"] = "94.54.68.158"
# found_user.last_agent = headers_request.get("evyos-user-agent", None)
# found_user.last_platform = headers_request.get("evyos-platform", None)
# found_user.last_remote_addr = headers_request.get("evyos-ip-ext", None)
# found_user.last_seen = str(system_arrow.now())
if ext_ip := headers_request.get("evyos-ip-ext"):
agent = headers_request.get("evyos-user-agent", "")
platform = headers_request.get("evyos-platform", "")
address = requests.get(f"http://ip-api.com/json/{ext_ip}").json()
address_package = {
"city": address["city"],
"zip": address["zip"],
"country": address["country"],
"countryCode": address["countryCode"],
"region": address["region"],
"regionName": address["regionName"],
}
mongo_db = MongoQueryIdentity(
company_uuid=str(found_user.related_company).replace(" ", ""),
storage_reasoning="AccessHistory",
)
filter_query = {
"agent": agent,
"platform": platform,
"address": address_package,
"user_id": found_user.id,
}
already_exits = mongo_db.mongo_engine.filter_by(filter_query) or None
no_address_validates = mongo_db.mongo_engine.get_all()[0] == 0
record_id = uuid.uuid4().__str__()
notice_link = ApiStatic.blacklist_login(record_id=record_id)
found_people = People.filter_one(People.id == found_user.person_id).data
access_via_user = query_engine.update_access_history_via_user(
AccessHistoryViaUser(
**{
"user_uu_id": found_user.uu_id.__str__(),
"access_history": {
"record_id": record_id,
"agent": agent,
"platform": platform,
"address": address_package,
"ip": ext_ip,
"access_token": access_token,
"created_at": system_arrow.now().timestamp(),
# "is_confirmed": True if no_address_validates else False,
# "is_first": True if no_address_validates else False,
},
}
)
)
if already_exits:
update_mongo = mongo_db.mongo_engine.table.update_one(
filter=filter_query,
update={
"$set": {
"ip": ext_ip,
"access_token": access_token,
"created_at": system_arrow.now().timestamp(),
}
},
)
else:
mongo_db.mongo_engine.insert(
payload={
"user_id": found_user.id,
"record_id": record_id,
"agent": agent,
"platform": platform,
"address": address_package,
"ip": ext_ip,
"access_token": access_token,
"created_at": system_arrow.now().timestamp(),
"is_confirmed": True if no_address_validates else False,
"is_first": True if no_address_validates else False,
}
)
found_user.remember_me = bool(data.remember_me)
found_user.save()
return {
"access_token": access_token,
"refresher_token": refresher_token,
"user": found_user,
"access_object": access_object_to_redis,
}
"""
query_engine = MongoQueryIdentity( query_engine = MongoQueryIdentity(
company_uuid="5f5f4d2b-0b3f-4b1f-8f8a-3b3b7f3b7f3b", company_uuid="5f5f4d2b-0b3f-4b1f-8f8a-3b3b7f3b7f3b",
) )
@ -118,21 +11,21 @@ query_engine_mongo = MongoQuery(
database_name="mongo_database", database_name="mongo_database",
) )
payload={ payload = {
"user_uu_id": "5f5f4d2b-0b3f-4b1f-8f8a-3b3b7f3b7f3b", "user_uu_id": "5f5f4d2b-0b3f-4b1f-8f8a-3b3b7f3b7f3b",
"other_domains_list": ["www.gluglu.com"], "other_domains_list": ["www.gluglu.com"],
"main_domain": "www.gluglu.com", "main_domain": "www.gluglu.com",
"modified_at": system_arrow.to_timestamp(system_arrow.now()), "modified_at": system_arrow.to_timestamp(system_arrow.now()),
} }
query_engine.use_collection("PasswordHistory") query_engine.use_collection("PasswordHistory")
or_insert =query_engine.mongo_engine.find_or_insert( or_insert = query_engine.mongo_engine.find_or_insert(
payload={ payload={
"user_uu_id": str(payload.get("user_uu_id")), "user_uu_id": str(payload.get("user_uu_id")),
"password_history": [], "password_history": [],
}, },
field="user_uu_id", field="user_uu_id",
) )
print('or_insert', or_insert.data) print("or_insert", or_insert.data)
quit() quit()
get_all = query_engine_mongo.get_all() get_all = query_engine_mongo.get_all()
print('get_all', get_all.data) print("get_all", get_all.data)