mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-10-24 04:39:06 -05:00
fix: send GITHUB_TOKEN from download.sh
download.py authenticated its release lookup and download.sh did not, so past the anonymous quota the shell twin failed with 403. The header goes to api.github.com only and is read from stdin, out of the process list.
This commit is contained in:
1 parent
7a120d7a51
commit
932410e00d
3 files changed
+61
-1
No files matched your search
@@ -66,7 +66,19 @@ normalize() {
|
||||
printf '%s' "$1" | tr '[:upper:]' '[:lower:]' | tr -cd 'a-z0-9'
|
||||
}
|
||||
|
||||
# The anonymous quota is 60 calls an hour per address. The token goes to
|
||||
# GitHub's API only: RETROBIOS_API can name any host. The header is read
|
||||
# from stdin so the token stays out of the process list.
|
||||
fetch_release() {
|
||||
case "$API_BASE" in
|
||||
https://api.github.com|https://api.github.com/)
|
||||
if [ -n "${GITHUB_TOKEN:-}" ]; then
|
||||
printf 'Authorization: Bearer %s\n' "$GITHUB_TOKEN" |
|
||||
curl -fsSL -H @- "$API"
|
||||
return
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
curl -fsSL "$API"
|
||||
}
|
||||
|
||||
|
||||
@@ -632,5 +632,52 @@ class AProgressBarOnlyOnATerminal(unittest.TestCase):
|
||||
self.assertEqual(out.getvalue().count("\n"), 1)
|
||||
|
||||
|
||||
class TheShellDownloaderSendsTheToken(unittest.TestCase):
|
||||
"""download.py sent GITHUB_TOKEN to the API and download.sh did not, so
|
||||
past the anonymous quota the shell twin failed with 403 where the Python
|
||||
one succeeded. A curl stand-in records what each call carries."""
|
||||
|
||||
def _calls(self, **env: str) -> str:
|
||||
scratch = Path(_tempdir(self))
|
||||
log = scratch / "calls.log"
|
||||
fake = scratch / "curl"
|
||||
fake.write_text(
|
||||
"#!/bin/sh\n"
|
||||
f'printf "%s\\n" "$*" >> "{log}"\n'
|
||||
'case "$*" in *"-H @-"*) cat >> "' + str(log) + '" ;; esac\n'
|
||||
"printf '{}'\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
fake.chmod(0o755)
|
||||
base = {k: v for k, v in os.environ.items()
|
||||
if k not in ("GITHUB_TOKEN", "RETROBIOS_API")}
|
||||
proc = subprocess.run(
|
||||
["bash", str(SHELL), "--list"],
|
||||
env={**base, "PATH": f"{scratch}{os.pathsep}{os.environ['PATH']}", **env},
|
||||
capture_output=True, text=True, timeout=60, check=False,
|
||||
)
|
||||
self.assertEqual(proc.returncode, 0, proc.stderr)
|
||||
return log.read_text(encoding="utf-8")
|
||||
|
||||
def test_the_api_call_carries_the_token(self):
|
||||
calls = self._calls(GITHUB_TOKEN="sekrit")
|
||||
self.assertIn("Authorization: Bearer sekrit", calls)
|
||||
self.assertIn("api.github.com/repos/", calls)
|
||||
|
||||
def test_the_token_stays_out_of_the_command_line(self):
|
||||
calls = self._calls(GITHUB_TOKEN="sekrit")
|
||||
command = calls.splitlines()[0]
|
||||
self.assertNotIn("sekrit", command)
|
||||
|
||||
def test_another_host_never_receives_it(self):
|
||||
calls = self._calls(
|
||||
GITHUB_TOKEN="sekrit", RETROBIOS_API="https://mirror.example"
|
||||
)
|
||||
self.assertNotIn("sekrit", calls)
|
||||
|
||||
def test_no_token_sends_no_header(self):
|
||||
self.assertNotIn("Authorization", self._calls())
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@@ -657,10 +657,11 @@ class EveryGitHubApiCallerSendsTheToken(unittest.TestCase):
|
||||
refresh_stale had put a token in their environment."""
|
||||
|
||||
def test_each_module_naming_the_api_reads_the_token(self):
|
||||
# download.sh is download.py's twin and called the API bare.
|
||||
scripts = Path(__file__).resolve().parent.parent / "scripts"
|
||||
silent = sorted(
|
||||
str(path.relative_to(scripts))
|
||||
for path in scripts.rglob("*.py")
|
||||
for path in [*scripts.rglob("*.py"), *scripts.rglob("*.sh")]
|
||||
if "api.github.com" in (source := path.read_text(encoding="utf-8"))
|
||||
and "GITHUB_TOKEN" not in source
|
||||
and "github_headers(" not in source
|
||||
|
||||
Reference in new issue
Block a user