60 lines
2.5 KiB
Python
60 lines
2.5 KiB
Python
from __future__ import annotations
|
|
|
|
import io
|
|
from types import SimpleNamespace
|
|
|
|
import pytest
|
|
from test_deploy_broker import BROKER_ROOT, _load_module
|
|
|
|
with pytest.MonkeyPatch.context() as patch:
|
|
patch.syspath_prepend(str(BROKER_ROOT))
|
|
transport = _load_module("registered_transport_test", BROKER_ROOT / "registered_legacy_transport.py")
|
|
REPO = "jens/quiz-monitor"
|
|
PREFIX = "/repos/" + REPO
|
|
|
|
|
|
def payload(path, query=None):
|
|
return {"repository": REPO, "path": PREFIX + path, "query": query or {},
|
|
"headers": {"Accept": "application/json", "Authorization": "token " + "x" * 40,
|
|
"User-Agent": transport.transport.USER_AGENT}}
|
|
|
|
|
|
@pytest.mark.parametrize("path,query", [
|
|
("/branches/main", {}),
|
|
("/actions/runs", {"event": "push", "branch": "main", "head_sha": "a" * 40, "page": "1", "limit": "100"}),
|
|
("/actions/runs/123/jobs", {"page": "10", "limit": "100"}),
|
|
])
|
|
def test_only_exact_main_metadata_is_admitted(path, query):
|
|
assert transport.allowed(REPO, PREFIX + path, query)
|
|
|
|
|
|
@pytest.mark.parametrize("path,query", [
|
|
("/branches/feature", {}), ("/branches/main", {"extra": "1"}),
|
|
("/actions/runs/123/jobs", {"page": "11", "limit": "100"}),
|
|
("/actions/runs", {"event": "pull_request", "branch": "main", "head_sha": "a" * 40, "page": "1", "limit": "100"}),
|
|
("/actions/artifacts/123/zip", {}), ("/branches/main/../../admin", {}),
|
|
])
|
|
def test_other_branches_runs_paths_and_artifacts_are_denied(path, query):
|
|
assert not transport.allowed(REPO, PREFIX + path, query)
|
|
|
|
|
|
def test_repository_and_headers_cannot_escape_read_scope():
|
|
assert not transport.allowed("jens/quiz-monitor/../other", PREFIX + "/branches/main", {})
|
|
assert not transport.allowed(REPO, "/repos/jens/other/branches/main", {})
|
|
request = payload("/branches/main")
|
|
request["headers"]["Authorization"] = "token invalid\nheader"
|
|
with pytest.raises(ValueError, match="headers_invalid"):
|
|
transport.execute(request)
|
|
|
|
|
|
def test_fixed_get_uses_bounded_reader_without_redirects_or_secret_output():
|
|
observed = []
|
|
class Response(io.BytesIO):
|
|
status = 200
|
|
def open_request(request, timeout):
|
|
observed.append((request.full_url, request.get_method(), timeout))
|
|
return Response(b'{"commit":{"id":"abc"}}')
|
|
result = transport.execute(payload("/branches/main"), opener=SimpleNamespace(open=open_request))
|
|
assert result == b'{"commit":{"id":"abc"}}'
|
|
assert observed == [("https://gitea.example.com/api/v1" + PREFIX + "/branches/main", "GET", 10)]
|