"""Logic for permissions.""" from typing import Any, Literal, TypeAlias, TypedDict from flask import request from owsrequest import context from owsrequest.constants import headers as owsrequest_headers from charts.services import ows_permissions class NonePermissionsType(TypedDict): artist_ids: None vendor_ids: None subaccount_ids: None label_participant_ids: None class NonAdminPermissionsType(TypedDict): artist_ids: list[int] vendor_ids: list[int] subaccount_ids: list[int] label_participant_ids: list[int] class AdminPermissionsType(TypedDict): artist_ids: list[Literal['*']] vendor_ids: list[Literal['*']] subaccount_ids: list[Literal['*']] label_participant_ids: list[Literal['*']] PermissionType: TypeAlias = NonePermissionsType | NonAdminPermissionsType | AdminPermissionsType def _parse_profile_permissions(permissions: Any) -> PermissionType: """Convert a permissions request response to lists of resources Args: permissions (dict): An ows_permissions response Returns: dict: a dict containing resources the user has access to. """ if not permissions or not permissions.get('items'): return NonePermissionsType({ 'artist_ids': None, 'vendor_ids': None, 'subaccount_ids': None, 'label_participant_ids': None, }) artist_ids: list[int] = [] vendor_ids: list[int] = [] subaccount_ids: list[int] = [] label_participant_ids: list[int] = [] for item in permissions.get('items'): item_type = item.get('type') if item_type == 'ArtistInfo': artist_ids.append(item.get('id')) elif item_type == 'Vendor': if item.get('id') == '*': return AdminPermissionsType({ 'artist_ids': ['*'], 'vendor_ids': ['*'], 'subaccount_ids': ['*'], 'label_participant_ids': ['*'], }) vendor_ids.append(item.get('id')) elif item_type in ['Subaccount', 'SubAccount']: subaccount_ids.append(item.get('id')) elif item_type == 'LabelParticipant': label_participant_ids.append(item.get('id')) if not any([artist_ids, vendor_ids, subaccount_ids, label_participant_ids]): return NonePermissionsType({ 'artist_ids': None, 'vendor_ids': None, 'subaccount_ids': None, 'label_participant_ids': None, }) return NonAdminPermissionsType({ 'artist_ids': artist_ids, 'vendor_ids': vendor_ids, 'subaccount_ids': subaccount_ids, 'label_participant_ids': label_participant_ids, }) def get_all_permissions_for_profile(profile_type: str | None, profile_id: str | None) -> PermissionType: """Return a dict containing resource permissions based on Insights profile. Args: profile_type (str): The profile type. profile_id (int): The profile id. Returns: dict: a dict containing resources the user has access to. """ if profile_id is None or profile_type is None: return { 'artist_ids': None, 'vendor_ids': None, 'subaccount_ids': None, 'label_participant_ids': None } response = ows_permissions.get_all_resources(profile_type, profile_id) return _parse_profile_permissions(response.message) def get_permissions(request_context: Any) -> PermissionType: """Return a dict containing resource permissions based on request context Args: request_context (RequestContext): request context Returns: dict: a dict containing resources the user has access to """ result = NonePermissionsType({ 'artist_ids': None, 'vendor_ids': None, 'subaccount_ids': None, 'label_participant_ids': None }) if request_context.context_type != owsrequest_headers.CONTEXT_TYPE_PROFILE: return result profile_type = request_context.profile_type profile_id = request_context.profile_id profile_permissions = get_all_permissions_for_profile(profile_type, profile_id) return profile_permissions def get_request_permissions() -> PermissionType: """Return a dict containing resource permissions based on global request context Returns: dict: a dict containing resources the user has access to """ request_context = context.get_request_context_from_headers(request.headers) return get_permissions(request_context)