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!())