Skip to content

Commit 7653e1a

Browse files
committed
OIDC: Do not overwrite local aliases (fixes #2065)
1 parent 751cb16 commit 7653e1a

File tree

4 files changed

+34
-13
lines changed

4 files changed

+34
-13
lines changed

crates/directory/src/backend/ldap/lookup.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ impl LdapDirectory {
270270
};
271271

272272
// Keep the internal store up to date with the LDAP server
273-
let changes = principal.update_external(external_principal);
273+
let changes = principal.update_external(external_principal, true);
274274
if !changes.is_empty() {
275275
self.data_store
276276
.update_principal(

crates/directory/src/backend/oidc/lookup.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ impl OpenIdDirectory {
104104
.ok_or_else(|| manage::not_found(id).caused_by(trc::location!()))?;
105105

106106
// Keep the internal store up to date with the OIDC server
107-
let changes = principal.update_external(external_principal);
107+
let changes = principal.update_external(external_principal, false);
108108
if !changes.is_empty() {
109109
self.data_store
110110
.update_principal(

crates/directory/src/backend/sql/lookup.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ use crate::{
1515
},
1616
},
1717
};
18-
1918
use mail_send::Credentials;
2019
use store::{NamedRows, Rows, Value};
2120
use trc::AddContext;
@@ -188,7 +187,7 @@ impl SqlDirectory {
188187
};
189188

190189
// Keep the internal store up to date with the SQL server
191-
let changes = principal.update_external(external_principal);
190+
let changes = principal.update_external(external_principal, true);
192191
if !changes.is_empty() {
193192
self.data_store
194193
.update_principal(

crates/directory/src/core/principal.rs

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,11 @@ impl Principal {
258258
}
259259
}
260260

261-
pub fn update_external(&mut self, mut external: Principal) -> Vec<PrincipalUpdate> {
261+
pub fn update_external(
262+
&mut self,
263+
mut external: Principal,
264+
overwrite_emails: bool,
265+
) -> Vec<PrincipalUpdate> {
262266
let mut updates = Vec::new();
263267

264268
// Add external members
@@ -284,16 +288,34 @@ impl Principal {
284288
));
285289
}
286290

287-
for (name, field, external_field) in [
288-
(PrincipalField::Secrets, &mut self.secrets, external.secrets),
289-
(PrincipalField::Emails, &mut self.emails, external.emails),
290-
] {
291-
if !external_field.is_empty() && &external_field != field {
292-
*field = external_field;
291+
if !external.secrets.is_empty() && external.secrets != self.secrets {
292+
self.secrets = external.secrets;
293+
updates.push(PrincipalUpdate::set(
294+
PrincipalField::Secrets,
295+
PrincipalValue::StringList(self.secrets.clone()),
296+
));
297+
}
298+
299+
if !external.emails.is_empty() && external.emails != self.emails {
300+
if overwrite_emails {
301+
self.emails = external.emails;
293302
updates.push(PrincipalUpdate::set(
294-
name,
295-
PrincipalValue::StringList(field.clone()),
303+
PrincipalField::Emails,
304+
PrincipalValue::StringList(self.emails.clone()),
296305
));
306+
} else {
307+
// Missing emails are appended to avoid overwriting locally defined aliases
308+
// This means that old email addresses need to be deleted either manually or using the API
309+
for email in external.emails {
310+
let email = email.to_lowercase();
311+
if !self.emails.contains(&email) {
312+
updates.push(PrincipalUpdate::add_item(
313+
PrincipalField::Emails,
314+
PrincipalValue::String(email.clone()),
315+
));
316+
self.emails.push(email);
317+
}
318+
}
297319
}
298320
}
299321

0 commit comments

Comments
 (0)