server: Only call expand_attributes at most once per request

This commit is contained in:
Valentin Tolmer
2024-01-22 23:13:14 +01:00
committed by nitnelave
parent b82a2d5705
commit c2eed8909a
3 changed files with 27 additions and 19 deletions
+8 -4
View File
@@ -100,13 +100,11 @@ fn expand_group_attribute_wildcards(attributes: &[String]) -> Vec<&str> {
fn make_ldap_search_group_result_entry( fn make_ldap_search_group_result_entry(
group: Group, group: Group,
base_dn_str: &str, base_dn_str: &str,
attributes: &[String], expanded_attributes: &[&str],
user_filter: &Option<UserId>, user_filter: &Option<UserId>,
ignored_group_attributes: &[AttributeName], ignored_group_attributes: &[AttributeName],
schema: &PublicSchema, schema: &PublicSchema,
) -> LdapSearchResultEntry { ) -> LdapSearchResultEntry {
let expanded_attributes = expand_group_attribute_wildcards(attributes);
LdapSearchResultEntry { LdapSearchResultEntry {
dn: format!("cn={},ou=groups,{}", group.display_name, base_dn_str), dn: format!("cn={},ou=groups,{}", group.display_name, base_dn_str),
attributes: expanded_attributes attributes: expanded_attributes
@@ -267,11 +265,17 @@ pub fn convert_groups_to_ldap_op<'a>(
user_filter: &'a Option<UserId>, user_filter: &'a Option<UserId>,
schema: &'a PublicSchema, schema: &'a PublicSchema,
) -> impl Iterator<Item = LdapOp> + 'a { ) -> impl Iterator<Item = LdapOp> + 'a {
let expanded_attributes = if groups.is_empty() {
None
} else {
Some(expand_group_attribute_wildcards(attributes))
};
groups.into_iter().map(move |g| { groups.into_iter().map(move |g| {
LdapOp::SearchResultEntry(make_ldap_search_group_result_entry( LdapOp::SearchResultEntry(make_ldap_search_group_result_entry(
g, g,
&ldap_info.base_dn_str, &ldap_info.base_dn_str,
attributes, expanded_attributes.as_ref().unwrap(),
user_filter, user_filter,
&ldap_info.ignored_group_attributes, &ldap_info.ignored_group_attributes,
schema, schema,
+7 -3
View File
@@ -119,12 +119,11 @@ const ALL_USER_ATTRIBUTE_KEYS: &[&str] = &[
fn make_ldap_search_user_result_entry( fn make_ldap_search_user_result_entry(
user: User, user: User,
base_dn_str: &str, base_dn_str: &str,
attributes: &[String], expanded_attributes: &[&str],
groups: Option<&[GroupDetails]>, groups: Option<&[GroupDetails]>,
ignored_user_attributes: &[AttributeName], ignored_user_attributes: &[AttributeName],
schema: &PublicSchema, schema: &PublicSchema,
) -> LdapSearchResultEntry { ) -> LdapSearchResultEntry {
let expanded_attributes = expand_user_attribute_wildcards(attributes);
let dn = format!("uid={},ou=people,{}", user.user_id.as_str(), base_dn_str); let dn = format!("uid={},ou=people,{}", user.user_id.as_str(), base_dn_str);
LdapSearchResultEntry { LdapSearchResultEntry {
dn, dn,
@@ -295,11 +294,16 @@ pub fn convert_users_to_ldap_op<'a>(
ldap_info: &'a LdapInfo, ldap_info: &'a LdapInfo,
schema: &'a PublicSchema, schema: &'a PublicSchema,
) -> impl Iterator<Item = LdapOp> + 'a { ) -> impl Iterator<Item = LdapOp> + 'a {
let expanded_attributes = if users.is_empty() {
None
} else {
Some(expand_user_attribute_wildcards(attributes))
};
users.into_iter().map(move |u| { users.into_iter().map(move |u| {
LdapOp::SearchResultEntry(make_ldap_search_user_result_entry( LdapOp::SearchResultEntry(make_ldap_search_user_result_entry(
u.user, u.user,
&ldap_info.base_dn_str, &ldap_info.base_dn_str,
attributes, expanded_attributes.as_ref().unwrap(),
u.groups.as_deref(), u.groups.as_deref(),
&ldap_info.ignored_user_attributes, &ldap_info.ignored_user_attributes,
schema, schema,
+12 -12
View File
@@ -114,21 +114,21 @@ pub fn expand_attribute_wildcards<'a>(
ldap_attributes: &'a [String], ldap_attributes: &'a [String],
all_attribute_keys: &'a [&'static str], all_attribute_keys: &'a [&'static str],
) -> Vec<&'a str> { ) -> Vec<&'a str> {
let mut attributes_out = ldap_attributes let extra_attributes =
if ldap_attributes.iter().any(|x| x == "*") || ldap_attributes.is_empty() {
all_attribute_keys
} else {
&[]
}
.iter() .iter()
.map(String::as_str) .copied();
.collect::<Vec<_>>(); let attributes_out = ldap_attributes
.iter()
if attributes_out.iter().any(|&x| x == "*") || attributes_out.is_empty() { .map(|s| s.as_str())
// Remove occurrences of '*' .filter(|&s| s != "*" && s != "+" && s != "1.1");
attributes_out.retain(|&x| x != "*");
// Splice in all non-operational attributes
attributes_out.extend(all_attribute_keys.iter());
}
// Deduplicate, preserving order // Deduplicate, preserving order
let resolved_attributes = attributes_out let resolved_attributes = itertools::chain(attributes_out, extra_attributes)
.into_iter()
.unique_by(|a| a.to_ascii_lowercase()) .unique_by(|a| a.to_ascii_lowercase())
.collect_vec(); .collect_vec();
debug!(?resolved_attributes); debug!(?resolved_attributes);