upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
path: root/grasp-audit/src
diff options
context:
space:
mode:
authorDanConwayDev <DanConwayDev@protonmail.com>2025-12-11 16:53:03 +0000
committerDanConwayDev <DanConwayDev@protonmail.com>2025-12-11 16:53:03 +0000
commit2a9160836bb87fdea3ae891563b0169c68d1c2ab (patch)
tree583c890687beaf7f380fc0be131bdf17485f06fa /grasp-audit/src
parent52489d3b1a7d79e164b4cc901b53fd06c05ce1b1 (diff)
fix: resolve all fmt and clippy warnings
Main lib (src/): - Add #[allow(dead_code)] for build_info field (stored to prevent Prometheus unregistration) - Add #[allow(dead_code)] for first_seen field (reserved for future rate limiting) - Replace .or_insert_with(RelaySyncNeeds::default) with .or_default() - Replace manual div_ceil implementations with .div_ceil(100) Test code (tests/): - Replace .expect(&format!(...)) with .unwrap_or_else(|_| panic!(...)) - Remove needless borrows in fetch_metrics() calls - Add #[allow(dead_code)] and #[allow(unused_imports)] to test helpers module grasp-audit: - Apply cargo fmt to fix formatting
Diffstat (limited to 'grasp-audit/src')
-rw-r--r--grasp-audit/src/client.rs4
-rw-r--r--grasp-audit/src/fixtures.rs6
-rw-r--r--grasp-audit/src/result.rs41
-rw-r--r--grasp-audit/src/specs/grasp01/mod.rs4
-rw-r--r--grasp-audit/src/specs/grasp01/nip01_smoke.rs32
-rw-r--r--grasp-audit/src/specs/grasp01/push_authorization.rs97
6 files changed, 127 insertions, 57 deletions
diff --git a/grasp-audit/src/client.rs b/grasp-audit/src/client.rs
index 21c70be..259a317 100644
--- a/grasp-audit/src/client.rs
+++ b/grasp-audit/src/client.rs
@@ -585,7 +585,9 @@ mod tests {
585 "Missing 'grasp-audit-test-event' tag" 585 "Missing 'grasp-audit-test-event' tag"
586 ); 586 );
587 assert!( 587 assert!(
588 tag_contents.iter().any(|t| t.starts_with("audit-isolated-")), 588 tag_contents
589 .iter()
590 .any(|t| t.starts_with("audit-isolated-")),
589 "Missing 'audit-isolated-*' tag" 591 "Missing 'audit-isolated-*' tag"
590 ); 592 );
591 assert!( 593 assert!(
diff --git a/grasp-audit/src/fixtures.rs b/grasp-audit/src/fixtures.rs
index 174f83d..a15bd79 100644
--- a/grasp-audit/src/fixtures.rs
+++ b/grasp-audit/src/fixtures.rs
@@ -1973,11 +1973,11 @@ mod tests {
1973 1973
1974 #[test] 1974 #[test]
1975 fn test_context_mode_from_audit_mode() { 1975 fn test_context_mode_from_audit_mode() {
1976 assert_eq!(ContextMode::from(AuditMode::Isolated), ContextMode::Isolated);
1977 assert_eq!( 1976 assert_eq!(
1978 ContextMode::from(AuditMode::Shared), 1977 ContextMode::from(AuditMode::Isolated),
1979 ContextMode::Shared 1978 ContextMode::Isolated
1980 ); 1979 );
1980 assert_eq!(ContextMode::from(AuditMode::Shared), ContextMode::Shared);
1981 } 1981 }
1982 1982
1983 #[test] 1983 #[test]
diff --git a/grasp-audit/src/result.rs b/grasp-audit/src/result.rs
index 0de16ae..f296633 100644
--- a/grasp-audit/src/result.rs
+++ b/grasp-audit/src/result.rs
@@ -38,7 +38,9 @@ fn parse_spec_lines(spec_ref: &str) -> Vec<u32> {
38 if line_part.contains('-') { 38 if line_part.contains('-') {
39 let range_parts: Vec<&str> = line_part.split('-').collect(); 39 let range_parts: Vec<&str> = line_part.split('-').collect();
40 if range_parts.len() == 2 { 40 if range_parts.len() == 2 {
41 if let (Ok(start), Ok(end)) = (range_parts[0].parse::<u32>(), range_parts[1].parse::<u32>()) { 41 if let (Ok(start), Ok(end)) =
42 (range_parts[0].parse::<u32>(), range_parts[1].parse::<u32>())
43 {
42 return (start..=end).collect(); 44 return (start..=end).collect();
43 } 45 }
44 } 46 }
@@ -162,10 +164,19 @@ impl AuditResult {
162 /// Print a detailed report aligned to GRASP-01 specification 164 /// Print a detailed report aligned to GRASP-01 specification
163 pub fn print_report(&self) { 165 pub fn print_report(&self) {
164 println!(); 166 println!();
165 println!("{}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━{}", BOLD, RESET); 167 println!(
168 "{}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━{}",
169 BOLD, RESET
170 );
166 println!("{}GRASP-01 Compliance Report{}", BOLD, RESET); 171 println!("{}GRASP-01 Compliance Report{}", BOLD, RESET);
167 println!("Source: github.com/nostr-protocol/grasp (commit: {})", GRASP_COMMIT_ID); 172 println!(
168 println!("{}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━{}", BOLD, RESET); 173 "Source: github.com/nostr-protocol/grasp (commit: {})",
174 GRASP_COMMIT_ID
175 );
176 println!(
177 "{}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━{}",
178 BOLD, RESET
179 );
169 180
170 // Build a map of spec line -> tests that cover it 181 // Build a map of spec line -> tests that cover it
171 let mut tests_by_line: BTreeMap<u32, Vec<&TestResult>> = BTreeMap::new(); 182 let mut tests_by_line: BTreeMap<u32, Vec<&TestResult>> = BTreeMap::new();
@@ -185,7 +196,10 @@ impl AuditResult {
185 println!(); 196 println!();
186 println!("{}{}## {}{}", CYAN, BOLD, section, RESET); 197 println!("{}{}## {}{}", CYAN, BOLD, section, RESET);
187 198
188 for req in GRASP_01_REQUIREMENTS.iter().filter(|r| r.section == section) { 199 for req in GRASP_01_REQUIREMENTS
200 .iter()
201 .filter(|r| r.section == section)
202 {
189 println!(); 203 println!();
190 // Print spec requirement in blue 204 // Print spec requirement in blue
191 println!("{}📘 Line {}: {}{}", BLUE, req.line, req.text, RESET); 205 println!("{}📘 Line {}: {}{}", BLUE, req.line, req.text, RESET);
@@ -218,7 +232,10 @@ impl AuditResult {
218 } 232 }
219 233
220 println!(); 234 println!();
221 println!("{}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━{}", BOLD, RESET); 235 println!(
236 "{}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━{}",
237 BOLD, RESET
238 );
222 239
223 // Summary statistics 240 // Summary statistics
224 let passed = self.passed_count(); 241 let passed = self.passed_count();
@@ -252,7 +269,10 @@ impl AuditResult {
252 "{}Test results: {}/{} tests passed ({:.1}%){}", 269 "{}Test results: {}/{} tests passed ({:.1}%){}",
253 summary_color, passed, total_tests, pass_rate, RESET 270 summary_color, passed, total_tests, pass_rate, RESET
254 ); 271 );
255 println!("{}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━{}", BOLD, RESET); 272 println!(
273 "{}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━{}",
274 BOLD, RESET
275 );
256 println!(); 276 println!();
257 } 277 }
258 278
@@ -313,7 +333,10 @@ mod tests {
313 #[test] 333 #[test]
314 fn test_parse_spec_lines_range() { 334 fn test_parse_spec_lines_range() {
315 assert_eq!(parse_spec_lines("GRASP-01:nostr-relay:7-9"), vec![7, 8, 9]); 335 assert_eq!(parse_spec_lines("GRASP-01:nostr-relay:7-9"), vec![7, 8, 9]);
316 assert_eq!(parse_spec_lines("GRASP-01:cors:44-47"), vec![44, 45, 46, 47]); 336 assert_eq!(
337 parse_spec_lines("GRASP-01:cors:44-47"),
338 vec![44, 45, 46, 47]
339 );
317 } 340 }
318 341
319 #[test] 342 #[test]
@@ -327,4 +350,4 @@ mod tests {
327 assert_eq!(parse_spec_lines("GRASP-01:invalid"), Vec::<u32>::new()); 350 assert_eq!(parse_spec_lines("GRASP-01:invalid"), Vec::<u32>::new());
328 assert_eq!(parse_spec_lines("GRASP-01:test:abc"), Vec::<u32>::new()); 351 assert_eq!(parse_spec_lines("GRASP-01:test:abc"), Vec::<u32>::new());
329 } 352 }
330} \ No newline at end of file 353}
diff --git a/grasp-audit/src/specs/grasp01/mod.rs b/grasp-audit/src/specs/grasp01/mod.rs
index ba27fef..fa05f35 100644
--- a/grasp-audit/src/specs/grasp01/mod.rs
+++ b/grasp-audit/src/specs/grasp01/mod.rs
@@ -29,6 +29,6 @@ pub use nip11_document::Nip11DocumentTests;
29pub use push_authorization::PushAuthorizationTests; 29pub use push_authorization::PushAuthorizationTests;
30pub use repository_creation::RepositoryCreationTests; 30pub use repository_creation::RepositoryCreationTests;
31pub use spec_requirements::{ 31pub use spec_requirements::{
32 get_requirement, get_requirements_for_section, get_sections, RequirementLevel, 32 get_requirement, get_requirements_for_section, get_sections, RequirementLevel, SpecRequirement,
33 SpecRequirement, GRASP_01_REQUIREMENTS, GRASP_COMMIT_ID, 33 GRASP_01_REQUIREMENTS, GRASP_COMMIT_ID,
34}; 34};
diff --git a/grasp-audit/src/specs/grasp01/nip01_smoke.rs b/grasp-audit/src/specs/grasp01/nip01_smoke.rs
index 8a0a4d1..4dbcd3d 100644
--- a/grasp-audit/src/specs/grasp01/nip01_smoke.rs
+++ b/grasp-audit/src/specs/grasp01/nip01_smoke.rs
@@ -163,23 +163,27 @@ impl Nip01SmokeTests {
163 /// Spec: NIP-01 CLOSE message 163 /// Spec: NIP-01 CLOSE message
164 /// Requirement: Relay MUST support CLOSE to end subscriptions 164 /// Requirement: Relay MUST support CLOSE to end subscriptions
165 pub async fn test_close_subscription(client: &AuditClient) -> TestResult { 165 pub async fn test_close_subscription(client: &AuditClient) -> TestResult {
166 TestResult::new("close_subscription", "GRASP-01:nostr-relay:7", "Can close subscriptions") 166 TestResult::new(
167 .run(|| async { 167 "close_subscription",
168 // For now, we just verify we can query events 168 "GRASP-01:nostr-relay:7",
169 // Full subscription management with CLOSE would require 169 "Can close subscriptions",
170 // lower-level WebSocket access 170 )
171 .run(|| async {
172 // For now, we just verify we can query events
173 // Full subscription management with CLOSE would require
174 // lower-level WebSocket access
171 175
172 let filter = Filter::new().kind(Kind::TextNote).limit(1); 176 let filter = Filter::new().kind(Kind::TextNote).limit(1);
173 177
174 let _events = client 178 let _events = client
175 .subscribe(vec![filter], Some(std::time::Duration::from_secs(2))) 179 .subscribe(vec![filter], Some(std::time::Duration::from_secs(2)))
176 .await 180 .await
177 .map_err(|e| format!("Failed to subscribe: {}", e))?; 181 .map_err(|e| format!("Failed to subscribe: {}", e))?;
178 182
179 // If we got here, subscription worked 183 // If we got here, subscription worked
180 Ok(()) 184 Ok(())
181 }) 185 })
182 .await 186 .await
183 } 187 }
184 188
185 /// Test 5: Rejects events with invalid signatures 189 /// Test 5: Rejects events with invalid signatures
diff --git a/grasp-audit/src/specs/grasp01/push_authorization.rs b/grasp-audit/src/specs/grasp01/push_authorization.rs
index c06da0d..ec08032 100644
--- a/grasp-audit/src/specs/grasp01/push_authorization.rs
+++ b/grasp-audit/src/specs/grasp01/push_authorization.rs
@@ -407,8 +407,12 @@ impl PushAuthorizationTests {
407 let repo = match ctx.get_fixture(FixtureKind::ValidRepo).await { 407 let repo = match ctx.get_fixture(FixtureKind::ValidRepo).await {
408 Ok(r) => r, 408 Ok(r) => r,
409 Err(e) => { 409 Err(e) => {
410 return TestResult::new(test_name, "GRASP-01:git-http:30", "Push rejected without state event") 410 return TestResult::new(
411 .fail(format!("Failed to create repo: {}", e)) 411 test_name,
412 "GRASP-01:git-http:30",
413 "Push rejected without state event",
414 )
415 .fail(format!("Failed to create repo: {}", e))
412 } 416 }
413 }; 417 };
414 418
@@ -427,8 +431,12 @@ impl PushAuthorizationTests {
427 let clone_path = match clone_repo(relay_domain, &npub, &repo_id) { 431 let clone_path = match clone_repo(relay_domain, &npub, &repo_id) {
428 Ok(p) => p, 432 Ok(p) => p,
429 Err(e) => { 433 Err(e) => {
430 return TestResult::new(test_name, "GRASP-01:git-http:30", "Push rejected without state event") 434 return TestResult::new(
431 .fail(&e) 435 test_name,
436 "GRASP-01:git-http:30",
437 "Push rejected without state event",
438 )
439 .fail(&e)
432 } 440 }
433 }; 441 };
434 let cleanup = || { 442 let cleanup = || {
@@ -437,8 +445,12 @@ impl PushAuthorizationTests {
437 445
438 if let Err(e) = create_commit(&clone_path, "Unauthorized commit") { 446 if let Err(e) = create_commit(&clone_path, "Unauthorized commit") {
439 cleanup(); 447 cleanup();
440 return TestResult::new(test_name, "GRASP-01:git-http:30", "Push rejected without state event") 448 return TestResult::new(
441 .fail(&e); 449 test_name,
450 "GRASP-01:git-http:30",
451 "Push rejected without state event",
452 )
453 .fail(&e);
442 } 454 }
443 455
444 // Do NOT publish state event - push should be rejected 456 // Do NOT publish state event - push should be rejected
@@ -446,14 +458,24 @@ impl PushAuthorizationTests {
446 cleanup(); 458 cleanup();
447 459
448 match push_result { 460 match push_result {
449 Ok(false) => { 461 Ok(false) => TestResult::new(
450 TestResult::new(test_name, "GRASP-01:git-http:30", "Push rejected without state event").pass() 462 test_name,
451 } 463 "GRASP-01:git-http:30",
452 Ok(true) => TestResult::new(test_name, "GRASP-01:git-http:30", "Push rejected without state event") 464 "Push rejected without state event",
453 .fail("Push accepted but should be rejected"), 465 )
454 Err(e) => { 466 .pass(),
455 TestResult::new(test_name, "GRASP-01:git-http:30", "Push rejected without state event").fail(&e) 467 Ok(true) => TestResult::new(
456 } 468 test_name,
469 "GRASP-01:git-http:30",
470 "Push rejected without state event",
471 )
472 .fail("Push accepted but should be rejected"),
473 Err(e) => TestResult::new(
474 test_name,
475 "GRASP-01:git-http:30",
476 "Push rejected without state event",
477 )
478 .fail(&e),
457 } 479 }
458 } 480 }
459 481
@@ -480,11 +502,18 @@ impl PushAuthorizationTests {
480 // The OwnerStateDataPushed fixture handles all stages: 502 // The OwnerStateDataPushed fixture handles all stages:
481 // Generate → Send → Verify → DataPush 503 // Generate → Send → Verify → DataPush
482 match ctx.get_fixture(FixtureKind::OwnerStateDataPushed).await { 504 match ctx.get_fixture(FixtureKind::OwnerStateDataPushed).await {
483 Ok(_state_event) => { 505 Ok(_state_event) => TestResult::new(
484 TestResult::new(test_name, "GRASP-01:git-http:30", "Push authorized with matching state").pass() 506 test_name,
485 } 507 "GRASP-01:git-http:30",
486 Err(e) => TestResult::new(test_name, "GRASP-01:git-http:30", "Push authorized with matching state") 508 "Push authorized with matching state",
487 .fail(format!("{}", e)), 509 )
510 .pass(),
511 Err(e) => TestResult::new(
512 test_name,
513 "GRASP-01:git-http:30",
514 "Push authorized with matching state",
515 )
516 .fail(format!("{}", e)),
488 } 517 }
489 } 518 }
490 519
@@ -868,8 +897,12 @@ impl PushAuthorizationTests {
868 // Send the rogue state event using the raw client to bypass AuditClient's key check 897 // Send the rogue state event using the raw client to bypass AuditClient's key check
869 if let Err(e) = client.client().send_event(&rogue_state).await { 898 if let Err(e) = client.client().send_event(&rogue_state).await {
870 cleanup(); 899 cleanup();
871 return TestResult::new(test_name, "GRASP-01:git-http:30", "Non-maintainer state events ignored") 900 return TestResult::new(
872 .fail(format!("Failed to send rogue state event: {}", e)); 901 test_name,
902 "GRASP-01:git-http:30",
903 "Non-maintainer state events ignored",
904 )
905 .fail(format!("Failed to send rogue state event: {}", e));
873 } 906 }
874 907
875 // Wait for event to propagate 908 // Wait for event to propagate
@@ -1036,7 +1069,9 @@ impl PushAuthorizationTests {
1036 .await 1069 .await
1037 { 1070 {
1038 Ok(_pr_event) => TestResult::new(test_name, "GRASP-01:git-http:34", desc).pass(), 1071 Ok(_pr_event) => TestResult::new(test_name, "GRASP-01:git-http:34", desc).pass(),
1039 Err(e) => TestResult::new(test_name, "GRASP-01:git-http:34", desc).fail(format!("{}", e)), 1072 Err(e) => {
1073 TestResult::new(test_name, "GRASP-01:git-http:34", desc).fail(format!("{}", e))
1074 }
1040 } 1075 }
1041 } 1076 }
1042 1077
@@ -1062,7 +1097,8 @@ impl PushAuthorizationTests {
1062 { 1097 {
1063 Ok(e) => e, 1098 Ok(e) => e,
1064 Err(e) => { 1099 Err(e) => {
1065 return TestResult::new(test_name, "GRASP-01:git-http:34", desc).fail(format!("{}", e)); 1100 return TestResult::new(test_name, "GRASP-01:git-http:34", desc)
1101 .fail(format!("{}", e));
1066 } 1102 }
1067 }; 1103 };
1068 1104
@@ -1072,7 +1108,8 @@ impl PushAuthorizationTests {
1072 let repo = match ctx.get_fixture(FixtureKind::ValidRepo).await { 1108 let repo = match ctx.get_fixture(FixtureKind::ValidRepo).await {
1073 Ok(r) => r, 1109 Ok(r) => r,
1074 Err(e) => { 1110 Err(e) => {
1075 return TestResult::new(test_name, "GRASP-01:git-http:34", desc).fail(format!("{}", e)); 1111 return TestResult::new(test_name, "GRASP-01:git-http:34", desc)
1112 .fail(format!("{}", e));
1076 } 1113 }
1077 }; 1114 };
1078 1115
@@ -1146,7 +1183,8 @@ impl PushAuthorizationTests {
1146 { 1183 {
1147 Ok(e) => e, 1184 Ok(e) => e,
1148 Err(e) => { 1185 Err(e) => {
1149 return TestResult::new(test_name, "GRASP-01:git-http:34", desc).fail(format!("{}", e)); 1186 return TestResult::new(test_name, "GRASP-01:git-http:34", desc)
1187 .fail(format!("{}", e));
1150 } 1188 }
1151 }; 1189 };
1152 1190
@@ -1156,7 +1194,8 @@ impl PushAuthorizationTests {
1156 let repo = match ctx.get_fixture(FixtureKind::ValidRepo).await { 1194 let repo = match ctx.get_fixture(FixtureKind::ValidRepo).await {
1157 Ok(r) => r, 1195 Ok(r) => r,
1158 Err(e) => { 1196 Err(e) => {
1159 return TestResult::new(test_name, "GRASP-01:git-http:34", desc).fail(format!("{}", e)); 1197 return TestResult::new(test_name, "GRASP-01:git-http:34", desc)
1198 .fail(format!("{}", e));
1160 } 1199 }
1161 }; 1200 };
1162 1201
@@ -1233,7 +1272,8 @@ impl PushAuthorizationTests {
1233 { 1272 {
1234 Ok(e) => e, 1273 Ok(e) => e,
1235 Err(e) => { 1274 Err(e) => {
1236 return TestResult::new(test_name, "GRASP-01:git-http:34", desc).fail(format!("{}", e)); 1275 return TestResult::new(test_name, "GRASP-01:git-http:34", desc)
1276 .fail(format!("{}", e));
1237 } 1277 }
1238 }; 1278 };
1239 1279
@@ -1243,7 +1283,8 @@ impl PushAuthorizationTests {
1243 let repo = match ctx.get_fixture(FixtureKind::ValidRepo).await { 1283 let repo = match ctx.get_fixture(FixtureKind::ValidRepo).await {
1244 Ok(r) => r, 1284 Ok(r) => r,
1245 Err(e) => { 1285 Err(e) => {
1246 return TestResult::new(test_name, "GRASP-01:git-http:34", desc).fail(format!("{}", e)); 1286 return TestResult::new(test_name, "GRASP-01:git-http:34", desc)
1287 .fail(format!("{}", e));
1247 } 1288 }
1248 }; 1289 };
1249 1290