upleb.uk

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

summaryrefslogtreecommitdiff
path: root/src/nostr/policy
diff options
context:
space:
mode:
Diffstat (limited to 'src/nostr/policy')
-rw-r--r--src/nostr/policy/announcement.rs18
-rw-r--r--src/nostr/policy/deletion.rs45
-rw-r--r--src/nostr/policy/pr_event.rs10
-rw-r--r--src/nostr/policy/state.rs6
4 files changed, 50 insertions, 29 deletions
diff --git a/src/nostr/policy/announcement.rs b/src/nostr/policy/announcement.rs
index b366f0b..aba5181 100644
--- a/src/nostr/policy/announcement.rs
+++ b/src/nostr/policy/announcement.rs
@@ -70,7 +70,10 @@ impl AnnouncementPolicy {
70 .is_some_and(|entry| event.created_at > entry.event.created_at); 70 .is_some_and(|entry| event.created_at > entry.event.created_at);
71 71
72 if should_evict { 72 if should_evict {
73 self.remove_purgatory_announcement(&event.pubkey, &announcement.identifier); 73 self.remove_purgatory_announcement(
74 &event.pubkey,
75 &announcement.identifier,
76 );
74 } 77 }
75 78
76 match self 79 match self
@@ -145,10 +148,9 @@ impl AnnouncementPolicy {
145 ); 148 );
146 AnnouncementResult::AcceptPurgatory 149 AnnouncementResult::AcceptPurgatory
147 } 150 }
148 Err(e) => AnnouncementResult::Reject(format!( 151 Err(e) => {
149 "Failed to parse announcement: {}", 152 AnnouncementResult::Reject(format!("Failed to parse announcement: {}", e))
150 e 153 }
151 )),
152 } 154 }
153 } 155 }
154 // AcceptPurgatory shouldn't come from validate_announcement, but handle it 156 // AcceptPurgatory shouldn't come from validate_announcement, but handle it
@@ -161,11 +163,7 @@ impl AnnouncementPolicy {
161 /// Called when a replacement announcement arrives for a (pubkey, identifier) pair 163 /// Called when a replacement announcement arrives for a (pubkey, identifier) pair
162 /// that is currently in purgatory. Updates the purgatory entry and extends the 164 /// that is currently in purgatory. Updates the purgatory entry and extends the
163 /// expiry so the new announcement has a fresh waiting window. 165 /// expiry so the new announcement has a fresh waiting window.
164 fn replace_purgatory_announcement( 166 fn replace_purgatory_announcement(&self, event: &Event, announcement: &RepositoryAnnouncement) {
165 &self,
166 event: &Event,
167 announcement: &RepositoryAnnouncement,
168 ) {
169 let repo_path = self.ctx.git_data_path.join(announcement.repo_path()); 167 let repo_path = self.ctx.git_data_path.join(announcement.repo_path());
170 let relays: HashSet<String> = announcement.relays.iter().cloned().collect(); 168 let relays: HashSet<String> = announcement.relays.iter().cloned().collect();
171 169
diff --git a/src/nostr/policy/deletion.rs b/src/nostr/policy/deletion.rs
index 6457c90..c5a52d4 100644
--- a/src/nostr/policy/deletion.rs
+++ b/src/nostr/policy/deletion.rs
@@ -155,7 +155,9 @@ impl DeletionPolicy {
155 author = %author.to_hex(), 155 author = %author.to_hex(),
156 "Deletion request: removing purgatory state event by event ID" 156 "Deletion request: removing purgatory state event by event ID"
157 ); 157 );
158 self.ctx.purgatory.remove_state_event(&identifier, &entry.event.id); 158 self.ctx
159 .purgatory
160 .remove_state_event(&identifier, &entry.event.id);
159 return; // event IDs are unique 161 return; // event IDs are unique
160 } 162 }
161 } 163 }
@@ -223,7 +225,9 @@ impl DeletionPolicy {
223 if entry.author == *author 225 if entry.author == *author
224 && entry.event.created_at.as_secs() <= deletion_created_at 226 && entry.event.created_at.as_secs() <= deletion_created_at
225 { 227 {
226 self.ctx.purgatory.remove_state_event(identifier, &entry.event.id); 228 self.ctx
229 .purgatory
230 .remove_state_event(identifier, &entry.event.id);
227 removed += 1; 231 removed += 1;
228 } 232 }
229 } 233 }
@@ -306,7 +310,10 @@ mod tests {
306 EventBuilder::new(Kind::GitRepoAnnouncement, "") 310 EventBuilder::new(Kind::GitRepoAnnouncement, "")
307 .tags(vec![ 311 .tags(vec![
308 Tag::identifier(identifier), 312 Tag::identifier(identifier),
309 Tag::custom(TagKind::custom("clone"), vec!["https://example.com/repo.git"]), 313 Tag::custom(
314 TagKind::custom("clone"),
315 vec!["https://example.com/repo.git"],
316 ),
310 ]) 317 ])
311 .sign_with_keys(keys) 318 .sign_with_keys(keys)
312 .unwrap() 319 .unwrap()
@@ -331,7 +338,9 @@ mod tests {
331 let announcement = make_announcement_event(&keys, identifier); 338 let announcement = make_announcement_event(&keys, identifier);
332 add_to_purgatory(&ctx, &announcement, identifier); 339 add_to_purgatory(&ctx, &announcement, identifier);
333 340
334 assert!(ctx.purgatory.has_purgatory_announcement(&keys.public_key(), identifier)); 341 assert!(ctx
342 .purgatory
343 .has_purgatory_announcement(&keys.public_key(), identifier));
335 344
336 // Build kind 5 deletion event referencing the announcement by event ID 345 // Build kind 5 deletion event referencing the announcement by event ID
337 let deletion = EventBuilder::new(Kind::EventDeletion, "") 346 let deletion = EventBuilder::new(Kind::EventDeletion, "")
@@ -347,7 +356,8 @@ mod tests {
347 356
348 assert!(matches!(result, WritePolicyResult::Accept)); 357 assert!(matches!(result, WritePolicyResult::Accept));
349 assert!( 358 assert!(
350 !ctx.purgatory.has_purgatory_announcement(&keys.public_key(), identifier), 359 !ctx.purgatory
360 .has_purgatory_announcement(&keys.public_key(), identifier),
351 "Purgatory entry should have been removed" 361 "Purgatory entry should have been removed"
352 ); 362 );
353 } 363 }
@@ -361,7 +371,9 @@ mod tests {
361 let announcement = make_announcement_event(&keys, identifier); 371 let announcement = make_announcement_event(&keys, identifier);
362 add_to_purgatory(&ctx, &announcement, identifier); 372 add_to_purgatory(&ctx, &announcement, identifier);
363 373
364 assert!(ctx.purgatory.has_purgatory_announcement(&keys.public_key(), identifier)); 374 assert!(ctx
375 .purgatory
376 .has_purgatory_announcement(&keys.public_key(), identifier));
365 377
366 // Build kind 5 deletion event referencing the announcement by coordinate 378 // Build kind 5 deletion event referencing the announcement by coordinate
367 let coord = format!("30617:{}:{}", keys.public_key().to_hex(), identifier); 379 let coord = format!("30617:{}:{}", keys.public_key().to_hex(), identifier);
@@ -378,7 +390,8 @@ mod tests {
378 390
379 assert!(matches!(result, WritePolicyResult::Accept)); 391 assert!(matches!(result, WritePolicyResult::Accept));
380 assert!( 392 assert!(
381 !ctx.purgatory.has_purgatory_announcement(&keys.public_key(), identifier), 393 !ctx.purgatory
394 .has_purgatory_announcement(&keys.public_key(), identifier),
382 "Purgatory entry should have been removed" 395 "Purgatory entry should have been removed"
383 ); 396 );
384 } 397 }
@@ -407,7 +420,8 @@ mod tests {
407 420
408 assert!(matches!(result, WritePolicyResult::Accept)); 421 assert!(matches!(result, WritePolicyResult::Accept));
409 assert!( 422 assert!(
410 ctx.purgatory.has_purgatory_announcement(&owner_keys.public_key(), identifier), 423 ctx.purgatory
424 .has_purgatory_announcement(&owner_keys.public_key(), identifier),
411 "Purgatory entry should NOT have been removed by wrong author" 425 "Purgatory entry should NOT have been removed by wrong author"
412 ); 426 );
413 } 427 }
@@ -438,7 +452,8 @@ mod tests {
438 452
439 assert!(matches!(result, WritePolicyResult::Accept)); 453 assert!(matches!(result, WritePolicyResult::Accept));
440 assert!( 454 assert!(
441 ctx.purgatory.has_purgatory_announcement(&owner_keys.public_key(), identifier), 455 ctx.purgatory
456 .has_purgatory_announcement(&owner_keys.public_key(), identifier),
442 "Purgatory entry should NOT have been removed by wrong author" 457 "Purgatory entry should NOT have been removed by wrong author"
443 ); 458 );
444 } 459 }
@@ -450,11 +465,10 @@ mod tests {
450 465
451 // No purgatory entry exists — deletion should still be accepted 466 // No purgatory entry exists — deletion should still be accepted
452 let deletion = EventBuilder::new(Kind::EventDeletion, "") 467 let deletion = EventBuilder::new(Kind::EventDeletion, "")
453 .tags(vec![ 468 .tags(vec![Tag::custom(
454 Tag::custom(TagKind::custom("a"), vec![ 469 TagKind::custom("a"),
455 format!("30617:{}:nonexistent", keys.public_key().to_hex()) 470 vec![format!("30617:{}:nonexistent", keys.public_key().to_hex())],
456 ]), 471 )])
457 ])
458 .sign_with_keys(&keys) 472 .sign_with_keys(&keys)
459 .unwrap(); 473 .unwrap();
460 474
@@ -491,7 +505,8 @@ mod tests {
491 505
492 assert!(matches!(result, WritePolicyResult::Accept)); 506 assert!(matches!(result, WritePolicyResult::Accept));
493 assert!( 507 assert!(
494 ctx.purgatory.has_purgatory_announcement(&keys.public_key(), identifier), 508 ctx.purgatory
509 .has_purgatory_announcement(&keys.public_key(), identifier),
495 "Purgatory entry should NOT be removed: entry is newer than deletion request" 510 "Purgatory entry should NOT be removed: entry is newer than deletion request"
496 ); 511 );
497 } 512 }
diff --git a/src/nostr/policy/pr_event.rs b/src/nostr/policy/pr_event.rs
index 52747a4..e4a64b8 100644
--- a/src/nostr/policy/pr_event.rs
+++ b/src/nostr/policy/pr_event.rs
@@ -7,7 +7,9 @@ use nostr_relay_builder::prelude::Event;
7 7
8use super::PolicyContext; 8use super::PolicyContext;
9use crate::git; 9use crate::git;
10use crate::git::authorization::{collect_authorized_maintainers, fetch_repository_data_excluding_purgatory}; 10use crate::git::authorization::{
11 collect_authorized_maintainers, fetch_repository_data_excluding_purgatory,
12};
11 13
12/// Policy for validating PR and PR Update events 14/// Policy for validating PR and PR Update events
13#[derive(Clone)] 15#[derive(Clone)]
@@ -131,7 +133,8 @@ impl PrEventPolicy {
131 // only be accepted for announcements that have been promoted (validated). 133 // only be accepted for announcements that have been promoted (validated).
132 // If the announcement is still in purgatory, the PR event should also go 134 // If the announcement is still in purgatory, the PR event should also go
133 // to purgatory and wait for the announcement to be promoted. 135 // to purgatory and wait for the announcement to be promoted.
134 let db_repo_data = fetch_repository_data_excluding_purgatory(&self.ctx.database, &identifier).await?; 136 let db_repo_data =
137 fetch_repository_data_excluding_purgatory(&self.ctx.database, &identifier).await?;
135 138
136 // Extract owner pubkey from source repo path 139 // Extract owner pubkey from source repo path
137 let owner_pubkey = crate::git::sync::extract_owner_from_repo_path( 140 let owner_pubkey = crate::git::sync::extract_owner_from_repo_path(
@@ -211,7 +214,8 @@ impl PrEventPolicy {
211 // only be accepted for announcements that have been promoted (validated). 214 // only be accepted for announcements that have been promoted (validated).
212 // If the announcement is still in purgatory, the PR event should also go 215 // If the announcement is still in purgatory, the PR event should also go
213 // to purgatory and wait for the announcement to be promoted. 216 // to purgatory and wait for the announcement to be promoted.
214 let db_repo_data = fetch_repository_data_excluding_purgatory(&self.ctx.database, identifier).await?; 217 let db_repo_data =
218 fetch_repository_data_excluding_purgatory(&self.ctx.database, identifier).await?;
215 219
216 // 3. Extract list of maintainers from "a 30617:<maintainer>:<identifier>" tags 220 // 3. Extract list of maintainers from "a 30617:<maintainer>:<identifier>" tags
217 let mut maintainer_pubkeys = std::collections::HashSet::new(); 221 let mut maintainer_pubkeys = std::collections::HashSet::new();
diff --git a/src/nostr/policy/state.rs b/src/nostr/policy/state.rs
index df743ae..80fe84c 100644
--- a/src/nostr/policy/state.rs
+++ b/src/nostr/policy/state.rs
@@ -158,7 +158,11 @@ impl StatePolicy {
158 // authorized it. 158 // authorized it.
159 for owner_hex in &authorized_owners { 159 for owner_hex in &authorized_owners {
160 if let Ok(owner_pk) = nostr_sdk::PublicKey::from_hex(owner_hex) { 160 if let Ok(owner_pk) = nostr_sdk::PublicKey::from_hex(owner_hex) {
161 if self.ctx.purgatory.has_purgatory_announcement(&owner_pk, &state.identifier) { 161 if self
162 .ctx
163 .purgatory
164 .has_purgatory_announcement(&owner_pk, &state.identifier)
165 {
162 self.ctx.purgatory.extend_announcement_expiry( 166 self.ctx.purgatory.extend_announcement_expiry(
163 &owner_pk, 167 &owner_pk,
164 &state.identifier, 168 &state.identifier,