services updated
This commit is contained in:
10
Events/AllEvents/validations/__init__.py
Normal file
10
Events/AllEvents/validations/__init__.py
Normal file
@@ -0,0 +1,10 @@
|
||||
"""
|
||||
Validations package initialization.
|
||||
"""
|
||||
|
||||
from .validation.cluster import ValidationsCluster
|
||||
|
||||
|
||||
__all__ = [
|
||||
"ValidationsCluster",
|
||||
]
|
||||
78
Events/AllEvents/validations/validation/api_events.py
Normal file
78
Events/AllEvents/validations/validation/api_events.py
Normal file
@@ -0,0 +1,78 @@
|
||||
from typing import Any
|
||||
from fastapi import Request
|
||||
|
||||
from Events.Engine.abstract_class import Event
|
||||
|
||||
from .models import ValidationsPydantic, ClusterPydantic, PagePydantic
|
||||
from .function_handlers import RetrieveValidation, RetrievePage
|
||||
|
||||
# Validation Event
|
||||
validation_event = Event(
|
||||
name="validation_event",
|
||||
key="02b5a596-14ba-4361-90d7-c6755727c63f",
|
||||
request_validator=ValidationsPydantic,
|
||||
language_models=[],
|
||||
statics=None,
|
||||
description="Get Validations by event function code",
|
||||
)
|
||||
|
||||
|
||||
def get_validation_by_event_function_code(request: Request, data: Any):
|
||||
return RetrieveValidation.retrieve_validation(data=data)
|
||||
|
||||
|
||||
validation_event.endpoint_callable = get_validation_by_event_function_code
|
||||
|
||||
|
||||
# Menu Event
|
||||
menu_event = Event(
|
||||
name="menu_event",
|
||||
key="a1613ca0-4843-498b-bfff-07ecea6777b2",
|
||||
request_validator=ValidationsPydantic,
|
||||
language_models=[],
|
||||
statics=None,
|
||||
description="Get Left Menu of the user",
|
||||
)
|
||||
|
||||
|
||||
def get_menu_by_event_function_code(request: Request, data: Any):
|
||||
return RetrieveValidation.retrieve_validation(data=data)
|
||||
|
||||
|
||||
menu_event.endpoint_callable = get_menu_by_event_function_code
|
||||
|
||||
|
||||
# Cluster Event
|
||||
cluster_event = Event(
|
||||
name="cluster_event",
|
||||
key="eed3fe12-cec1-4f35-b43d-62fca0682f73",
|
||||
request_validator=ClusterPydantic,
|
||||
language_models=[],
|
||||
statics=None,
|
||||
description="Get Left Menu of the user",
|
||||
)
|
||||
|
||||
|
||||
def get_cluster_by_event_function_code(request: Request, data: Any):
|
||||
return RetrievePage.retrieve_cluster(data=data)
|
||||
|
||||
|
||||
cluster_event.endpoint_callable = get_cluster_by_event_function_code
|
||||
|
||||
|
||||
# Page Event
|
||||
page_event = Event(
|
||||
name="page_event",
|
||||
key="2a43bff2-3720-4427-b226-9b2f6ef00b57",
|
||||
request_validator=PagePydantic,
|
||||
language_models=[],
|
||||
statics=None,
|
||||
description="Get Left Menu of the user",
|
||||
)
|
||||
|
||||
|
||||
def get_page_by_event_function_code(request: Request, data: Any):
|
||||
return RetrievePage.retrieve_page(data=data)
|
||||
|
||||
|
||||
page_event.endpoint_callable = get_page_by_event_function_code
|
||||
24
Events/AllEvents/validations/validation/cluster.py
Normal file
24
Events/AllEvents/validations/validation/cluster.py
Normal file
@@ -0,0 +1,24 @@
|
||||
from Events.Engine.abstract_class import CategoryCluster
|
||||
|
||||
from .validation import (
|
||||
ValidationEventMethods,
|
||||
MenuEventMethods,
|
||||
ClusterEventMethods,
|
||||
PageEventMethods,
|
||||
)
|
||||
|
||||
|
||||
ValidationsCluster = CategoryCluster(
|
||||
name="ValidationsCluster",
|
||||
tags=["Validations"],
|
||||
prefix="/validations",
|
||||
description="Validations cluster",
|
||||
endpoints={
|
||||
"ValidationEventMethods": ValidationEventMethods,
|
||||
"MenuEventMethods": MenuEventMethods,
|
||||
"ClusterEventMethods": ClusterEventMethods,
|
||||
"PageEventMethods": PageEventMethods,
|
||||
},
|
||||
include_in_schema=True,
|
||||
sub_category=[],
|
||||
)
|
||||
257
Events/AllEvents/validations/validation/function_handlers.py
Normal file
257
Events/AllEvents/validations/validation/function_handlers.py
Normal file
@@ -0,0 +1,257 @@
|
||||
"""
|
||||
Validation function handlers
|
||||
"""
|
||||
|
||||
from typing import Dict, Any, Optional
|
||||
from fastapi import Request
|
||||
|
||||
from ApiLayers.AllConfigs.Redis.configs import (
|
||||
RedisCategoryKeys,
|
||||
RedisValidationKeysAction,
|
||||
RedisCategoryPageInfoKeysAction,
|
||||
)
|
||||
from ApiLayers.ApiLibrary.common.line_number import get_line_number_for_error
|
||||
from ApiLayers.ErrorHandlers.Exceptions.api_exc import HTTPExceptionApi
|
||||
from Services.Redis.Actions.actions import RedisActions
|
||||
from Events.base_request_model import BaseRouteModel
|
||||
|
||||
from config import ValidationsConfig
|
||||
|
||||
|
||||
class ValidateBase:
|
||||
|
||||
redis_key: str = f"{RedisCategoryKeys.METHOD_FUNCTION_CODES}:*:"
|
||||
|
||||
def __init__(self, url: str, reachable_codes: list):
|
||||
self.url = url
|
||||
self.reachable_codes = reachable_codes
|
||||
|
||||
@property
|
||||
def function_codes(self):
|
||||
redis_function_codes = RedisActions.get_json(
|
||||
list_keys=[f"{self.redis_key}{self.url}"]
|
||||
)
|
||||
if redis_function_codes.status:
|
||||
return redis_function_codes.first
|
||||
raise ValueError("Function code not found")
|
||||
|
||||
@property
|
||||
def intersection(self):
|
||||
intersection = list(
|
||||
set(self.function_codes).intersection(set(self.reachable_codes))
|
||||
)
|
||||
if not len(intersection) == 1:
|
||||
raise ValueError(
|
||||
"Users reachable function codes does not match or match more than one."
|
||||
)
|
||||
return intersection[0]
|
||||
|
||||
|
||||
class RedisHeaderRetrieve(ValidateBase):
|
||||
|
||||
redis_key: str = RedisValidationKeysAction.dynamic_header_request_key
|
||||
|
||||
@property
|
||||
def header(self):
|
||||
"""
|
||||
Headers: Headers which is merged with response model && language models of event
|
||||
"""
|
||||
redis_header = RedisActions.get_json(
|
||||
list_keys=[f"{self.redis_key}:{self.intersection}"]
|
||||
)
|
||||
if redis_header.status:
|
||||
return redis_header.first
|
||||
raise ValueError("Header not found")
|
||||
|
||||
|
||||
class RedisValidationRetrieve(ValidateBase):
|
||||
|
||||
redis_key: str = RedisValidationKeysAction.dynamic_validation_key
|
||||
|
||||
@property
|
||||
def validation(self):
|
||||
"""
|
||||
Validation: Validation of event which is merged with response model && language models of event
|
||||
"""
|
||||
redis_validation = RedisActions.get_json(
|
||||
list_keys=[f"{self.redis_key}:{self.intersection}"]
|
||||
)
|
||||
if redis_validation.status:
|
||||
return redis_validation.first
|
||||
raise ValueError("Validation not found")
|
||||
|
||||
|
||||
class ValidationsBoth(RedisHeaderRetrieve, RedisValidationRetrieve):
|
||||
|
||||
@property
|
||||
def both(self) -> Dict[str, Any]:
|
||||
"""
|
||||
Headers: Headers which is merged with response model && language models of event
|
||||
Validation: Validation of event which is merged with response model && language models of event
|
||||
"""
|
||||
return {"headers": self.header, "validation": self.validation}
|
||||
|
||||
|
||||
class RetrieveValidation(BaseRouteModel):
|
||||
|
||||
@classmethod
|
||||
def retrieve_validation(cls, data: Any):
|
||||
"""
|
||||
Retrieve validation by event function code
|
||||
"""
|
||||
if (
|
||||
getattr(data, "asked_field", "")
|
||||
not in ValidationsConfig.SUPPORTED_VALIDATIONS
|
||||
):
|
||||
raise ValueError(
|
||||
f"Invalid asked field please retry with valid fields {ValidationsConfig.SUPPORTED_VALIDATIONS}"
|
||||
)
|
||||
|
||||
reachable_codes = []
|
||||
if cls.context_retriever.token.is_employee:
|
||||
reachable_codes = (
|
||||
cls.context_retriever.token.selected_company.reachable_event_codes
|
||||
)
|
||||
elif cls.context_retriever.token.is_occupant:
|
||||
reachable_codes = (
|
||||
cls.context_retriever.token.selected_occupant.reachable_event_codes
|
||||
)
|
||||
|
||||
validate_dict = dict(url=data.url, reachable_code=reachable_codes)
|
||||
if data.asked_field == "all":
|
||||
return ValidationsBoth(**validate_dict).both
|
||||
elif data.asked_field == "headers":
|
||||
return RedisHeaderRetrieve(**validate_dict).header
|
||||
elif data.asked_field == "validation":
|
||||
return RedisValidationRetrieve(**validate_dict).validation
|
||||
|
||||
|
||||
class RetrievePage(BaseRouteModel):
|
||||
|
||||
@staticmethod
|
||||
def get_site_cluster(page_name: str):
|
||||
"""
|
||||
/dashboard?site=clusterName retrieves clusterName
|
||||
"""
|
||||
if page_name:
|
||||
return page_name.split("?")[1].split("=")[1]
|
||||
raise ValueError("Page name not found")
|
||||
|
||||
@classmethod
|
||||
def retrieve_cluster(cls, data: Any):
|
||||
"""
|
||||
Retrieve cluster by event function code
|
||||
"""
|
||||
reachable_codes = []
|
||||
if cls.context_retriever.token.is_employee:
|
||||
reachable_codes = (
|
||||
cls.context_retriever.token.selected_company.reachable_event_codes
|
||||
)
|
||||
elif cls.context_retriever.token.is_occupant:
|
||||
reachable_codes = (
|
||||
cls.context_retriever.token.selected_occupant.reachable_event_codes
|
||||
)
|
||||
validate_dict = dict(url=data.url, reachable_code=reachable_codes)
|
||||
print("validate_dict", validate_dict)
|
||||
cluster_name = data.get("name")
|
||||
print("cluster_name", cluster_name)
|
||||
raise NotImplementedError("Cluster not found")
|
||||
|
||||
@classmethod
|
||||
def retrieve_page(cls, data: Any) -> Optional[Dict[str, Any]]:
|
||||
"""
|
||||
Retrieve page by event function code
|
||||
Check reachable codes for user to render which page and components on Frontend
|
||||
Uses:
|
||||
Context Token Retriever to get user information from ACCESS_TOKEN
|
||||
CategoryCluster Retrieve Cluster Retrieve cluster by name
|
||||
Check available instructions of page and info user with it
|
||||
Args:
|
||||
request: FastAPI request object
|
||||
data.page: Request body containing login credentials
|
||||
{
|
||||
"page": "/dashboard?site=AccountCluster"
|
||||
}
|
||||
Returns:
|
||||
NAME=cluster_name.name,
|
||||
PREFIX=cluster_name.PREFIX,
|
||||
URL=dict(page_info).get("URL", None),
|
||||
ICON=dict(page_info).get("ICON", None),
|
||||
INFO=dict(page_info).get("INFO", None),
|
||||
SUB_COMPONENTS=sub_components,
|
||||
"""
|
||||
from Events.Engine import CategoryCluster
|
||||
from Events.JustEvents.events_file import retrieve_cluster_by_name
|
||||
|
||||
reachable_codes, page_name = [], getattr(data, "page", None)
|
||||
if cls.context_retriever.token.is_employee:
|
||||
reachable_codes = (
|
||||
cls.context_retriever.token.selected_company.reachable_event_codes
|
||||
)
|
||||
elif cls.context_retriever.token.is_occupant:
|
||||
reachable_codes = (
|
||||
cls.context_retriever.token.selected_occupant.reachable_event_codes
|
||||
)
|
||||
cluster_name = str(page_name).split("?")[1].split("=")[1]
|
||||
print("page_name", f"{RedisCategoryPageInfoKeysAction.page_index}:{page_name}")
|
||||
page_info_from_redis = RedisActions.get_json(
|
||||
list_keys=[
|
||||
RedisCategoryPageInfoKeysAction.page_index,
|
||||
cluster_name,
|
||||
]
|
||||
)
|
||||
page_info_all = page_info_from_redis.first
|
||||
if not page_info_all:
|
||||
return dict(
|
||||
NAME=f"{cluster_name}",
|
||||
PREFIX=f"NOT IMPLEMENTED",
|
||||
URL=f"{page_name}",
|
||||
MESSAGE="Cluster not found",
|
||||
)
|
||||
|
||||
page_info = page_info_all.get(page_name, {})
|
||||
sub_components = dict(page_info).get("SUB_COMPONENTS", {})
|
||||
|
||||
print(
|
||||
"PAGE INFO : ",
|
||||
dict(
|
||||
page_name=page_name,
|
||||
page_info=page_info,
|
||||
sub_components=sub_components,
|
||||
NAME=cluster_name,
|
||||
PREFIX=page_info_all.get("prefix", ""),
|
||||
TEMPLATE_UI=dict(page_info).get("TEMPLATE_UI", ""),
|
||||
URL=dict(page_info).get("URL", None),
|
||||
ICON=dict(page_info).get("ICON", None),
|
||||
INFO=dict(page_info).get("INFO", None),
|
||||
SUB_COMPONENTS=sub_components,
|
||||
# MAPPING=cluster_name.MAPPING,
|
||||
),
|
||||
)
|
||||
new_page_info = dict(
|
||||
NAME=cluster_name,
|
||||
PREFIX=page_info_all.get("prefix", ""),
|
||||
TEMPLATE_UI=dict(page_info).get("TEMPLATE_UI", ""),
|
||||
URL=dict(page_info).get("URL", None),
|
||||
ICON=dict(page_info).get("ICON", None),
|
||||
INFO=dict(page_info).get("INFO", None),
|
||||
SUB_COMPONENTS=sub_components,
|
||||
# MAPPING=cluster_name.MAPPING,
|
||||
)
|
||||
for key, events in dict(sub_components).items():
|
||||
# Meaning client can reach this endpoint [] & [] intersection in reachable_codes
|
||||
endpoint_event_codes = dict(events).get("ENDPOINTS", [])
|
||||
if not len(list(set(endpoint_event_codes) & set(reachable_codes))) == 1:
|
||||
print(
|
||||
f"{endpoint_event_codes} :||: Endpoint is not available for the current user"
|
||||
)
|
||||
new_page_info["SUB_COMPONENTS"].pop(key, None)
|
||||
for key in new_page_info["SUB_COMPONENTS"].keys():
|
||||
new_page_info["SUB_COMPONENTS"][key].pop("ENDPOINTS", None)
|
||||
if len(new_page_info["SUB_COMPONENTS"]) == 0:
|
||||
return dict(
|
||||
NAME=cluster_name,
|
||||
PREFIX=page_info_all.get("prefix", ""),
|
||||
MESSAGE="This cluster is not registered or not accessible for the current user",
|
||||
)
|
||||
return new_page_info
|
||||
11
Events/AllEvents/validations/validation/info.py
Normal file
11
Events/AllEvents/validations/validation/info.py
Normal file
@@ -0,0 +1,11 @@
|
||||
from Events.Engine.abstract_class import PageInfo
|
||||
|
||||
|
||||
template_page_info = PageInfo(
|
||||
name="template",
|
||||
title={"en": "template"},
|
||||
description={"en": "template"},
|
||||
icon="",
|
||||
parent="",
|
||||
url="",
|
||||
)
|
||||
20
Events/AllEvents/validations/validation/models.py
Normal file
20
Events/AllEvents/validations/validation/models.py
Normal file
@@ -0,0 +1,20 @@
|
||||
"""
|
||||
Validation records request and response models.
|
||||
"""
|
||||
|
||||
from typing import Optional
|
||||
from pydantic import BaseModel
|
||||
|
||||
|
||||
class ValidationsPydantic(BaseModel):
|
||||
event_code: str
|
||||
type: Optional[str] = "REQUEST"
|
||||
asked_field: Optional[str] = "all"
|
||||
|
||||
|
||||
class ClusterPydantic(BaseModel):
|
||||
name: str
|
||||
|
||||
|
||||
class PagePydantic(BaseModel):
|
||||
page: str
|
||||
115
Events/AllEvents/validations/validation/validation.py
Normal file
115
Events/AllEvents/validations/validation/validation.py
Normal file
@@ -0,0 +1,115 @@
|
||||
"""
|
||||
Validation related API endpoints.
|
||||
"""
|
||||
|
||||
from typing import Any, Dict
|
||||
from fastapi import Request
|
||||
|
||||
from Events.Engine.abstract_class import MethodToEvent
|
||||
from Events.base_request_model import EndpointBaseRequestModel, ContextRetrievers
|
||||
from ApiLayers.Middleware.auth_middleware import MiddlewareModule
|
||||
|
||||
from .api_events import validation_event, menu_event, cluster_event, page_event
|
||||
from .function_handlers import RetrieveValidation, RetrievePage
|
||||
|
||||
|
||||
ValidationEventMethods = MethodToEvent(
|
||||
name="ValidationEventMethods",
|
||||
events={validation_event.key: validation_event},
|
||||
headers=[],
|
||||
errors=[],
|
||||
url="/validations",
|
||||
method="POST",
|
||||
decorators_list=[MiddlewareModule.auth_required],
|
||||
summary="Get Validations by event function code",
|
||||
description="Get Validations by event function code by All, Header, Validation & request url",
|
||||
)
|
||||
|
||||
|
||||
def validations_endpoint(
|
||||
request: Request, data: EndpointBaseRequestModel
|
||||
) -> Dict[str, Any]:
|
||||
function = ValidationEventMethods.retrieve_event(
|
||||
event_function_code=f"{validation_event.key}"
|
||||
)
|
||||
data = function.REQUEST_VALIDATOR(**data.data)
|
||||
RetrieveValidation.context_retriever = ContextRetrievers(func=validations_endpoint)
|
||||
return function.endpoint_callable(request=request, data=data)
|
||||
|
||||
|
||||
ValidationEventMethods.endpoint_callable = validations_endpoint
|
||||
|
||||
|
||||
MenuEventMethods = MethodToEvent(
|
||||
name="MenuEventMethods",
|
||||
events={menu_event.key: menu_event},
|
||||
headers=[],
|
||||
errors=[],
|
||||
url="/menu",
|
||||
method="POST",
|
||||
decorators_list=[MiddlewareModule.auth_required],
|
||||
summary="Get Left Menu of the user",
|
||||
description="Get Left Menu of the user",
|
||||
)
|
||||
|
||||
|
||||
def menu_endpoint(request: Request, data: EndpointBaseRequestModel) -> Dict[str, Any]:
|
||||
function = MenuEventMethods.retrieve_event(event_function_code=f"{menu_event.key}")
|
||||
data = function.REQUEST_VALIDATOR(**data.data)
|
||||
RetrieveValidation.context_retriever = ContextRetrievers(func=menu_endpoint)
|
||||
return function.endpoint_callable(request=request, data=data)
|
||||
|
||||
|
||||
MenuEventMethods.endpoint_callable = menu_endpoint
|
||||
|
||||
|
||||
# Cluster Event
|
||||
ClusterEventMethods = MethodToEvent(
|
||||
name="ClusterEventMethods",
|
||||
events={cluster_event.key: cluster_event},
|
||||
headers=[],
|
||||
errors=[],
|
||||
url="/cluster",
|
||||
method="POST",
|
||||
decorators_list=[MiddlewareModule.auth_required],
|
||||
summary="Get Left Menu of the user",
|
||||
description="Get Left Menu of the user",
|
||||
)
|
||||
|
||||
|
||||
def cluster_endpoint(
|
||||
request: Request, data: EndpointBaseRequestModel
|
||||
) -> Dict[str, Any]:
|
||||
function = ClusterEventMethods.retrieve_event(
|
||||
event_function_code=f"{cluster_event.key}"
|
||||
)
|
||||
data = function.REQUEST_VALIDATOR(**data.data)
|
||||
RetrievePage.context_retriever = ContextRetrievers(func=cluster_endpoint)
|
||||
return function.endpoint_callable(request=request, data=data)
|
||||
|
||||
|
||||
ClusterEventMethods.endpoint_callable = cluster_endpoint
|
||||
|
||||
|
||||
# Page Event
|
||||
PageEventMethods = MethodToEvent(
|
||||
name="PageEventMethods",
|
||||
events={page_event.key: page_event},
|
||||
headers=[],
|
||||
errors=[],
|
||||
url="/page",
|
||||
method="POST",
|
||||
decorators_list=[MiddlewareModule.auth_required],
|
||||
summary="Get Left Menu of the user",
|
||||
description="Get Left Menu of the user",
|
||||
)
|
||||
|
||||
|
||||
def page_endpoint(request: Request, data: EndpointBaseRequestModel) -> Dict[str, Any]:
|
||||
function = PageEventMethods.retrieve_event(event_function_code=f"{page_event.key}")
|
||||
data = function.REQUEST_VALIDATOR(**data.data)
|
||||
RetrievePage.context_retriever = ContextRetrievers(func=page_endpoint)
|
||||
return function.endpoint_callable(request=request, data=data)
|
||||
|
||||
|
||||
PageEventMethods.endpoint_callable = page_endpoint
|
||||
Reference in New Issue
Block a user