fix(user-pref): permit edition of user prefs for OIDC account
This commit is contained in:
@@ -406,6 +406,23 @@ pub struct UpdateProfileDto {
|
|||||||
pub ui_preferences: Option<serde_json::Value>,
|
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)]
|
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
|
||||||
pub struct AuthResponseDto {
|
pub struct AuthResponseDto {
|
||||||
pub user: UserDto,
|
pub user: UserDto,
|
||||||
|
|||||||
@@ -2446,7 +2446,13 @@ impl AuthApplicationService {
|
|||||||
) -> Result<UserDto, DomainError> {
|
) -> Result<UserDto, DomainError> {
|
||||||
let mut user = self.user_storage.get_user_by_id(caller_id).await?;
|
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!(
|
tracing::info!(
|
||||||
target: "audit",
|
target: "audit",
|
||||||
event = "auth.profile_update_rejected",
|
event = "auth.profile_update_rejected",
|
||||||
@@ -2457,7 +2463,7 @@ impl AuthApplicationService {
|
|||||||
return Err(DomainError::new(
|
return Err(DomainError::new(
|
||||||
ErrorKind::AccessDenied,
|
ErrorKind::AccessDenied,
|
||||||
"User",
|
"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 \
|
cannot be edited here. Update it at the IdP — changes \
|
||||||
will propagate on your next sign-in.",
|
will propagate on your next sign-in.",
|
||||||
));
|
));
|
||||||
|
|||||||
Reference in New Issue
Block a user