mirror of
https://github.com/block/buzz.git
synced 2026-10-27 20:41:57 +00:00
fix(relay): confirm a stored create's resend before its members' policies
An exact resend of a kind:9007 writes nothing, so a member that closed its channel adds after the create no longer refuses it. Co-authored-by: claude00 <fb8b76a01257932b8ca35060862c29bd09b2137638573731c2d5074fc02c5385@buzz.block.builderlab.xyz> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Bradley Axen <baxen@squareup.com>
This commit is contained in:
@@ -170,7 +170,8 @@ async fn create_respects_the_members_add_policy() {
|
||||
/// Resending a create whose OK was lost is accepted; a different create for
|
||||
/// the same UUID, even from its creator, is refused before its side effects,
|
||||
/// so it can neither add nor announce anyone.
|
||||
/// Mutations: refuse every existing UUID → resend not accepted → RED; let the
|
||||
/// Mutations: refuse every existing UUID → resend not accepted → RED; check the
|
||||
/// members' policies before recognizing a stored resend → RED; let the
|
||||
/// creator's changed create through → stranger announced → RED.
|
||||
#[tokio::test]
|
||||
#[ignore = "requires Postgres"]
|
||||
@@ -191,7 +192,7 @@ async fn resending_a_create_confirms_it() {
|
||||
.expect("create");
|
||||
assert!(first.accepted, "{}", first.message);
|
||||
let before = roles(&state, &tenant, channel_id).await;
|
||||
let resent = ingest(&state, &tenant, create, &creator)
|
||||
let resent = ingest(&state, &tenant, create.clone(), &creator)
|
||||
.await
|
||||
.expect("resend");
|
||||
assert!(resent.accepted, "{}", resent.message);
|
||||
@@ -209,6 +210,27 @@ async fn resending_a_create_confirms_it() {
|
||||
assert_eq!(changed.message, "duplicate: channel already exists");
|
||||
}
|
||||
|
||||
// The agent closing its adds after the create doesn't refuse the resend.
|
||||
let agent_bytes = agent.public_key().to_bytes().to_vec();
|
||||
state
|
||||
.db
|
||||
.ensure_user(tenant.community(), &agent_bytes)
|
||||
.await
|
||||
.expect("agent user");
|
||||
state
|
||||
.db
|
||||
.set_channel_add_policy(tenant.community(), &agent_bytes, "nobody")
|
||||
.await
|
||||
.expect("policy");
|
||||
let resent_after_policy = ingest(&state, &tenant, create, &creator)
|
||||
.await
|
||||
.expect("resend after policy change");
|
||||
assert!(
|
||||
resent_after_policy.accepted,
|
||||
"{}",
|
||||
resent_after_policy.message
|
||||
);
|
||||
|
||||
assert_eq!(roles(&state, &tenant, channel_id).await, before);
|
||||
let notices = state
|
||||
.db
|
||||
|
||||
@@ -543,8 +543,20 @@ pub async fn validate_admin_event(
|
||||
// CREATE_GROUP doesn't need an existing channel — skip h-tag extraction.
|
||||
// Its initial members get the third-party add check a kind:9000 would.
|
||||
if kind == 9007 {
|
||||
let members = initial_members(event)?;
|
||||
// Ingest confirms a resend of a stored create without writing anything,
|
||||
// so a policy changed since then must not refuse it.
|
||||
if members.is_empty()
|
||||
|| state
|
||||
.db
|
||||
.get_event_by_id_for_event_write(tenant.community(), event.id.as_bytes())
|
||||
.await?
|
||||
.is_some()
|
||||
{
|
||||
return Ok(());
|
||||
}
|
||||
let actor_bytes = event.pubkey.to_bytes().to_vec();
|
||||
for member in initial_members(event)? {
|
||||
for member in members {
|
||||
if let Some((policy, owner)) = state
|
||||
.db
|
||||
.get_agent_channel_policy(tenant.community(), &member)
|
||||
|
||||
Reference in New Issue
Block a user