import requests from apollo_utils.service.exceptions import Unauthorized from flask import current_app as app from flask import g, request from http import HTTPStatus from src.config.auth import Auth0ManagementConfig from src.utils import ComplexAttribute, ComplexEntity def authorize(): """Check request authorization key. Raises: Unauthorized: If authorization token is invalid or missing. """ blueprint = request.blueprint if blueprint and getattr(app.blueprints.get(blueprint), "_no_authorize", False): return endpoint = request.endpoint if not endpoint: return if getattr(app.view_functions.get(endpoint), "_no_authorize", False): return api_key = request.headers.get("Authorization") if not api_key: raise Unauthorized("Authorization key is not provided.") if api_key != app.config["AUTH_API_KEY"]: raise Unauthorized("Invalid authorization key.") def check_health() -> bool: """Check Auth0 core health.""" response = requests.get( f"https://{Auth0ManagementConfig.DOMAIN}/test", timeout=app.config["DEFAULT_REQUEST_TIMEOUT"] ) # nosec B113 return response.status_code == HTTPStatus.OK class AuthField(ComplexAttribute): """Descriptor for authorization data. Raise Unauthorized on getting data if data is None.""" def __get__(self, instance, owner): value = super().__get__(instance, owner) if value is None: raise Unauthorized(f"{self.outer_name} is needed but not provided.") return value class User(ComplexEntity): """User object for current request. As ComplexEntity provides __contains__ and get methods also. Args: user_id: str - user id for current request. Raise Unauthorized on getting user_id if it is None. """ user_id = AuthField() def __init__(self, user_id): self.user_id = user_id def get_user() -> User: """Returns user object for current request.""" return g._user def no_authorize(obj): """View function or blueprint decorator to skip authorization for.""" obj._no_authorize = True return obj