fix(user-pref): permit edition of user prefs for OIDC account

This commit is contained in:
Edouard Vanbelle
2026-08-13 20:39:55 +02:00
parent b1493e2d0e
commit 1104a4cb06
2 changed files with 25 additions and 2 deletions
+17
View File
@@ -406,6 +406,23 @@ pub struct UpdateProfileDto {
pub ui_preferences: Option<serde_json::Value>,
}
impl UpdateProfileDto {
/// True when the patch touches at least one field whose source of
/// truth is an external identity provider — currently `given_name`
/// and `family_name`. For OIDC-managed users the auth service
/// refuses the whole patch when this returns true (IdP pushes those
/// fields on every login; editing them here would be silently
/// overwritten). Local-only fields — `ui_preferences`,
/// `notify_on_share`, `preferred_locale`, the claim-once `username`
/// (never re-synced from the IdP) — return `false` so an OIDC user
/// can still change their view mode, share-mail opt-in, locale,
/// etc. Add future IdP-authoritative fields (e.g. `email`, `image`)
/// here if they land in this DTO.
pub fn touches_idp_managed_fields(&self) -> bool {
self.given_name.is_some() || self.family_name.is_some()
}
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct AuthResponseDto {
pub user: UserDto,
@@ -2446,7 +2446,13 @@ impl AuthApplicationService {
) -> Result<UserDto, DomainError> {
let mut user = self.user_storage.get_user_by_id(caller_id).await?;
if user.is_oidc_user() {
// For OIDC-managed users, refuse the patch ONLY when it touches
// a field the IdP owns (currently `given_name` / `family_name`
// — see `UpdateProfileDto::touches_idp_managed_fields`). Local-
// only fields (ui_preferences, notify_on_share, preferred_locale,
// claim-once username) stay editable — those are personal
// OxiCloud preferences, not identity data pushed by the IdP.
if user.is_oidc_user() && dto.touches_idp_managed_fields() {
tracing::info!(
target: "audit",
event = "auth.profile_update_rejected",
@@ -2457,7 +2463,7 @@ impl AuthApplicationService {
return Err(DomainError::new(
ErrorKind::AccessDenied,
"User",
"Your profile is managed by the identity provider and \
"Your name is managed by the identity provider and \
cannot be edited here. Update it at the IdP — changes \
will propagate on your next sign-in.",
));