fix(web): name the scope problem behind a Gitea 403

Both listing endpoints answering 403 means Gitea authenticated the token and
then rejected its scope -- exactly what an OIDC login token with only
`openid profile` gets. The card showed a bare "Gitea API returned HTTP 403",
which sends the operator hunting the wrong thing (admin rights, allowlist,
URL). Say what it is and name both fixes: add an API read scope to
`[web.oidc] scopes`, or configure the keyring PAT fallback. A 403 on the admin
listing alone still falls through to the user listing as before, and a 404
there keeps its plain message.
This commit is contained in:
2026-07-25 15:03:25 +02:00
parent af7dee60e5
commit 4aedd937d7
2 changed files with 34 additions and 1 deletions
+20 -1
View File
@@ -330,9 +330,10 @@ def test_admin_denied_falls_back_to_user_endpoint(
]
def test_both_endpoints_denied_degrades(
def test_both_endpoints_denied_names_the_scope_problem(
tmp_path: Path, monkeypatch: pytest.MonkeyPatch
) -> None:
"""403 on both listings means "valid token, no API scope" -- say that."""
_install_urlopen(monkeypatch, lambda _url: _http_error(403))
view = list_executions(_make_config(tmp_path), [], token="tok", now=_NOW)
@@ -341,6 +342,24 @@ def test_both_endpoints_denied_degrades(
assert view.source == "none"
assert view.error is not None
assert "403" in view.error
assert "read:repository" in view.error
assert "gitea_token_cred" in view.error
assert view.auth_failed is False # a refresh would not fix a scope problem
def test_user_endpoint_404_keeps_the_plain_http_error(
tmp_path: Path, monkeypatch: pytest.MonkeyPatch
) -> None:
"""Only a 403 on the *user* listing implies a scope problem, not a 404."""
def handler(url: str) -> Any:
return _http_error(403 if "/admin/" in url else 404)
_install_urlopen(monkeypatch, handler)
view = list_executions(_make_config(tmp_path), [], token="tok", now=_NOW)
assert view.error == "Gitea API returned HTTP 404."
# ── degraded paths ──────────────────────────────────────────────────────────