diff --git a/crates/buzz-test-client/tests/community_ban_routes.rs b/crates/buzz-test-client/tests/community_ban_routes.rs index 3708261a79..de9b3d3eea 100644 --- a/crates/buzz-test-client/tests/community_ban_routes.rs +++ b/crates/buzz-test-client/tests/community_ban_routes.rs @@ -28,6 +28,8 @@ const BANNED_MESSAGE: &str = "blocked: you are banned from this community"; const COMMUNITY_BAN_MATRIX_CASES: &[&str] = &[ "events", + "buzz_sidebar", + "buzz_read_state", "moderation_command", "query", "count", @@ -268,7 +270,7 @@ fn request_body(case: &str, actor: &Principal) -> Vec { "limit": 1 }])) .expect("serialize Nostr filter"), - "gif_search" | "gif_share" | "invite_mint" => b"{".to_vec(), + "gif_search" | "gif_share" | "invite_mint" | "buzz_read_state" => b"{".to_vec(), "media_upload" => b"not an image file".to_vec(), "git_upload_pack" | "git_receive_pack" => Vec::new(), "git_default_post" => serde_json::to_vec(&serde_json::json!({ @@ -406,6 +408,12 @@ fn assert_ban_denial( route.method, route.path ); + } else if route.id.starts_with("buzz_") { + assert_eq!( + serde_json::from_str::(body).expect("accessory denial JSON") + ["error"]["code"], + "forbidden" + ); } else if route.method == "HEAD" { assert!( body.is_empty(), diff --git a/crates/buzz-test-client/tests/fixtures/community-ban-route-inventory.tsv b/crates/buzz-test-client/tests/fixtures/community-ban-route-inventory.tsv index 0738a94296..b1431793fc 100644 --- a/crates/buzz-test-client/tests/fixtures/community-ban-route-inventory.tsv +++ b/crates/buzz-test-client/tests/fixtures/community-ban-route-inventory.tsv @@ -31,7 +31,7 @@ nip_fi_disconnect relay POST /api/nip-fi/disconnect internal_nip_fi not_applicab moderation_reports relay GET /moderation/reports community_nip98 community enforce matrix:moderation_reports+moderation_owner_ban admin moderation_audit relay GET /moderation/audit community_nip98 community enforce matrix:moderation_audit+moderation_owner_ban admin moderation_restricted relay GET /moderation/restricted community_nip98 community enforce matrix:moderation_restricted+moderation_owner_ban admin -workflow_webhook relay POST /hooks/{id} workflow_webhook_secret not_applicable not_applicable:webhook_secret_auth classified - +workflow_webhook relay POST /hooks/{id} workflow_webhook_secret not_applicable enforce pending:BUZZ-272 BUZZ-272 mesh_demo_echo relay POST /_mesh/demo/echo testbed_internal not_applicable not_applicable:testbed_only classified - huddle_audio relay GET /huddle/{channel_id}/audio community_nip42 community enforce pg:audio_join_rejects_community_banned_member+audio_join_rejects_banned_admin+audio_join_rejects_banned_owner_agent - media_upload relay PUT /upload community_blossom community enforce matrix:media_upload member @@ -67,3 +67,9 @@ health_liveness health GET /_liveness health_probe not_applicable not_applicable health_readiness health GET /_readiness health_probe not_applicable not_applicable:health_probe classified - health_status health GET /_status health_probe not_applicable not_applicable:health_probe classified - health_mesh health GET /_mesh health_probe not_applicable not_applicable:health_probe classified - +admin_communities relay GET /api/admin/v1/communities operator_control not_applicable not_applicable:relay_admin_control classified - +admin_event relay GET /api/admin/v1/events/{id} operator_control not_applicable not_applicable:relay_admin_control classified - +admin_member_search relay GET /api/admin/v1/members/search operator_control not_applicable not_applicable:relay_admin_control classified - +admin_member relay GET /api/admin/v1/members/{pubkey} operator_control not_applicable not_applicable:relay_admin_control classified - +buzz_sidebar relay GET /buzz/v1/me/sidebar community_nip98 community enforce matrix:buzz_sidebar member +buzz_read_state relay POST /buzz/v1/me/read-state community_nip98 community enforce matrix:buzz_read_state member diff --git a/scripts/check-community-ban-route-inventory.py b/scripts/check-community-ban-route-inventory.py index 7345e8117d..6fbc511f1f 100644 --- a/scripts/check-community-ban-route-inventory.py +++ b/scripts/check-community-ban-route-inventory.py @@ -293,7 +293,7 @@ def builder_prefixes(builders) -> dict[str, str]: _, _, path, source, mask, start, _, end = main prefixes = {} for first, second_mask, second_source in registered_calls(mask, source, start, end, "nest"): - prefix = string_value(first) + prefix = route_path(first, route_constants()) target_match = re.search(r"((?:[A-Za-z_]\w*::)*[A-Za-z_]\w*)\s*\(", second_mask) if prefix is None or target_match is None: continue @@ -485,9 +485,9 @@ def check_route_inventory() -> tuple[int, int, int]: details.append("inventory rows without registered routes: " + ", ".join(map(str, stale))) raise ValueError("; ".join(details)) - if len(pending) != 1 or pending[0] != ("invite_claim", "pending:BUZZ-268"): + if set(pending) != {("invite_claim", "pending:BUZZ-268"), ("workflow_webhook", "pending:BUZZ-272")}: raise ValueError( - "the only pending route coverage must be invite_claim pending:BUZZ-268" + "pending coverage must explicitly track BUZZ-268 invitations and BUZZ-272 webhook owner bans" ) 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": @@ -547,7 +547,7 @@ def main() -> int: print( "community-ban route inventory passed: " f"{route_count} registered routes classified, {case_count} HTTP behavior cases, " - f"{regression_count} supporting regressions indexed, {pending_count} BUZZ-268 invite case pending" + f"{regression_count} supporting regressions indexed, {pending_count} sibling implementation cases pending" ) return 0