mirror of
https://github.com/kanidm/kanidm.git
synced 2025-02-23 20:47:01 +01:00
feat(kanidmd): add ldap support for mail primary and alternative address (#1287)
This commit is contained in:
parent
0d9467a570
commit
d3e73cdac0
|
@ -220,6 +220,9 @@ pub const UUID_SCHEMA_CLASS_SYNC_OBJECT: Uuid = uuid!("00000000-0000-0000-0000-f
|
||||||
pub const UUID_SCHEMA_ATTR_SYNC_CLASS: Uuid = uuid!("00000000-0000-0000-0000-ffff00000124");
|
pub const UUID_SCHEMA_ATTR_SYNC_CLASS: Uuid = uuid!("00000000-0000-0000-0000-ffff00000124");
|
||||||
pub const UUID_SCHEMA_ATTR_SYNC_ALLOWED: Uuid = uuid!("00000000-0000-0000-0000-ffff00000125");
|
pub const UUID_SCHEMA_ATTR_SYNC_ALLOWED: Uuid = uuid!("00000000-0000-0000-0000-ffff00000125");
|
||||||
|
|
||||||
|
pub const UUID_SCHEMA_ATTR_EMAILPRIMARY: Uuid = uuid!("00000000-0000-0000-0000-ffff00000126");
|
||||||
|
pub const UUID_SCHEMA_ATTR_EMAILALTERNATIVE: Uuid = uuid!("00000000-0000-0000-0000-ffff00000127");
|
||||||
|
|
||||||
// System and domain infos
|
// System and domain infos
|
||||||
// I'd like to strongly criticise william of the past for making poor choices about these allocations.
|
// I'd like to strongly criticise william of the past for making poor choices about these allocations.
|
||||||
pub const UUID_SYSTEM_INFO: Uuid = uuid!("00000000-0000-0000-0000-ffffff000001");
|
pub const UUID_SYSTEM_INFO: Uuid = uuid!("00000000-0000-0000-0000-ffffff000001");
|
||||||
|
|
|
@ -1795,6 +1795,24 @@ impl Entry<EntryReduced, EntryCommitted> {
|
||||||
atype: "entrydn".to_string(),
|
atype: "entrydn".to_string(),
|
||||||
vals: vec![dn.as_bytes().to_vec()],
|
vals: vec![dn.as_bytes().to_vec()],
|
||||||
}),
|
}),
|
||||||
|
"mail;primary" | "emailprimary" => {
|
||||||
|
attr_map.get(kani_a).map(|pvs| LdapPartialAttribute {
|
||||||
|
atype: ldap_a.to_string(),
|
||||||
|
vals: pvs
|
||||||
|
.first()
|
||||||
|
.map(|first| vec![first.clone()])
|
||||||
|
.unwrap_or_default(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
"mail;alternative" | "emailalternative" => {
|
||||||
|
attr_map.get(kani_a).map(|pvs| LdapPartialAttribute {
|
||||||
|
atype: ldap_a.to_string(),
|
||||||
|
vals: pvs
|
||||||
|
.split_first()
|
||||||
|
.map(|(_, rest)| rest.to_vec())
|
||||||
|
.unwrap_or_default(),
|
||||||
|
})
|
||||||
|
}
|
||||||
_ => attr_map.get(kani_a).map(|pvs| LdapPartialAttribute {
|
_ => attr_map.get(kani_a).map(|pvs| LdapPartialAttribute {
|
||||||
atype: ldap_a.to_string(),
|
atype: ldap_a.to_string(),
|
||||||
vals: pvs.clone(),
|
vals: pvs.clone(),
|
||||||
|
|
|
@ -526,14 +526,18 @@ fn operationerr_to_ldapresultcode(e: OperationError) -> (LdapResultCode, String)
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate) fn ldap_all_vattrs() -> Vec<String> {
|
pub(crate) fn ldap_all_vattrs() -> Vec<String> {
|
||||||
vec![
|
vec![
|
||||||
"entryuuid".to_string(),
|
"cn".to_string(),
|
||||||
"objectclass".to_string(),
|
|
||||||
"entrydn".to_string(),
|
|
||||||
"email".to_string(),
|
"email".to_string(),
|
||||||
"emailaddress".to_string(),
|
"emailaddress".to_string(),
|
||||||
|
"emailalternative".to_string(),
|
||||||
|
"emailprimary".to_string(),
|
||||||
|
"entrydn".to_string(),
|
||||||
|
"entryuuid".to_string(),
|
||||||
"keys".to_string(),
|
"keys".to_string(),
|
||||||
|
"mail;alternative".to_string(),
|
||||||
|
"mail;primary".to_string(),
|
||||||
|
"objectclass".to_string(),
|
||||||
"sshpublickey".to_string(),
|
"sshpublickey".to_string(),
|
||||||
"cn".to_string(),
|
|
||||||
"uidnumber".to_string(),
|
"uidnumber".to_string(),
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -547,13 +551,17 @@ pub(crate) fn ldap_vattr_map(input: &str) -> &str {
|
||||||
//
|
//
|
||||||
// LDAP NAME KANI ATTR SOURCE NAME
|
// LDAP NAME KANI ATTR SOURCE NAME
|
||||||
match input {
|
match input {
|
||||||
"entryuuid" => "uuid",
|
"cn" => "name",
|
||||||
"objectclass" => "class",
|
|
||||||
"email" => "mail",
|
"email" => "mail",
|
||||||
"emailaddress" => "mail",
|
"emailaddress" => "mail",
|
||||||
|
"emailalternative" => "mail",
|
||||||
|
"emailprimary" => "mail",
|
||||||
|
"entryuuid" => "uuid",
|
||||||
"keys" => "ssh_publickey",
|
"keys" => "ssh_publickey",
|
||||||
|
"mail;alternative" => "mail",
|
||||||
|
"mail;primary" => "mail",
|
||||||
|
"objectclass" => "class",
|
||||||
"sshpublickey" => "ssh_publickey",
|
"sshpublickey" => "ssh_publickey",
|
||||||
"cn" => "name",
|
|
||||||
"uidnumber" => "gidnumber",
|
"uidnumber" => "gidnumber",
|
||||||
a => a,
|
a => a,
|
||||||
}
|
}
|
||||||
|
@ -912,7 +920,7 @@ mod tests {
|
||||||
base: "dc=example,dc=com".to_string(),
|
base: "dc=example,dc=com".to_string(),
|
||||||
scope: LdapSearchScope::Subtree,
|
scope: LdapSearchScope::Subtree,
|
||||||
filter: LdapFilter::Equality("name".to_string(), "testperson1".to_string()),
|
filter: LdapFilter::Equality("name".to_string(), "testperson1".to_string()),
|
||||||
attrs: vec!["name".to_string(), "mail".to_string()],
|
attrs: vec!["name".to_string(), "mail".to_string(), "mail;primary".to_string(), "mail;alternative".to_string(), "emailprimary".to_string(), "emailalternative".to_string()],
|
||||||
};
|
};
|
||||||
|
|
||||||
let sa_uuid = uuid::uuid!("cc8e95b4-c24f-4d68-ba54-8bed76f63930");
|
let sa_uuid = uuid::uuid!("cc8e95b4-c24f-4d68-ba54-8bed76f63930");
|
||||||
|
@ -942,6 +950,13 @@ mod tests {
|
||||||
"mail",
|
"mail",
|
||||||
Value::EmailAddress("testperson1@example.com".to_string(), true)
|
Value::EmailAddress("testperson1@example.com".to_string(), true)
|
||||||
),
|
),
|
||||||
|
(
|
||||||
|
"mail",
|
||||||
|
Value::EmailAddress(
|
||||||
|
"testperson1.alternative@example.com".to_string(),
|
||||||
|
false
|
||||||
|
)
|
||||||
|
),
|
||||||
("description", Value::new_utf8s("testperson1")),
|
("description", Value::new_utf8s("testperson1")),
|
||||||
("displayname", Value::new_utf8s("testperson1")),
|
("displayname", Value::new_utf8s("testperson1")),
|
||||||
("gidnumber", Value::new_uint32(12345678)),
|
("gidnumber", Value::new_uint32(12345678)),
|
||||||
|
@ -1038,7 +1053,12 @@ mod tests {
|
||||||
lsre,
|
lsre,
|
||||||
"spn=testperson1@example.com,dc=example,dc=com",
|
"spn=testperson1@example.com,dc=example,dc=com",
|
||||||
("name", "testperson1"),
|
("name", "testperson1"),
|
||||||
("mail", "testperson1@example.com")
|
("mail", "testperson1@example.com"),
|
||||||
|
("mail", "testperson1.alternative@example.com"),
|
||||||
|
("mail;primary", "testperson1@example.com"),
|
||||||
|
("mail;alternative", "testperson1.alternative@example.com"),
|
||||||
|
("emailprimary", "testperson1@example.com"),
|
||||||
|
("emailalternative", "testperson1.alternative@example.com")
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
_ => assert!(false),
|
_ => assert!(false),
|
||||||
|
|
|
@ -1430,6 +1430,34 @@ impl<'a> SchemaWriteTransaction<'a> {
|
||||||
syntax: SyntaxType::EmailAddress,
|
syntax: SyntaxType::EmailAddress,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
self.attributes.insert(
|
||||||
|
AttrString::from("emailprimary"),
|
||||||
|
SchemaAttribute {
|
||||||
|
name: AttrString::from("emailprimary"),
|
||||||
|
uuid: UUID_SCHEMA_ATTR_EMAILPRIMARY,
|
||||||
|
description: String::from("An LDAP Compatible primary email"),
|
||||||
|
multivalue: false,
|
||||||
|
unique: false,
|
||||||
|
phantom: true,
|
||||||
|
sync_allowed: false,
|
||||||
|
index: vec![],
|
||||||
|
syntax: SyntaxType::EmailAddress,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
self.attributes.insert(
|
||||||
|
AttrString::from("emailalternative"),
|
||||||
|
SchemaAttribute {
|
||||||
|
name: AttrString::from("emailalternative"),
|
||||||
|
uuid: UUID_SCHEMA_ATTR_EMAILALTERNATIVE,
|
||||||
|
description: String::from("An LDAP Compatible alternative email"),
|
||||||
|
multivalue: false,
|
||||||
|
unique: false,
|
||||||
|
phantom: true,
|
||||||
|
sync_allowed: false,
|
||||||
|
index: vec![],
|
||||||
|
syntax: SyntaxType::EmailAddress,
|
||||||
|
},
|
||||||
|
);
|
||||||
self.attributes.insert(
|
self.attributes.insert(
|
||||||
AttrString::from("emailaddress"),
|
AttrString::from("emailaddress"),
|
||||||
SchemaAttribute {
|
SchemaAttribute {
|
||||||
|
|
|
@ -319,7 +319,18 @@ impl ValueSetT for ValueSetEmailAddress {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_proto_string_clone_iter(&self) -> Box<dyn Iterator<Item = String> + '_> {
|
fn to_proto_string_clone_iter(&self) -> Box<dyn Iterator<Item = String> + '_> {
|
||||||
|
if self.primary.is_empty() {
|
||||||
Box::new(self.set.iter().cloned())
|
Box::new(self.set.iter().cloned())
|
||||||
|
} else {
|
||||||
|
Box::new(
|
||||||
|
std::iter::once(self.primary.clone()).chain(
|
||||||
|
self.set
|
||||||
|
.iter()
|
||||||
|
.filter(|mail| **mail != self.primary)
|
||||||
|
.cloned(),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_db_valueset_v2(&self) -> DbValueSetV2 {
|
fn to_db_valueset_v2(&self) -> DbValueSetV2 {
|
||||||
|
|
Loading…
Reference in a new issue