fix devpi gateway auth
This commit is contained in:
@@ -12,11 +12,12 @@ On every ``get`` the helper:
|
||||
1. Reads the auth file (same path the gateway uses:
|
||||
``~/.forge-stack-devpi-gateway-gitea/client-auth.json`` by default,
|
||||
or whatever ``FSDGG_AUTH_STORE_PATH`` / ``FSDGG_RUNTIME_DIR`` point
|
||||
at). If the file is missing, the helper passes git's input through
|
||||
unchanged so the normal prompt chain continues.
|
||||
at). If the file is missing, the helper emits no output so the next
|
||||
helper in Git's chain can answer without receiving echoed fields from
|
||||
this helper.
|
||||
2. Checks that the git request host matches the host recorded in
|
||||
``_forge_gitea_base_url`` (or ``FORGE_GITEA_URL``). If not, passes
|
||||
through. This prevents OAuth token disclosure to unrelated
|
||||
``_forge_gitea_base_url`` (or ``FORGE_GITEA_URL``). If not, emits no
|
||||
output. This prevents OAuth token disclosure to unrelated
|
||||
hosts even if git mis-scopes its lookup.
|
||||
3. If ``gitea_access_token`` is live, emits
|
||||
``username=<stored-user>`` and ``password=<gitea_access_token>``.
|
||||
@@ -29,7 +30,7 @@ Security notes
|
||||
--------------
|
||||
* The helper never writes to stdout except the credential key=value
|
||||
block. Logs go to stderr.
|
||||
* On OAuth refresh failure the helper exits **non-zero** rather than silently
|
||||
* On OAuth refresh failure the helper emits no credentials rather than
|
||||
returning stale credentials.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
@@ -82,6 +83,10 @@ def emit(fields: dict[str, str]) -> None:
|
||||
sys.stdout.write(f"{key}={value}\n")
|
||||
|
||||
|
||||
def emit_no_credentials() -> None:
|
||||
return
|
||||
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Host matching
|
||||
# --------------------------------------------------------------------
|
||||
@@ -150,10 +155,10 @@ def _request_matches(
|
||||
def cmd_get(fields: dict[str, str]) -> int:
|
||||
configured = _configured_host()
|
||||
if configured is None:
|
||||
emit(fields) # pass-through: helper scope is unknown
|
||||
emit_no_credentials()
|
||||
return 0
|
||||
if not _request_matches(fields, configured):
|
||||
emit(fields) # pass-through: request targets a different host
|
||||
emit_no_credentials()
|
||||
return 0
|
||||
|
||||
state = forge_auth.AuthFile.read(forge_auth.auth_store_path())
|
||||
@@ -172,7 +177,7 @@ def cmd_get(fields: dict[str, str]) -> int:
|
||||
"FSDGG_CLI_CLIENT_ID are not set in the environment; "
|
||||
"cannot refresh. Run 'just login' to re-authenticate."
|
||||
)
|
||||
emit(fields)
|
||||
emit_no_credentials()
|
||||
return 0
|
||||
try:
|
||||
refreshed = forge_auth.run_refresh(config, must_refresh=True)
|
||||
@@ -181,7 +186,7 @@ def cmd_get(fields: dict[str, str]) -> int:
|
||||
f"token refresh failed: {exc}. "
|
||||
f"Run 'just login' to re-authenticate."
|
||||
)
|
||||
emit(fields)
|
||||
emit_no_credentials()
|
||||
return 0
|
||||
_emit_credentials(fields, refreshed)
|
||||
return 0
|
||||
@@ -190,7 +195,7 @@ def cmd_get(fields: dict[str, str]) -> int:
|
||||
def _emit_credentials(fields: dict[str, str], state: forge_auth.AuthFile) -> None:
|
||||
token = state.gitea_access_token
|
||||
if not token:
|
||||
emit(fields)
|
||||
emit_no_credentials()
|
||||
return
|
||||
out = dict(fields)
|
||||
out["username"] = state.username or fields.get("username") or "oauth"
|
||||
|
||||
Reference in New Issue
Block a user