mirror of
https://github.com/block/buzz.git
synced 2026-11-09 19:02:00 +00:00
test(auth): bind route controls to exact outcomes and merged routers
Co-authored-by: Sarnow <1894dcbafaa4df1ac607a9bf879ac0b7d77fbccb0e0f4619ecc252c8adbad8a2@seiler-test.communities.public.builderlabstaging.xyz> Signed-off-by: Brad Seiler <seiler@squareup.com>
This commit is contained in:
@@ -348,10 +348,17 @@ def builder_prefixes(builders) -> dict[str, str]:
|
||||
return prefixes
|
||||
|
||||
|
||||
# Service and fallback registrations bypass the per-route method
|
||||
# classification, so each one is a hard error unless this list names its
|
||||
# builder, call, and exact (whitespace-normalized) argument, once.
|
||||
# Service, fallback, and merge registrations bypass per-route classification.
|
||||
# Pin the existing composition seams by builder and exact normalized argument;
|
||||
# reject new or repeated compositions until their routes can be classified.
|
||||
ALLOWED_UNROUTED_REGISTRATIONS = {
|
||||
# These root aliases are constructed in build_router at the root prefix.
|
||||
("router::build_router", "merge", "media_router"),
|
||||
("router::build_router", "merge", "git_router"),
|
||||
("router::build_router", "merge", "git_policy_router"),
|
||||
("router::build_router", "merge", "optional"),
|
||||
# Git settings already carry their complete /git paths; no nest prefix.
|
||||
("api::git::transport::git_router", "merge", "super::settings::router()"),
|
||||
# SPA static bundles; it only serves files, never a community API.
|
||||
("router::build_router", "fallback_service", "spa_fallback"),
|
||||
# Unknown accessory paths answer 404 instead of SPA HTML.
|
||||
@@ -381,6 +388,11 @@ def collect_registered_routes() -> Counter:
|
||||
mask = mask_comments_and_strings(source)
|
||||
test_ranges = test_module_ranges(mask)
|
||||
path_builders = [builder for builder in builders if builder[2] == path]
|
||||
# Root aliases have root paths only when merged outside a nest target.
|
||||
nest_arguments = []
|
||||
for nest in re.finditer(r"\.\s*nest\s*\(", mask):
|
||||
opening = mask.find("(", nest.start(), nest.end())
|
||||
nest_arguments.append((opening, matching_delimiter(mask, opening)))
|
||||
|
||||
def enclosing_builder(position: int) -> str | None:
|
||||
for builder in path_builders:
|
||||
@@ -389,7 +401,7 @@ def collect_registered_routes() -> Counter:
|
||||
return None
|
||||
|
||||
for match in re.finditer(
|
||||
r"\.\s*(route|nest|route_service|nest_service|fallback_service|fallback)\s*\(",
|
||||
r"\.\s*(route|nest|route_service|nest_service|fallback_service|fallback|merge)\s*\(",
|
||||
mask,
|
||||
):
|
||||
if in_ranges(match.start(), test_ranges):
|
||||
@@ -398,13 +410,22 @@ def collect_registered_routes() -> Counter:
|
||||
builder = enclosing_builder(match.start())
|
||||
line = source.count("\n", 0, match.start()) + 1
|
||||
location = f"{path.relative_to(ROOT)}:{line}"
|
||||
if call.endswith("_service") or call == "fallback":
|
||||
if call.endswith("_service") or call in {"fallback", "merge"}:
|
||||
opening = mask.find("(", match.start(), match.end())
|
||||
argument = " ".join(
|
||||
source[opening + 1 : matching_delimiter(mask, opening)].split()
|
||||
)
|
||||
registration = (builder, call, argument)
|
||||
if registration not in ALLOWED_UNROUTED_REGISTRATIONS:
|
||||
if (
|
||||
call == "merge"
|
||||
and builder == "router::build_router"
|
||||
and in_ranges(match.start(), nest_arguments)
|
||||
):
|
||||
errors.append(
|
||||
f"{location}: root .merge registration inside a .nest target "
|
||||
"is not classified"
|
||||
)
|
||||
elif registration not in ALLOWED_UNROUTED_REGISTRATIONS:
|
||||
errors.append(
|
||||
f"{location}: production .{call} registration is not classified; "
|
||||
"use .route with an HTTP method or allow-list it"
|
||||
@@ -551,7 +572,6 @@ def check_route_inventory() -> tuple[int, int, int]:
|
||||
found = any(
|
||||
test_function_exists(path, test_name)
|
||||
for path in RELAY_SRC.rglob("*.rs")
|
||||
if "tests" not in path.parts and not path.name.endswith("_tests.rs")
|
||||
)
|
||||
if not found:
|
||||
raise ValueError(f"{route_id}: missing PostgreSQL regression {test_name!r}")
|
||||
@@ -573,10 +593,8 @@ def check_route_inventory() -> tuple[int, int, int]:
|
||||
details.append("inventory rows without registered routes: " + ", ".join(map(str, stale)))
|
||||
raise ValueError("; ".join(details))
|
||||
|
||||
if set(pending) != {("invite_claim", "pending:BUZZ-268"), ("workflow_webhook", "pending:BUZZ-272")}:
|
||||
raise ValueError(
|
||||
"pending coverage must explicitly track BUZZ-268 invitations and BUZZ-272 webhook owner bans"
|
||||
)
|
||||
if pending:
|
||||
raise ValueError(f"integrated ban coverage cannot retain pending sibling cases: {pending}")
|
||||
claim = next((row for row in routes if row["id"] == "invite_claim"), None)
|
||||
if claim is None or claim["membership"] != "exempt" or claim["restriction"] != "enforce":
|
||||
raise ValueError("invite claim must remain membership-exempt and restriction-enforced")
|
||||
|
||||
@@ -68,6 +68,41 @@ class RouteScannerFixtures(unittest.TestCase):
|
||||
with self.assertRaisesRegex(ValueError, message):
|
||||
self.scan(router, admin)
|
||||
|
||||
def test_nested_builder_merge_is_rejected(self):
|
||||
self.assert_rejected(
|
||||
r"\.merge registration is not classified",
|
||||
build_router(),
|
||||
ADMIN.replace('get(probe))', 'get(probe)).merge(crate::api::profiles::router(state))'),
|
||||
)
|
||||
|
||||
def test_unclassified_root_merge_is_rejected(self):
|
||||
self.assert_rejected(
|
||||
r"\.merge registration is not classified",
|
||||
build_router(".merge(api::admin::router(state.clone()))"),
|
||||
)
|
||||
|
||||
def test_existing_root_merge_alias_is_allowed_once(self):
|
||||
self.scan(build_router(".merge(media_router)"))
|
||||
self.assert_rejected(
|
||||
r"allow-listed \.merge registration appears more than once",
|
||||
build_router(".merge(media_router).merge(media_router)"),
|
||||
)
|
||||
|
||||
def test_root_merge_alias_moved_inside_nest_is_rejected(self):
|
||||
self.assert_rejected(
|
||||
r"root \.merge registration inside a \.nest target is not classified",
|
||||
build_router().replace(
|
||||
'api::admin::router(state.clone()))',
|
||||
'api::admin::router(state.clone()).merge(git_policy_router))',
|
||||
),
|
||||
)
|
||||
|
||||
def test_merge_outside_router_builder_is_rejected(self):
|
||||
self.assert_rejected(
|
||||
r"\.merge registration is not classified",
|
||||
build_router() + "\nfn hidden() { opaque.merge(private_router); }",
|
||||
)
|
||||
|
||||
def test_same_named_constants_resolve_per_module(self):
|
||||
routes = self.scan(build_router())
|
||||
self.assertEqual(
|
||||
|
||||
Reference in New Issue
Block a user