from __future__ import annotations from typing import Dict, List, Protocol, Tuple, Union from uuid import UUID from pydantic import BaseModel from pdp import config from pdp.constants.constants import CacheEntryType from pdp.fastapi.schemas.get_allowed_tenants import ( GetAllowedTenantsRequest, GetAllowedTenantsResponse, ) from pdp.fastapi.schemas.identity import RolesResponse, TenantRoles from pdp.utils.cache import make_complicated_cache_key class LookupCacheObject(Protocol): """Common interface for ows-pdp CacheObject.""" def to_key_vals_tuple(self) -> List[Tuple[str, str]]: """Transform object into tuple for cache key formation.""" ... def get_cache_entry_type(self) -> CacheEntryType: """Get cache entry type associated with object.""" ... def to_cache_key(self) -> str: """Transform relevant attributes into cache key.""" ... def get_ttl(self) -> int | None: """Get the time-to-live (seconds) for object.""" ... def is_valid_to_save(self) -> bool: """Check if this object is worthy of being saved.""" ... class PrincipalPdpCacheObject(BaseModel): """Representation of PDP Principal as cache object.""" identity_uuid: UUID tenant_roles: Dict[UUID, TenantRoles] | None = None def to_key_vals_tuple(self) -> List[Tuple[str, str]]: """Transform object into tuple for cache key formation.""" return [ ("identity_uuid", str(self.identity_uuid)), ] def get_cache_entry_type(self) -> CacheEntryType: """Get cache entry type associated with object.""" return CacheEntryType.CACHE_ENTRY_PRINCIPAL_PDP def to_cache_key(self) -> str: """Transform relevant attributes into cache key.""" return make_complicated_cache_key( self.get_cache_entry_type().value, self.to_key_vals_tuple(), ) def get_ttl(self) -> int | None: """Get the time-to-live (seconds) for object.""" return config.CACHE_TTL_SECONDS_IDENTITY_TENANT_ROLES def is_valid_to_save(self) -> bool: """Check if this object is worthy of being saved.""" return self.tenant_roles is not None class IdentityRolesResponseCacheObject(BaseModel): """Representation of Identity Roles Response as cache object.""" principal_identity_uuid: UUID listed_identity_uuid: UUID cursor: Union[str | None] = None roles_response: RolesResponse | None = None def to_key_vals_tuple(self) -> List[Tuple[str, str]]: """Transform object into tuple for cache key formation.""" return [ ("principal_identity_uuid", str(self.principal_identity_uuid)), ("listed_identity_uuid", str(self.listed_identity_uuid)), ("cursor", self.cursor or ""), ] def get_cache_entry_type(self) -> CacheEntryType: """Get cache entry type associated with object.""" return CacheEntryType.CACHE_ENTRY_IDENTITY_ROLES def to_cache_key(self) -> str: """Transform relevant attributes into cache key.""" return make_complicated_cache_key( self.get_cache_entry_type().value, self.to_key_vals_tuple(), ) def get_ttl(self) -> int | None: """Get the time-to-live (seconds) for object.""" return config.CACHE_TTL_SECONDS_IDENTITY_TENANT_ROLES def is_valid_to_save(self) -> bool: """Check if this object is worthy of being saved.""" return self.roles_response is not None class IdentityAllowedTenantsCacheObject(GetAllowedTenantsRequest): """Representation of Identity Allowed Tenants Response as cache object.""" identity_uuid: UUID get_allowed_tenants_response: GetAllowedTenantsResponse | None = None def to_key_vals_tuple(self) -> List[Tuple[str, str]]: """Transform object into tuple for cache key formation.""" return [ ("action", str(self.action)), ("identity_uuid", str(self.identity_uuid)), ("resource_type", str(self.resource_type)), ] def get_cache_entry_type(self) -> CacheEntryType: """Get cache entry type associated with object.""" return CacheEntryType.CACHE_ENTRY_IDENTITY_ALLOWED_TENANTS def to_cache_key(self) -> str: """Transform relevant attributes into cache key.""" return make_complicated_cache_key( self.get_cache_entry_type().value, self.to_key_vals_tuple(), ) def get_ttl(self) -> int | None: """Get the time-to-live (seconds) for object.""" return config.CACHE_TTL_SECONDS_IDENTITY_ALLOWED_TENANTS def is_valid_to_save(self) -> bool: """Check if this object is worthy of being saved.""" return self.get_allowed_tenants_response is not None