def validate_value( type: NotificationSettingTypes, value_param: str, context: Optional[List[str]] = None ) -> NotificationSettingOptionValues: try: value = NotificationSettingOptionValues(value_param) except ValueError: raise ParameterValidationError(f"Unknown value: {value_param}", context) if not helper_validate(type, value): raise ParameterValidationError(f"Invalid value for type {type}: {value}", context) return value
def validate_type( type: str, context: Optional[List[str]] = None) -> NotificationSettingTypes: try: return {v: k for k, v in NOTIFICATION_SETTING_TYPES.items()}[type] except KeyError: raise ParameterValidationError(f"Unknown type: {type}", context)
def validate_projects( project_ids_to_look_up: Set[int], user: Optional[Any] = None, team: Optional[Any] = None, ) -> Mapping[int, Any]: if not project_ids_to_look_up: return {} if user: projects_by_id = { project.id: project for project in user.get_projects() } elif team: projects_by_id = { project.id: project for project in team.get_projects() } else: raise Exception("User or Team must be set.") missing_project_ids = project_ids_to_look_up - projects_by_id.keys() if missing_project_ids: raise ParameterValidationError( f"Invalid project IDs: {missing_project_ids}") return intersect_dict_set(projects_by_id, project_ids_to_look_up)
def validate_organizations( organization_ids_to_look_up: Set[int], user: Optional[Any] = None, team: Optional[Any] = None, ) -> Mapping[int, Any]: if not organization_ids_to_look_up: return {} if user: organizations_by_id = { organization.id: organization for organization in user.get_orgs() } elif team: organizations_by_id = {team.organization.id: team.organization} else: raise Exception("User or Team must be set.") missing_organization_ids = organization_ids_to_look_up - organizations_by_id.keys( ) if missing_organization_ids: raise ParameterValidationError( f"Invalid organization IDs: {missing_organization_ids}") return intersect_dict_set(organizations_by_id, organization_ids_to_look_up)
def validate_type( type: str, context: Optional[List[str]] = None) -> NotificationSettingTypes: try: return NotificationSettingTypes[type.upper()] except KeyError: raise ParameterValidationError(f"Unknown type: {type}", context)
def validate_scope_type( scope_type: str, context: Optional[List[str]] = None ) -> NotificationScopeType: try: return NotificationScopeType(scope_type) except ValueError: raise ParameterValidationError(f"Unknown scope_type: {scope_type}", context)
def validate_provider( provider: str, available_providers: Optional[Set[ExternalProviders]] = None, context: Optional[List[str]] = None, ) -> ExternalProviders: provider_option = get_provider_enum(provider) if not provider_option: raise ParameterValidationError(f"Unknown provider: {provider}", context) # If not available_providers are provider, assume all are acceptable if available_providers and provider_option not in available_providers: raise ParameterValidationError( f'The provider "{provider}" is not supported. We currently accept {available_providers} identities.' ) return provider_option
def validate_scope_type( scope_type: str, context: Optional[List[str]] = None) -> NotificationScopeType: try: return {v: k for k, v in NOTIFICATION_SCOPE_TYPE.items()}[scope_type] except KeyError: raise ParameterValidationError(f"Unknown scope_type: {scope_type}", context)
def validate_provider( provider: str, context: Optional[List[str]] = None) -> ExternalProviders: try: return ExternalProviders(provider) except ValueError: raise ParameterValidationError(f"Unknown provider: {provider}", context)
def validate_value( type: NotificationSettingTypes, value_param: str, context: Optional[List[str]] = None ) -> NotificationSettingOptionValues: try: value = {v: k for k, v in NOTIFICATION_SETTING_OPTION_VALUES.items() }[value_param] except KeyError: raise ParameterValidationError(f"Unknown value: {value_param}", context) if value != NotificationSettingOptionValues.DEFAULT and not helper_validate( type, value): raise ParameterValidationError( f"Invalid value for type {type}: {value}", context) return value
def validate_scope( scope_id: Union[int, str], scope_type: NotificationScopeType, user: Optional[Any] = None, context: Optional[List[str]] = None, ) -> int: if user and scope_type == NotificationScopeType.USER: if scope_id == "me": # Overwrite "me" with the current user's ID. scope_id = user.id elif scope_id != str(user.id): raise ParameterValidationError(f"Incorrect user ID: {scope_id}", context) try: return int(scope_id) except ValueError: raise ParameterValidationError(f"Invalid ID: {scope_id}", context)
def validate( data: Mapping[str, Mapping[str, Mapping[int, Mapping[str, str]]]], user: Optional[Any] = None, team: Optional[Any] = None, ) -> Iterable[Tuple[ExternalProviders, NotificationSettingTypes, NotificationScopeType, int, NotificationSettingOptionValues, ], ]: """ Validate some serialized notification settings. If invalid, raise an exception. Otherwise, return them as a list of tuples. """ if not data: raise ParameterValidationError("Payload required") parent_context = ["notification_settings"] context = parent_context notification_settings_to_update: Dict[ Tuple[NotificationSettingTypes, NotificationScopeType, int, ExternalProviders, ], NotificationSettingOptionValues, ] = {} project_ids_to_look_up: Set[int] = set() organization_ids_to_look_up: Set[int] = set() for type_key, notifications_by_type in get_valid_items(data, context): type = validate_type(type_key, context) context = parent_context + [type_key] for scope_type_key, notifications_by_scope_type in get_valid_items( notifications_by_type, context): scope_type = validate_scope_type(scope_type_key, context) context = parent_context + [type_key, scope_type_key] for scope_id, notifications_by_scope_id in get_valid_items( notifications_by_scope_type, context): scope_id = validate_scope(scope_id, scope_type, user, context) if scope_type == NotificationScopeType.PROJECT: project_ids_to_look_up.add(scope_id) elif scope_type == NotificationScopeType.ORGANIZATION: organization_ids_to_look_up.add(scope_id) context = parent_context + [ type_key, scope_type_key, str(scope_id) ] for provider_key, value_key in get_valid_items( notifications_by_scope_id, context): provider = validate_provider(provider_key, context=context) value = validate_value(type, value_key, context) notification_settings_to_update[(type, scope_type, scope_id, provider)] = value validate_projects(project_ids_to_look_up, user=user, team=team) validate_organizations(organization_ids_to_look_up, user=user, team=team) return {(provider, type, scope_type, scope_id, value) for ( type, scope_type, scope_id, provider, ), value in notification_settings_to_update.items()}
def get_valid_items(data: Mapping[Any, Any], context: Optional[List[str]] = None) -> AbstractSet[Any]: try: return data.items() except AttributeError: raise ParameterValidationError("Malformed JSON in payload", context)
def validate_provider(provider: str, context: Optional[List[str]] = None) -> ExternalProviders: provider_option = get_provider_enum(provider) if provider_option: return provider_option raise ParameterValidationError(f"Unknown provider: {provider}", context)