mirror of
https://github.com/pypa/gh-action-pypi-publish.git
synced 2024-11-22 16:41:07 -05:00
oidc-exchange: render claims if exchange fails
Signed-off-by: William Woodruff <william@trailofbits.com>
This commit is contained in:
parent
413a8d5d62
commit
71a0032909
1 changed files with 45 additions and 1 deletions
|
@ -1,3 +1,5 @@
|
||||||
|
import base64
|
||||||
|
import json
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
from http import HTTPStatus
|
from http import HTTPStatus
|
||||||
|
@ -50,6 +52,25 @@ _SERVER_REFUSED_TOKEN_EXCHANGE_MESSAGE = """
|
||||||
Token request failed: the server refused the request for the following reasons:
|
Token request failed: the server refused the request for the following reasons:
|
||||||
|
|
||||||
{reasons}
|
{reasons}
|
||||||
|
|
||||||
|
This generally indicates a trusted publisher configuration error, but could
|
||||||
|
also indicate an internal error on GitHub or PyPI's part.
|
||||||
|
|
||||||
|
{rendered_claims}
|
||||||
|
"""
|
||||||
|
|
||||||
|
_RENDERED_CLAIMS = """
|
||||||
|
The claims rendered below are **for debugging purposes only**. You should **not**
|
||||||
|
use them to configure a trusted publisher unless they already match your expectations.
|
||||||
|
|
||||||
|
If a claim is not present in the claim set, then it is rendered as `MISSING`.
|
||||||
|
|
||||||
|
* `sub`: `{sub}`
|
||||||
|
* `repository`: `{repository}`
|
||||||
|
* `repository_owner`: `{repository_owner}`
|
||||||
|
* `repository_owner_id`: `{repository_owner_id}`
|
||||||
|
* `job_workflow_ref`: `{job_workflow_ref}`
|
||||||
|
* `ref`: `{ref}`
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Rendered if the package index's token response isn't valid JSON.
|
# Rendered if the package index's token response isn't valid JSON.
|
||||||
|
@ -121,6 +142,23 @@ def assert_successful_audience_call(resp: requests.Response, domain: str):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def render_claims(oidc_token: str) -> str:
|
||||||
|
_, payload, _ = oidc_token.split(".", 2)
|
||||||
|
claims = json.loads(base64.urlsafe_b64decode(payload))
|
||||||
|
|
||||||
|
def _get(name: str) -> str:
|
||||||
|
return claims.get(name, "MISSING")
|
||||||
|
|
||||||
|
return _RENDERED_CLAIMS.format(
|
||||||
|
sub=_get("sub"),
|
||||||
|
repository=_get("repository"),
|
||||||
|
repository_owner=_get("repository_owner"),
|
||||||
|
repository_owner_id=_get("repository_owner_id"),
|
||||||
|
job_workflow_ref=_get("job_workflow_ref"),
|
||||||
|
ref=_get("ref"),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
repository_url = get_normalized_input("repository-url")
|
repository_url = get_normalized_input("repository-url")
|
||||||
repository_domain = urlparse(repository_url).netloc
|
repository_domain = urlparse(repository_url).netloc
|
||||||
token_exchange_url = f"https://{repository_domain}/_/oidc/github/mint-token"
|
token_exchange_url = f"https://{repository_domain}/_/oidc/github/mint-token"
|
||||||
|
@ -165,7 +203,13 @@ if not mint_token_resp.ok:
|
||||||
for error in mint_token_payload["errors"]
|
for error in mint_token_payload["errors"]
|
||||||
)
|
)
|
||||||
|
|
||||||
die(_SERVER_REFUSED_TOKEN_EXCHANGE_MESSAGE.format(reasons=reasons))
|
rendered_claims = render_claims(oidc_token)
|
||||||
|
|
||||||
|
die(
|
||||||
|
_SERVER_REFUSED_TOKEN_EXCHANGE_MESSAGE.format(
|
||||||
|
reasons=reasons, rendered_claims=rendered_claims
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
pypi_token = mint_token_payload.get("token")
|
pypi_token = mint_token_payload.get("token")
|
||||||
if pypi_token is None:
|
if pypi_token is None:
|
||||||
|
|
Loading…
Reference in a new issue