refactor: Reuse typed LDAP attributes in search results

This commit is contained in:
selfhoster selfhoster 2026-09-21 15:39:49 +02:00
commit e32b4bfb82

View file

@ -148,30 +148,42 @@ pub async fn search_success(
fn search_entry_from_user(user: &User, req_attrs: &[String]) -> LdapSearchResultEntry {
let mut res: Vec<LdapPartialAttribute> = vec![];
for attr in req_attrs {
if let Some(attr_values) = match attr.as_str() {
"uid" => Some(vec![user.username.clone()]),
"cn" | "mail" => Some(vec![user.mail.clone()]),
// TODO: group membership
"memberof" => Some(vec![]),
// Copied from lldap output, not sure if we want to add/remove some classes depending on context
"objectclass" => Some(
vec!["inetOrgPerson", "posixAccount", "mailAccount", "person"]
.into_iter()
.map(String::from)
.collect(),
),
_ => {
tracing::warn!("Ignoring unknown attr in search query: {attr}");
None
for attr_str in req_attrs {
// We keep a copy of the requested attribute so that we can answer as it was requested,
// eg. `CN` => `CN` (instead of normalizing to `cn`).
let Some(attr) = LdapAttribute::from_str(attr_str)
.inspect_err(|e| tracing::debug!("Unknown attribute in request: {e}"))
.ok()
else {
continue;
};
let str_values = match attr {
// TODO: should we normalize the value some more here?
LdapAttribute::Uid => vec![user.username.clone()],
// TODO: should CN be different than the mail?
// TODO: should we normalize values some more here?
LdapAttribute::CommonName | LdapAttribute::Mail | LdapAttribute::MailAlias => {
vec![user.mail.clone()]
}
} {
res.push(LdapPartialAttribute {
atype: attr.clone(),
// LDAP response expects raw byte vec for each value
vals: attr_values.into_iter().map(Vec::from).collect(),
});
}
// TODO: group membership
LdapAttribute::MemberOf => vec![],
// TODO: if we introduce mail permission, we need to remove mailaccount from here
LdapAttribute::ObjectClass => vec![
"inetOrgPerson".to_string(),
"posixAccount".to_string(),
"mailAccount".to_string(),
"person".to_string(),
],
};
res.push(LdapPartialAttribute {
// Reuse the requested attribute name, not the normalized form
// we would otherwise produce.
atype: attr_str.clone(),
// LDAP response expects raw byte vec for each value
vals: str_values.into_iter().map(Vec::from).collect(),
});
}
LdapSearchResultEntry {