Add authentication for product pages

This commit is contained in:
Brendan Reilly
2025-04-17 16:28:13 -04:00
parent 5a0c8b37e1
commit 23f77986e2
3 changed files with 72 additions and 5 deletions

View File

@@ -662,6 +662,21 @@ class Config(object):
"stream has been released. If it has, the stream may be modified automatically "
"to use a different support stream.",
},
"product_pages_token_endpoint": {
"type": str,
"default": "",
"desc": "The endpoint to request a token to authenticate with Product Pages.",
},
"product_pages_oidc_client_id": {
"type": str,
"default": "",
"desc": "Client ID to authenticate with the token endpoint.",
},
"product_pages_client_secret": {
"type": str,
"default": "",
"desc": "Client secret to authenticate with the token endpoint.",
},
"product_pages_module_streams": {
"type": dict,
"default": {},

View File

@@ -387,6 +387,29 @@ def resolve_base_module_virtual_streams(db_session, name, streams):
return new_streams
def _product_pages_oidc_auth():
"""
Obtain an OIDC access token to authenticate with Product Pages
"""
try:
token_response = requests.post(
conf.product_pages_token_endpoint,
{
'grant_type': 'client_credentials',
'client_id': conf.product_pages_oidc_client_id,
'client_secret': conf.product_pages_client_secret,
},
)
token_response.raise_for_status()
except requests.exceptions.RequestException as e:
log.error(f"Product Pages authentication failed: {e}")
raise RuntimeError("Failed to authenticate with Product Pages.")
access_token = token_response.json()['access_token']
return {'Authorization': f'Bearer {access_token}'}
def _process_support_streams(db_session, mmd, params):
"""
Check if any buildrequired base modules require a support stream suffix.
@@ -407,6 +430,17 @@ def _process_support_streams(db_session, mmd, params):
elif not conf.product_pages_module_streams:
log.debug(config_msg, "product_pages_module_streams")
return
elif not conf.product_pages_token_endpoint:
log.debug(config_msg, "product_pages_token_endpoint")
return
elif not conf.product_pages_oidc_client_id:
log.debug(config_msg, "product_pages_oidc_client_id")
return
elif not conf.product_pages_client_secret:
log.debug(config_msg, "product_pages_client_secret")
return
auth_header = _product_pages_oidc_auth()
buildrequire_overrides = params.get("buildrequire_overrides", {})
@@ -427,7 +461,7 @@ def _process_support_streams(db_session, mmd, params):
conf.product_pages_url.rstrip("/"), pp_release)
try:
pp_rv = requests.get(schedule_url, timeout=15)
pp_rv = requests.get(schedule_url, timeout=15, headers=auth_header)
# raise exception if we receive 404
pp_rv.raise_for_status()
pp_json = pp_rv.json()
@@ -459,7 +493,7 @@ def _process_support_streams(db_session, mmd, params):
Check if the stream has been released. Return True if it has.
"""
try:
pp_rv = requests.get(url, timeout=15)
pp_rv = requests.get(url, timeout=15, headers=auth_header)
pp_json = pp_rv.json()
# Catch requests failures and JSON parsing errors
except (requests.exceptions.RequestException, ValueError):