Skip to content

Commit 933dc31

Browse files
committed
fix: redirty watch interest on authorization changes
1 parent 3a7f4b7 commit 933dc31

1 file changed

Lines changed: 65 additions & 0 deletions

File tree

operations/src/notifications/watch/interest.rs

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -498,6 +498,12 @@ pub async fn refresh_watch_interest_for_targets(
498498
DocumentSyncTarget::WatchSubscription { owner, .. } => {
499499
dirty_realms.insert(owner.realm_id);
500500
}
501+
DocumentSyncTarget::GroupAuthorization { .. } => {
502+
dirty_realms.insert(*net_handle.realm_id());
503+
}
504+
DocumentSyncTarget::RealmAuthorization { realm_id } => {
505+
dirty_realms.insert(*realm_id);
506+
}
501507
DocumentSyncTarget::RealmConfig { realm_id } => {
502508
realms.insert(*realm_id);
503509
dirty_realms.insert(*realm_id);
@@ -1103,6 +1109,65 @@ mod tests {
11031109
assert_eq!(table.nodes(realm_id).map(|nodes| nodes.len()), Some(1));
11041110
}
11051111

1112+
// A consumed empty digest must be re-dirtied by group authorization
1113+
// reconciliation so a later READ grant restores remote interest.
1114+
#[tokio::test]
1115+
async fn regrant_restores_digest() {
1116+
let realm_id = RealmId([6u8; 32]);
1117+
let (_dir, ctx, net) = ctx_with_net(realm_id, [72u8; 32]).await;
1118+
let node_id = net.node_id();
1119+
install_realm_config(&ctx, realm_id, &[node_id]).await;
1120+
let group_id = Ulid::r#gen();
1121+
let auth_owner = user(6, 3);
1122+
let watch_owner = user(6, 2);
1123+
let prefix = metadata_prefix(group_id, "a");
1124+
install_authorization(&ctx, realm_id, node_id, group_id, auth_owner, &[]).await;
1125+
create_watch_subscription(&ctx.storage_handle, watch_owner, prefix.clone(), mask(), 1)
1126+
.await
1127+
.expect("create");
1128+
1129+
assert!(
1130+
publish_watch_interest(&ctx, node_id)
1131+
.await
1132+
.expect("publish")
1133+
);
1134+
assert!(
1135+
read_digest(&ctx, realm_id, node_id)
1136+
.await
1137+
.expect("empty digest")
1138+
.entries
1139+
.is_empty()
1140+
);
1141+
assert!(read_marker(&ctx, realm_id).await.is_none());
1142+
1143+
install_authorization(
1144+
&ctx,
1145+
realm_id,
1146+
node_id,
1147+
group_id,
1148+
auth_owner,
1149+
&[watch_owner],
1150+
)
1151+
.await;
1152+
refresh_watch_interest_for_targets(
1153+
&ctx,
1154+
&[DocumentSyncTarget::GroupAuthorization { group_id }],
1155+
)
1156+
.await;
1157+
1158+
assert!(read_marker(&ctx, realm_id).await.is_some());
1159+
assert!(
1160+
publish_watch_interest(&ctx, node_id)
1161+
.await
1162+
.expect("republish")
1163+
);
1164+
let digest = read_digest(&ctx, realm_id, node_id)
1165+
.await
1166+
.expect("restored digest");
1167+
assert_eq!(digest.entries.len(), 1);
1168+
assert_eq!(digest.entries[0].path_prefix, prefix);
1169+
}
1170+
11061171
#[tokio::test]
11071172
async fn refresh_updates_the_net_handle_table() {
11081173
let realm_id = RealmId([4u8; 32]);

0 commit comments

Comments
 (0)