from audience_common import constants, context from audience_common.auth.account import AccountAccess from fastapi import Depends, Security from fastapi.security.api_key import APIKeyHeader from pyxdi.ext.fastapi import Inject from campaigns.auth.dtos import User, UserId from campaigns.auth.exceptions import NotAuthenticated, PermissionDenied from campaigns.auth.services import AuthService identity_id_auth = APIKeyHeader( name=constants.HEADER_ORCHARD_IDENTITY_ID, scheme_name="OrchardIdentityId", auto_error=False, ) profile_id_auth = APIKeyHeader( name=constants.HEADER_ORCHARD_PROFILE_ID, scheme_name="OrchardProfileId", auto_error=False, ) def get_identity_id(identity_id: str | None = Security(identity_id_auth)) -> str: if not identity_id: request_context = context.request_context.get() if request_context: identity_id = request_context.identity_id if not identity_id: raise NotAuthenticated( f"Missing `{constants.HEADER_ORCHARD_IDENTITY_ID}` header." ) return identity_id def get_profile_id( profile_id: str | None = Security(profile_id_auth), ) -> int: if not profile_id: request_context = context.request_context.get() if request_context and request_context.profile_id: profile_id = str(request_context.profile_id) if not profile_id: raise NotAuthenticated( f"Missing `{constants.HEADER_ORCHARD_PROFILE_ID}` header." ) if not profile_id.isnumeric(): raise NotAuthenticated( f"Invalid `{constants.HEADER_ORCHARD_PROFILE_ID}` header value." ) return int(profile_id) def get_user_id( identity_id: str = Depends(get_identity_id), profile_id: int = Depends(get_profile_id), ) -> UserId: return UserId(identity_id=identity_id, profile_id=profile_id) async def get_account_access( profile_id: int = Depends(get_profile_id), auth_service: AuthService = Inject(), ) -> AccountAccess: try: return await auth_service.authorization_backend.get_account_access(profile_id) except Exception as exc: raise PermissionDenied("Account access is not allowed.") from exc async def get_user( user_id: UserId = Depends(get_user_id), account_access: AccountAccess = Depends(get_account_access), ) -> User: return User(id=user_id, account_access=account_access)