From 7e56afe872e2963f1bcba80f7d9cf7c510bacdce Mon Sep 17 00:00:00 2001 From: Maurus Decimus <11444311+mdecimus@users.noreply.github.com> Date: Wed, 29 Apr 2026 09:22:41 +0200 Subject: [PATCH] Fix Directory: Invalidate caches when group memberships change on an external directory. --- CHANGELOG.md | 1 + crates/common/src/auth/access_token.rs | 3 +++ crates/common/src/cache/directory.rs | 33 ++++++++++++++++++++------ 3 files changed, 30 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5714c0d8..c34eb4ab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ If you are upgrading from v0.16.x, replace the binary (or run `docker pull`). If ## Changed ## Fixed +- Directory: Invalidate caches when group memberships change on an external directory. - Log viewer: All events show as `INFO`. ## [0.16.2] - 2026-04-28 diff --git a/crates/common/src/auth/access_token.rs b/crates/common/src/auth/access_token.rs index ccd7081e..8adbfe1a 100644 --- a/crates/common/src/auth/access_token.rs +++ b/crates/common/src/auth/access_token.rs @@ -840,6 +840,9 @@ fn hash_account(account: &Account) -> u64 { credential.expires_at.hash(&mut s); hash_credential_permissions(&mut s, &credential.permissions); } + for group_id in account.member_group_ids.iter() { + group_id.hash(&mut s); + } } Account::Group(account) => { account.member_tenant_id.hash(&mut s); diff --git a/crates/common/src/cache/directory.rs b/crates/common/src/cache/directory.rs index 1462698d..0c68498e 100644 --- a/crates/common/src/cache/directory.rs +++ b/crates/common/src/cache/directory.rs @@ -4,7 +4,9 @@ * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL */ -use crate::{Server, auth::DomainCache, ipc::BroadcastEvent}; +use crate::{ + Server, auth::DomainCache, cache::invalidate::CacheInvalidationBuilder, ipc::BroadcastEvent, +}; use registry::{ schema::{ prelude::{Object, ObjectType}, @@ -126,10 +128,18 @@ impl Server { .await .caused_by(trc::location!())? { - RegistryWriteResult::Success(id) => Ok(AccountWithId { - id: id.document_id(), - account: updated_account.into(), - }), + RegistryWriteResult::Success(id) => { + let mut invalidator = CacheInvalidationBuilder::default(); + invalidator.process_update(id, ¤t_account, &updated_account); + self.invalidate_caches(invalidator) + .await + .caused_by(trc::location!())?; + + Ok(AccountWithId { + id: id.document_id(), + account: updated_account.into(), + }) + } failure => Err(trc::AuthEvent::Error .into_err() .caused_by(trc::location!()) @@ -287,17 +297,26 @@ impl Server { } if has_changes { + let updated_account = Object::from(Account::Group(updated_account)); match self .registry() .write(RegistryWrite::update( Id::from(account_id), - &Object::from(Account::Group(updated_account)), + &updated_account, ¤t_account, )) .await .caused_by(trc::location!())? { - RegistryWriteResult::Success(id) => Ok(id.document_id()), + RegistryWriteResult::Success(id) => { + let mut invalidator = CacheInvalidationBuilder::default(); + invalidator.process_update(id, ¤t_account, &updated_account); + self.invalidate_caches(invalidator) + .await + .caused_by(trc::location!())?; + + Ok(id.document_id()) + } failure => Err(trc::AuthEvent::Error .into_err() .caused_by(trc::location!())