def validate_token_info( token_info: InternalSecurityCheckResponse, scope_validate_func: ScopeValidateFunc, required_scopes: Sequence[str], ) -> InternalSecurityCheckResponse: scopes: Optional[Sequence[str]] = None if not token_info: return None if "scopes" in token_info: scopes = token_info.get("scopes") elif "scope" in token_info: scope = token_info.get("scope") if isinstance(scope, str): scopes = scope.split() else: raise ValueError("'scope' should be a string") if not scopes: raise ValueError("missing scopes in token info") if not scope_validate_func(required_scopes, scopes): raise SecurityException( f"Invalid scopes: required: {required_scopes}, provided: {scopes}") return token_info
def load_bearer_info_func(scheme: SecurityScheme) -> BearerInfoFunc: if not scheme.x_bearer_info_func: raise SecurityException("Missing Bearer info function") try: return load_handler(scheme.x_bearer_info_func) except (AttributeError, ValueError) as err: raise SecurityException from err
def load_api_key_info_func(scheme: SecurityScheme) -> APIKeyInfoFunc: if not scheme.x_api_key_info_func: raise SecurityException("Missing API Key info function") try: return load_handler(scheme.x_api_key_info_func) except (AttributeError, ValueError) as err: raise SecurityException from err
def validate_scopes(required_scopes: Sequence[str], token_scopes: Sequence[str]) -> bool: """Validates that all require scopes are present in the token scopes""" missing_scopes = set(required_scopes) - set(token_scopes) if missing_scopes: raise SecurityException(f"Missing required scopes: {missing_scopes}") return not missing_scopes
def decorator(handler: Func[T]) -> Func[T]: if handler is None: raise SecurityException("invalid or missing handler") @wraps(handler) def handler_with_security(*args: Any, **kwargs: Any) -> T: # match the args that connexion passes to handlers after a security check token_info = security_handler(current_flask_request) user = token_info.get("sub", token_info.get("uid")) return handler(*args, user=user, token_info=token_info, **kwargs) return handler_with_security
def extract_auth_header(request: Request) -> Optional[Tuple[str, str]]: authorization = request.headers.get("Authorization") if not authorization: return None try: lhs, rhs = authorization.split(None, 1) if not lhs or not rhs: raise SecurityException("invalid Authorization header" " expected: <format> <value>" f" found {authorization}") return lhs, rhs except ValueError as err: raise SecurityException from err
def security_handler(request: Request) -> SecurityInfo: # apply the security schemes in the order listed in the API file for check in security_checks: # if a security check fails if will raise the appropriate exception # if the security check passes it will return a dict of kwargs to pass to the handler # noqa: 501 # if the check is not applicable based on lack provided argument the check will return None indicating # noqa: 501 # that the next (if any) check should be run. security_args = check(request) if security_args: return security_args raise SecurityException("No checks passed")