All checks were successful
ci/woodpecker/pr/ci Pipeline was successful
Round-6 remediation for PR #866 addressing four cross-host exact-diff audit blockers (REQUEST_CHANGES governs): Blocker 1 (detect-platform.sh get_gitea_token_for_login line parser): the PyYAML-absence fallback attributed any `key: value` at any depth to the current login, so a token from a nested sub-map or a mis-indented line could be selected where PyYAML fails closed, and inline comments were not stripped. The fallback is now scope-aware — a field attaches only at the entry's own direct-field indentation, only list items at the login list's own dash indent open an entry — and _strip_scalar strips a trailing inline comment like PyYAML. It is therefore only ever MORE conservative than PyYAML, never less. Blocker 2 (detect-platform.sh host bind): credential binding compared parsed.hostname only, dropping the port, so a :9443 login satisfied a portless host and a matching :8443 login was rejected. Binding now normalizes scheme + host + effective port (scheme default applied symmetrically) exactly like gitea_url_matches_host. Blocker 3 (issue-comment.sh + pr-review.sh read-back URL check): verification used path.endswith, accepting a look-alike host or a decoy path prefix. It now pins the returned issue_url/pull_request_url ORIGIN (scheme+host+effective-port) and FULL path (deployment prefix + exact owner/repo + kind + number). A new GITEA_WEB_BASE is exported from gitea_resolve_api_for_login for this. Blocker 4 (pr-review.sh gitea_submit_review_verified): the submitted review body was not verified, so a finalized/reused pending review id carrying foreign Content passed. The persisted body is now bound to the exact submitted body. Tests: added forced-PyYAML-absence parser-equivalence fixtures (nested sub-map, sibling, mis-indent, inline comment, tab-indent fail-closed, port match/mismatch) to test-gitea-login-resolution.sh; URL-forgery fail-closed cases (wrong-host/owner/repo + prefix injection) to both write suites; and a reused-review-id body-mismatch case to the pr-review suite. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
444 lines
16 KiB
Bash
Executable File
444 lines
16 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Regression harness for host-specific Gitea tea login resolution.
|
|
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
WORK_DIR="${MOSAIC_TEST_WORK_DIR:-$PWD/.mosaic-test-work/gitea-login-resolution}"
|
|
REPO_DIR="$WORK_DIR/repo"
|
|
BIN_DIR="$WORK_DIR/bin"
|
|
LOG_FILE="$WORK_DIR/calls.log"
|
|
CREDENTIALS_FILE="$WORK_DIR/credentials.json"
|
|
|
|
rm -rf "$WORK_DIR"
|
|
mkdir -p "$REPO_DIR" "$BIN_DIR"
|
|
|
|
git -C "$REPO_DIR" init -q
|
|
git -C "$REPO_DIR" remote add origin https://git.uscllc.com/USC/uconnect.git
|
|
|
|
cat > "$CREDENTIALS_FILE" <<'JSON'
|
|
{
|
|
"gitea": {
|
|
"mosaicstack": {
|
|
"url": "https://git.mosaicstack.dev",
|
|
"token": "mosaic-token"
|
|
},
|
|
"usc": {
|
|
"url": "https://git.uscllc.com",
|
|
"token": "usc-token"
|
|
}
|
|
}
|
|
}
|
|
JSON
|
|
|
|
cat > "$BIN_DIR/tea" <<'SH'
|
|
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
if [[ "$*" == "login list --output json" ]]; then
|
|
cat <<'JSON'
|
|
[
|
|
{"name":"evil-usc","url":"https://evilgit.uscllc.com","user":"bad.actor"},
|
|
{"name":"usc","url":"https://git.uscllc.com","user":"ci-bot"}
|
|
]
|
|
JSON
|
|
exit 0
|
|
fi
|
|
|
|
if [[ "${1:-}" == "api" ]]; then
|
|
printf '%s\n' '{"login":"ci-bot"}'
|
|
exit 0
|
|
fi
|
|
|
|
printf 'tea %s\n' "$*" >> "$MOSAIC_TEST_LOG"
|
|
if [[ "${MOSAIC_TEA_FAIL_PR_CREATE:-}" == "1" && "$*" == pr\ create* ]]; then
|
|
echo 'GetUserByName: simulated stale login failure' >&2
|
|
exit 1
|
|
fi
|
|
exit 0
|
|
SH
|
|
|
|
cat > "$BIN_DIR/curl" <<'SH'
|
|
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
printf 'curl %s\n' "$*" >> "$MOSAIC_TEST_LOG"
|
|
url="${*: -1}"
|
|
case "$url" in
|
|
*/pulls/*.diff)
|
|
printf 'diff --git a/file b/file\n'
|
|
;;
|
|
*/pulls/*)
|
|
printf '{"head":{"sha":"abc123"}}'
|
|
;;
|
|
*/commits/*/status)
|
|
printf '{"state":"success","statuses":[{"context":"ci/mock","status":"success"}]}'
|
|
;;
|
|
*)
|
|
printf '{}'
|
|
;;
|
|
esac
|
|
SH
|
|
|
|
chmod +x "$BIN_DIR/tea" "$BIN_DIR/curl"
|
|
|
|
run_in_repo() {
|
|
(
|
|
cd "$REPO_DIR"
|
|
PATH="$BIN_DIR:$PATH" \
|
|
MOSAIC_CREDENTIALS_FILE="$CREDENTIALS_FILE" \
|
|
MOSAIC_TEST_LOG="$LOG_FILE" \
|
|
"$@"
|
|
)
|
|
}
|
|
|
|
usc_login=$(run_in_repo bash -c '
|
|
export GITEA_LOGIN=mosaicstack
|
|
export GITEA_URL=https://git.mosaicstack.dev
|
|
source "'"$SCRIPT_DIR"'/detect-platform.sh"
|
|
get_gitea_login
|
|
')
|
|
if [[ "$usc_login" != "usc" ]]; then
|
|
echo "Expected USC host to resolve tea login 'usc' despite stale mosaicstack env; got '$usc_login'" >&2
|
|
exit 1
|
|
fi
|
|
|
|
usc_login_with_usc_url=$(run_in_repo bash -c '
|
|
export GITEA_LOGIN=mosaicstack
|
|
export GITEA_URL=https://git.uscllc.com
|
|
source "'"$SCRIPT_DIR"'/detect-platform.sh"
|
|
get_gitea_login
|
|
')
|
|
if [[ "$usc_login_with_usc_url" != "usc" ]]; then
|
|
echo "Expected USC host to reject stale GITEA_LOGIN even when GITEA_URL matches USC; got '$usc_login_with_usc_url'" >&2
|
|
exit 1
|
|
fi
|
|
|
|
usc_login_without_url=$(run_in_repo bash -c '
|
|
export GITEA_LOGIN=mosaicstack
|
|
unset GITEA_URL
|
|
source "'"$SCRIPT_DIR"'/detect-platform.sh"
|
|
get_gitea_login
|
|
')
|
|
if [[ "$usc_login_without_url" != "usc" ]]; then
|
|
echo "Expected USC host to ignore unmatched GITEA_LOGIN without URL; got '$usc_login_without_url'" >&2
|
|
exit 1
|
|
fi
|
|
|
|
git -C "$REPO_DIR" remote set-url origin https://hermes:token@git.uscllc.com/USC/uconnect.git
|
|
embedded_host=$(run_in_repo bash -c '
|
|
source "'"$SCRIPT_DIR"'/detect-platform.sh"
|
|
get_remote_host
|
|
')
|
|
if [[ "$embedded_host" != "git.uscllc.com" ]]; then
|
|
echo "Expected credential-bearing remote host to strip userinfo; got '$embedded_host'" >&2
|
|
exit 1
|
|
fi
|
|
git -C "$REPO_DIR" remote set-url origin https://git.uscllc.com/USC/uconnect.git
|
|
|
|
override_login=$(run_in_repo bash -c '
|
|
export GITEA_LOGIN=usc
|
|
source "'"$SCRIPT_DIR"'/detect-platform.sh"
|
|
get_gitea_login_for_repo_override
|
|
')
|
|
if [[ "$override_login" != "usc" ]]; then
|
|
echo "Expected --repo override path to honor explicit GITEA_LOGIN; got '$override_login'" >&2
|
|
exit 1
|
|
fi
|
|
|
|
git -C "$REPO_DIR" remote set-url origin https://git.mosaicstack.dev/mosaicstack/stack.git
|
|
: > "$LOG_FILE"
|
|
run_in_repo env GITEA_LOGIN=usc "$SCRIPT_DIR/issue-list.sh" --repo USC/uconnect -n 1
|
|
grep -q -- 'tea issues list --repo USC/uconnect --login usc' "$LOG_FILE"
|
|
git -C "$REPO_DIR" remote set-url origin https://git.uscllc.com/USC/uconnect.git
|
|
|
|
: > "$LOG_FILE"
|
|
run_in_repo "$SCRIPT_DIR/issue-close.sh" -i 42
|
|
grep -q -- 'tea issue close 42 --repo USC/uconnect --login usc' "$LOG_FILE"
|
|
if grep -q -- '--login mosaicstack' "$LOG_FILE"; then
|
|
echo "issue-close.sh used hardcoded mosaicstack login on USC host" >&2
|
|
exit 1
|
|
fi
|
|
|
|
: > "$LOG_FILE"
|
|
run_in_repo "$SCRIPT_DIR/milestone-list.sh"
|
|
grep -q -- 'tea milestone list --repo USC/uconnect --login usc' "$LOG_FILE"
|
|
|
|
: > "$LOG_FILE"
|
|
run_in_repo "$SCRIPT_DIR/milestone-create.sh" -t "0.2.0" -d "USC milestone"
|
|
grep -q -- 'tea milestones create --title 0.2.0 --description USC milestone --repo USC/uconnect --login usc' "$LOG_FILE"
|
|
|
|
: > "$LOG_FILE"
|
|
run_in_repo "$SCRIPT_DIR/milestone-close.sh" -t "0.2.0"
|
|
grep -q -- 'tea milestone close 0.2.0 --repo USC/uconnect --login usc' "$LOG_FILE"
|
|
|
|
if command -v pwsh >/dev/null 2>&1; then
|
|
: > "$LOG_FILE"
|
|
run_in_repo pwsh -NoProfile -File "$SCRIPT_DIR/issue-list.ps1" -Limit 1
|
|
grep -q -- 'tea issues list --state open --limit 1 --repo USC/uconnect --login usc' "$LOG_FILE"
|
|
|
|
: > "$LOG_FILE"
|
|
run_in_repo pwsh -NoProfile -File "$SCRIPT_DIR/issue-create.ps1" -Title "PowerShell issue"
|
|
grep -q -- 'tea issue create --title PowerShell issue --repo USC/uconnect --login usc' "$LOG_FILE"
|
|
|
|
: > "$LOG_FILE"
|
|
run_in_repo pwsh -NoProfile -File "$SCRIPT_DIR/pr-list.ps1" -Limit 1
|
|
grep -q -- 'tea pr list --state open --limit 1 --repo USC/uconnect --login usc' "$LOG_FILE"
|
|
|
|
: > "$LOG_FILE"
|
|
run_in_repo pwsh -NoProfile -File "$SCRIPT_DIR/pr-create.ps1" -Title "PowerShell PR"
|
|
grep -q -- 'tea pr create --title PowerShell PR --head master --repo USC/uconnect --login usc' "$LOG_FILE"
|
|
|
|
: > "$LOG_FILE"
|
|
run_in_repo pwsh -NoProfile -File "$SCRIPT_DIR/pr-merge.ps1" -Number 42 -SkipQueueGuard
|
|
grep -q -- 'tea pr merge 42 --style squash --repo USC/uconnect --login usc' "$LOG_FILE"
|
|
|
|
: > "$LOG_FILE"
|
|
run_in_repo pwsh -NoProfile -File "$SCRIPT_DIR/milestone-create.ps1" -List
|
|
grep -q -- 'tea milestones list --repo USC/uconnect --login usc' "$LOG_FILE"
|
|
fi
|
|
|
|
: > "$LOG_FILE"
|
|
if run_in_repo "$SCRIPT_DIR/pr-diff.sh" --repo USC/uconnect -n 7 >/dev/null 2>&1; then
|
|
echo "Expected pr-diff.sh --repo without host to fail loud" >&2
|
|
exit 1
|
|
fi
|
|
if grep -q -- 'git.mosaicstack.dev/api/v1/repos/USC/uconnect' "$LOG_FILE"; then
|
|
echo "pr-diff.sh --repo defaulted API host to git.mosaicstack.dev" >&2
|
|
exit 1
|
|
fi
|
|
|
|
: > "$LOG_FILE"
|
|
run_in_repo env GITEA_URL=https://git.uscllc.com "$SCRIPT_DIR/pr-diff.sh" --repo USC/uconnect -n 7 >/dev/null
|
|
grep -q -- 'curl .*https://git.uscllc.com/api/v1/repos/USC/uconnect/pulls/7.diff' "$LOG_FILE"
|
|
|
|
: > "$LOG_FILE"
|
|
run_in_repo "$SCRIPT_DIR/pr-ci-wait.sh" --repo USC/uconnect --host git.uscllc.com -n 9 -t 2 -i 1
|
|
grep -q -- 'curl .*https://git.uscllc.com/api/v1/repos/USC/uconnect/pulls/9' "$LOG_FILE"
|
|
grep -q -- 'curl .*https://git.uscllc.com/api/v1/repos/USC/uconnect/commits/abc123/status' "$LOG_FILE"
|
|
|
|
: > "$LOG_FILE"
|
|
run_in_repo env MOSAIC_TEA_FAIL_PR_CREATE=1 GITEA_TOKEN=usc-token GITEA_URL=https://git.uscllc.com "$SCRIPT_DIR/pr-create.sh" -t "USC API fallback" -H feature/pr-create
|
|
grep -q -- 'tea pr create --repo USC/uconnect --login usc --title USC API fallback --head feature/pr-create' "$LOG_FILE"
|
|
grep -q -- 'curl .*Authorization: token usc-token .*https://git.uscllc.com/api/v1/repos/USC/uconnect/pulls' "$LOG_FILE"
|
|
if grep -q -- 'git.mosaicstack.dev/api/v1/repos/USC/uconnect/pulls' "$LOG_FILE"; then
|
|
echo "pr-create.sh API fallback defaulted USC repo to git.mosaicstack.dev" >&2
|
|
exit 1
|
|
fi
|
|
|
|
git -C "$REPO_DIR" remote set-url origin https://git.mosaicstack.dev/mosaicstack/stack.git
|
|
: > "$LOG_FILE"
|
|
run_in_repo env GITEA_TOKEN=mosaic-token GITEA_URL=https://git.mosaicstack.dev "$SCRIPT_DIR/issue-close.sh" -i 536
|
|
grep -q -- 'curl .*https://git.mosaicstack.dev/api/v1/repos/mosaicstack/stack/issues/536' "$LOG_FILE"
|
|
if grep -q -- 'tea issue close 536 .*--login mosaicstack' "$LOG_FILE"; then
|
|
echo "issue-close.sh invented a mosaicstack tea login instead of using API fallback" >&2
|
|
exit 1
|
|
fi
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# #560: loud diagnostic + host-derived login for BOTH instances + override-wins
|
|
# ---------------------------------------------------------------------------
|
|
|
|
# Loud diagnostic: a host with no matching tea login must emit an actionable
|
|
# error to stderr (the previous behavior was a SILENT failure). The original
|
|
# mock defines only usc/evil-usc logins, so mosaicstack resolution fails here.
|
|
git -C "$REPO_DIR" remote set-url origin https://git.mosaicstack.dev/mosaicstack/stack.git
|
|
diag_stderr=$(run_in_repo bash -c '
|
|
source "'"$SCRIPT_DIR"'/detect-platform.sh"
|
|
get_gitea_login_for_host git.mosaicstack.dev
|
|
' 2>&1 1>/dev/null || true)
|
|
if ! grep -q "no Gitea tea login matches host 'git.mosaicstack.dev'" <<<"$diag_stderr"; then
|
|
echo "Expected loud diagnostic naming the unresolved host; got: $diag_stderr" >&2
|
|
exit 1
|
|
fi
|
|
if ! grep -q "Available tea logins:" <<<"$diag_stderr"; then
|
|
echo "Expected diagnostic to list available tea logins; got: $diag_stderr" >&2
|
|
exit 1
|
|
fi
|
|
|
|
# Both-instance host derivation + override-wins, using a mock that DOES define a
|
|
# mosaicstack login. Scoped to this section so the API-fallback assertions above
|
|
# (which rely on mosaicstack having NO tea login) remain valid.
|
|
BIN_DIR2="$WORK_DIR/bin2"
|
|
mkdir -p "$BIN_DIR2"
|
|
cp "$BIN_DIR/curl" "$BIN_DIR2/curl"
|
|
cat > "$BIN_DIR2/tea" <<'SH'
|
|
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
if [[ "$*" == "login list --output json" ]]; then
|
|
cat <<'JSON'
|
|
[
|
|
{"name":"mosaicstack","url":"https://git.mosaicstack.dev","user":"ci-bot"},
|
|
{"name":"usc","url":"https://git.uscllc.com","user":"ci-bot"}
|
|
]
|
|
JSON
|
|
exit 0
|
|
fi
|
|
printf 'tea %s\n' "$*" >> "$MOSAIC_TEST_LOG"
|
|
exit 0
|
|
SH
|
|
chmod +x "$BIN_DIR2/tea"
|
|
|
|
run_in_repo2() {
|
|
(
|
|
cd "$REPO_DIR"
|
|
PATH="$BIN_DIR2:$PATH" \
|
|
MOSAIC_CREDENTIALS_FILE="$CREDENTIALS_FILE" \
|
|
MOSAIC_TEST_LOG="$LOG_FILE" \
|
|
"$@"
|
|
)
|
|
}
|
|
|
|
git -C "$REPO_DIR" remote set-url origin https://git.mosaicstack.dev/mosaicstack/stack.git
|
|
mosaic_login=$(run_in_repo2 bash -c 'source "'"$SCRIPT_DIR"'/detect-platform.sh"; get_gitea_login')
|
|
if [[ "$mosaic_login" != "mosaicstack" ]]; then
|
|
echo "Expected mosaicstack origin to derive login 'mosaicstack'; got '$mosaic_login'" >&2
|
|
exit 1
|
|
fi
|
|
|
|
git -C "$REPO_DIR" remote set-url origin https://git.uscllc.com/USC/uconnect.git
|
|
usc_login_derived=$(run_in_repo2 bash -c 'source "'"$SCRIPT_DIR"'/detect-platform.sh"; get_gitea_login')
|
|
if [[ "$usc_login_derived" != "usc" ]]; then
|
|
echo "Expected usc origin to derive login 'usc'; got '$usc_login_derived'" >&2
|
|
exit 1
|
|
fi
|
|
|
|
# Explicit GITEA_LOGIN override is honored when it matches the host.
|
|
git -C "$REPO_DIR" remote set-url origin https://git.mosaicstack.dev/mosaicstack/stack.git
|
|
override_wins=$(run_in_repo2 bash -c 'export GITEA_LOGIN=mosaicstack; source "'"$SCRIPT_DIR"'/detect-platform.sh"; get_gitea_login')
|
|
if [[ "$override_wins" != "mosaicstack" ]]; then
|
|
echo "Expected valid GITEA_LOGIN override to win on mosaicstack host; got '$override_wins'" >&2
|
|
exit 1
|
|
fi
|
|
git -C "$REPO_DIR" remote set-url origin https://git.uscllc.com/USC/uconnect.git
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# #865 Blocker 1 & 2: get_gitea_token_for_login must resolve the SAME token as
|
|
# PyYAML would (or fail closed identically) even when PyYAML is ABSENT, and must
|
|
# bind the credential to the repo host's scheme + host + EFFECTIVE PORT — not the
|
|
# hostname alone. These fixtures probe the ImportError-dispatched line-parser
|
|
# fallback under FORCED PyYAML absence with adversarial YAML shapes, asserting it
|
|
# NEVER misattributes a token from a nested sub-map or a mis-indented line, strips
|
|
# inline comments like PyYAML, fails closed where PyYAML errors, and rejects a
|
|
# port mismatch while accepting an exact / default-port match. When PyYAML is
|
|
# available the same fixtures also assert the PyYAML path agrees (equivalence).
|
|
# ---------------------------------------------------------------------------
|
|
FIXTURE_XDG="$WORK_DIR/tokenfix"
|
|
NOYAML_DIR="$WORK_DIR/noyaml"
|
|
mkdir -p "$FIXTURE_XDG/tea" "$NOYAML_DIR"
|
|
# A shadow `yaml` module that raises ImportError, forcing the fallback path.
|
|
printf 'raise ImportError("forced-absent for #865 fallback regression")\n' > "$NOYAML_DIR/yaml.py"
|
|
if python3 -c 'import yaml' >/dev/null 2>&1; then HAVE_PYYAML=true; else HAVE_PYYAML=false; fi
|
|
# Confirm the shim really does force ImportError, so the fallback is exercised.
|
|
if python3 -c 'import yaml' >/dev/null 2>&1; then
|
|
if PYTHONPATH="$NOYAML_DIR" python3 -c 'import yaml' >/dev/null 2>&1; then
|
|
echo "FAIL: PyYAML-absence shim did not force ImportError (fallback not exercised)" >&2
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
write_fixture() { printf '%s' "$1" > "$FIXTURE_XDG/tea/config.yml"; }
|
|
|
|
# Resolve a token via the FORCED-fallback path (PyYAML shimmed to ImportError).
|
|
token_fallback() {
|
|
(
|
|
cd "$REPO_DIR"
|
|
XDG_CONFIG_HOME="$FIXTURE_XDG" PYTHONPATH="$NOYAML_DIR" bash -c '
|
|
source "'"$SCRIPT_DIR"'/detect-platform.sh"
|
|
get_gitea_token_for_login "$1" "$2"
|
|
' _ "$1" "$2"
|
|
) 2>/dev/null || true
|
|
}
|
|
|
|
# Resolve a token via the normal path (uses PyYAML when installed).
|
|
token_pyyaml() {
|
|
(
|
|
cd "$REPO_DIR"
|
|
XDG_CONFIG_HOME="$FIXTURE_XDG" bash -c '
|
|
source "'"$SCRIPT_DIR"'/detect-platform.sh"
|
|
get_gitea_token_for_login "$1" "$2"
|
|
' _ "$1" "$2"
|
|
) 2>/dev/null || true
|
|
}
|
|
|
|
assert_token() {
|
|
local desc="$1" expected="$2" login="$3" host="$4" got
|
|
got=$(token_fallback "$login" "$host")
|
|
if [[ "$got" != "$expected" ]]; then
|
|
echo "FAIL fallback [$desc]: expected [$expected] got [$got]" >&2
|
|
exit 1
|
|
fi
|
|
if [[ "$HAVE_PYYAML" == true ]]; then
|
|
got=$(token_pyyaml "$login" "$host")
|
|
if [[ "$got" != "$expected" ]]; then
|
|
echo "FAIL pyyaml [$desc]: expected [$expected] got [$got]" >&2
|
|
exit 1
|
|
fi
|
|
fi
|
|
}
|
|
|
|
# 1. Plain, well-formed entry resolves its token.
|
|
write_fixture 'logins:
|
|
- name: primary
|
|
url: https://git.example
|
|
token: TOK_PLAIN
|
|
'
|
|
assert_token "plain scalar" "TOK_PLAIN" primary git.example
|
|
|
|
# 2. A token nested inside a deeper SUB-MAP must NOT attach to the entry — PyYAML
|
|
# resolves the entry's own token to None here, so the fallback must too.
|
|
write_fixture 'logins:
|
|
- name: primary
|
|
url: https://git.example
|
|
extra:
|
|
token: TOK_NESTED_ATTACKER
|
|
- name: other
|
|
url: https://git.example
|
|
token: TOK_OTHER
|
|
'
|
|
assert_token "nested sub-map token is not attributed" "" primary git.example
|
|
assert_token "sibling entry still resolves its own token" "TOK_OTHER" other git.example
|
|
|
|
# 3. A MIS-INDENTED token line (deeper than the entry's fields) must not attach;
|
|
# PyYAML errors on this shape, so both fail closed.
|
|
write_fixture 'logins:
|
|
- name: primary
|
|
url: https://git.example
|
|
token: TOK_MISINDENT
|
|
'
|
|
assert_token "mis-indented token fails closed" "" primary git.example
|
|
|
|
# 4. A trailing inline comment on a scalar is stripped, exactly as PyYAML does.
|
|
write_fixture 'logins:
|
|
- name: primary
|
|
url: https://git.example
|
|
token: TOK_INLINE # trailing note
|
|
'
|
|
assert_token "inline comment stripped" "TOK_INLINE" primary git.example
|
|
|
|
# 5. A PyYAML-fail-closed case: tab indentation. PyYAML raises a scanner error;
|
|
# the fallback resolves no token. Both fail closed identically.
|
|
write_fixture "$(printf 'logins:\n - name: primary\n url: https://git.example\n\ttoken: TOK_TAB\n')"
|
|
assert_token "tab-indent fails closed like PyYAML" "" primary git.example
|
|
|
|
# 6. Host binding is scheme + host + EFFECTIVE PORT, not hostname alone.
|
|
write_fixture 'logins:
|
|
- name: ported
|
|
url: https://git.example:8443
|
|
token: TOK_PORTED
|
|
'
|
|
assert_token "explicit port exact match accepted" "TOK_PORTED" ported git.example:8443
|
|
assert_token "portless repo host rejects :8443 login" "" ported git.example
|
|
assert_token "wrong explicit port rejected" "" ported git.example:9443
|
|
|
|
# 7. An implicit (portless) login URL equals the scheme's explicit default port.
|
|
write_fixture 'logins:
|
|
- name: defported
|
|
url: https://git.example
|
|
token: TOK_DEFPORT
|
|
'
|
|
assert_token "implicit https vs explicit :443 match" "TOK_DEFPORT" defported git.example:443
|
|
assert_token "implicit https vs :8443 rejected" "" defported git.example:8443
|
|
|
|
echo "Gitea login resolution regression harness passed"
|