server: Add support for the custom LDAP object classes in LDAP filters

This commit is contained in:
Valentin Tolmer 2024-02-06 22:23:10 +01:00 committed by nitnelave
parent 646fe32645
commit 4955b7fac1
3 changed files with 62 additions and 10 deletions

View File

@ -9,7 +9,7 @@ use crate::domain::{
handler::{GroupListerBackendHandler, GroupRequestFilter},
ldap::error::LdapError,
schema::{PublicSchema, SchemaGroupAttributeExtractor},
types::{AttributeName, AttributeType, Group, UserId, Uuid},
types::{AttributeName, AttributeType, Group, LdapObjectClass, UserId, Uuid},
};
use super::{
@ -177,10 +177,13 @@ fn convert_group_filter(
)?;
Ok(GroupRequestFilter::Member(user_name))
}
GroupFieldType::ObjectClass => Ok(GroupRequestFilter::from(matches!(
value.as_str(),
"groupofuniquenames" | "groupofnames"
))),
GroupFieldType::ObjectClass => Ok(GroupRequestFilter::from(
matches!(value.as_str(), "groupofuniquenames" | "groupofnames")
|| schema
.get_schema()
.extra_group_object_classes
.contains(&LdapObjectClass::from(value)),
)),
GroupFieldType::Dn | GroupFieldType::EntryDn => {
Ok(get_group_id_from_distinguished_name(
value.as_str(),

View File

@ -15,7 +15,10 @@ use crate::domain::{
},
},
schema::{PublicSchema, SchemaUserAttributeExtractor},
types::{AttributeName, AttributeType, GroupDetails, User, UserAndGroups, UserColumn, UserId},
types::{
AttributeName, AttributeType, GroupDetails, LdapObjectClass, User, UserAndGroups,
UserColumn, UserId,
},
};
pub fn get_user_attribute(
@ -206,10 +209,15 @@ fn convert_user_filter(
}
Ok(UserRequestFilter::from(false))
}
UserFieldType::ObjectClass => Ok(UserRequestFilter::from(matches!(
value.as_str(),
"person" | "inetorgperson" | "posixaccount" | "mailaccount"
))),
UserFieldType::ObjectClass => Ok(UserRequestFilter::from(
matches!(
value.as_str(),
"person" | "inetorgperson" | "posixaccount" | "mailaccount"
) || schema
.get_schema()
.extra_user_object_classes
.contains(&LdapObjectClass::from(value)),
)),
UserFieldType::MemberOf => Ok(UserRequestFilter::MemberOf(
get_group_id_from_distinguished_name(
&value,

View File

@ -1931,6 +1931,47 @@ mod tests {
);
}
#[tokio::test]
async fn test_search_filters_custom_object_class() {
let mut mock = MockTestBackendHandler::new();
mock.expect_list_users()
.with(eq(Some(UserRequestFilter::from(true))), eq(false))
.times(1)
.return_once(|_, _| {
Ok(vec![UserAndGroups {
user: User {
user_id: UserId::new("bob_1"),
..Default::default()
},
groups: None,
}])
});
let mut ldap_handler = setup_bound_admin_handler(mock).await;
let request = make_user_search_request(
LdapFilter::Equality("objectClass".to_owned(), "CUSTOMuserCLASS".to_owned()),
vec!["objectclass"],
);
assert_eq!(
ldap_handler.do_search_or_dse(&request).await,
Ok(vec![
LdapOp::SearchResultEntry(LdapSearchResultEntry {
dn: "uid=bob_1,ou=people,dc=example,dc=com".to_string(),
attributes: vec![LdapPartialAttribute {
atype: "objectclass".to_string(),
vals: vec![
b"inetOrgPerson".to_vec(),
b"posixAccount".to_vec(),
b"mailAccount".to_vec(),
b"person".to_vec(),
b"customUserClass".to_vec(),
]
},]
}),
make_search_success()
])
);
}
#[tokio::test]
async fn test_search_both() {
let mut mock = MockTestBackendHandler::new();