diff --git a/bento_beacon/authz/access.py b/bento_beacon/authz/access.py index 7e08097..3d2b229 100644 --- a/bento_beacon/authz/access.py +++ b/bento_beacon/authz/access.py @@ -1,8 +1,8 @@ -import functools -import requests +import aiocache +import aiohttp from flask import current_app - from .headers import auth_header_from_request +from ..utils.http import tcp_connector __all__ = [ "get_access_token", @@ -10,57 +10,63 @@ ] -@functools.cache -def get_token_endpoint_from_openid_config_url(url: str, validate_ssl: bool = True): - r = requests.get(url, verify=validate_ssl) +@aiocache.cached() +async def get_token_endpoint_from_openid_config_url(url: str): + async with aiohttp.ClientSession(connector=tcp_connector(current_app.config)) as s: + r = await s.get(url) + if not r.ok: raise Exception(f"Received not-OK response from OIDC config URL: {r.status_code}") - return r.json()["token_endpoint"] + response = await r.json() + return response["token_endpoint"] -def get_access_token() -> str | None: + +async def get_access_token() -> str | None: logger = current_app.logger oidc_config_url = current_app.config["OPENID_CONFIG_URL"] client_id = current_app.config["CLIENT_ID"] client_secret = current_app.config["CLIENT_SECRET"] - validate_ssl = current_app.config["BENTO_VALIDATE_SSL"] if not all((oidc_config_url, client_id, client_secret)): logger.error("Could not retrieve access token; one of OPENID_CONFIG_URL | CLIENT_ID | CLIENT_SECRET is not set") return None try: - token_endpoint = get_token_endpoint_from_openid_config_url(oidc_config_url, validate_ssl=validate_ssl) + token_endpoint = await get_token_endpoint_from_openid_config_url(oidc_config_url) + current_app.logger.info(f"token_endpoint: {token_endpoint}") except Exception as e: logger.error(f"Could not retrieve access token; got exception from OpenID config URL: {e}") return None - token_res = requests.post( - token_endpoint, - verify=validate_ssl, - data={ - "grant_type": "client_credentials", - "client_id": client_id, - "client_secret": client_secret, - }, - ) + async with aiohttp.ClientSession(connector=tcp_connector(current_app.config)) as s: + token_res = await s.post( + token_endpoint, + data={ + "grant_type": "client_credentials", + "client_id": client_id, + "client_secret": client_secret, + }, + ) + + res = await token_res.json() if not token_res.ok: - logger.error(f"Could not retrieve access token; got error response: {token_res.json()}") + logger.error(f"Could not retrieve access token; got error response: {res}") return None - return token_res.json()["access_token"] + return res["access_token"] -def create_access_header_or_fall_back(): +async def create_access_header_or_fall_back(): logger = current_app.logger if not current_app.config["AUTHZ_BENTO_REQUESTS_ENABLED"]: logger.warning("AUTHZ_BENTO_REQUESTS_ENABLED is false; falling back to request headers") return auth_header_from_request() - access_token = get_access_token() + access_token = await get_access_token() if access_token is None: logger.error("create_access_header_or_fall_back: falling back to request headers") return auth_header_from_request()