server: Add support for querying GroupId with LDAP filters

This commit is contained in:
Simon Broeng Jensen
2025-01-20 17:07:53 +01:00
committed by GitHub
parent fb43af1299
commit 33fb59f2f7
3 changed files with 46 additions and 1 deletions

View File

@@ -17,7 +17,7 @@ use crate::domain::{
},
},
schema::{PublicSchema, SchemaGroupAttributeExtractor},
types::{AttributeName, AttributeType, Group, LdapObjectClass, UserId, Uuid},
types::{AttributeName, AttributeType, Group, GroupId, LdapObjectClass, UserId, Uuid},
};
pub fn get_group_attribute(
@@ -45,6 +45,9 @@ pub fn get_group_attribute(
GroupFieldType::EntryDn => {
vec![format!("uid={},ou=groups,{}", group.display_name, base_dn_str).into_bytes()]
}
GroupFieldType::GroupId => {
vec![group.id.0.to_string().into_bytes()]
}
GroupFieldType::DisplayName => vec![group.display_name.to_string().into_bytes()],
GroupFieldType::CreationDate => vec![chrono::Utc
.from_utc_datetime(&group.creation_date)
@@ -170,6 +173,13 @@ fn convert_group_filter(
let field = AttributeName::from(field.as_str());
let value = value.to_ascii_lowercase();
match map_group_field(&field, schema) {
GroupFieldType::GroupId => Ok(value
.parse::<i32>()
.map(|id| GroupRequestFilter::GroupId(GroupId(id)))
.unwrap_or_else(|_| {
warn!("Given group id is not a valid integer: {}", value);
GroupRequestFilter::from(false)
})),
GroupFieldType::DisplayName => Ok(GroupRequestFilter::DisplayName(value.into())),
GroupFieldType::Uuid => Uuid::try_from(value.as_str())
.map(GroupRequestFilter::Uuid)

View File

@@ -245,6 +245,7 @@ pub fn map_user_field(field: &AttributeName, schema: &PublicSchema) -> UserField
pub enum GroupFieldType {
NoMatch,
GroupId,
DisplayName,
CreationDate,
ObjectClass,
@@ -267,6 +268,7 @@ pub fn map_group_field(field: &AttributeName, schema: &PublicSchema) -> GroupFie
}
"member" | "uniquemember" => GroupFieldType::Member,
"entryuuid" | "uuid" => GroupFieldType::Uuid,
"group_id" | "groupid" => GroupFieldType::GroupId,
_ => schema
.get_schema()
.group_attributes

View File

@@ -1499,6 +1499,39 @@ mod tests {
);
}
#[tokio::test]
async fn test_search_groups_by_groupid() {
let mut mock = MockTestBackendHandler::new();
mock.expect_list_groups()
.with(eq(Some(GroupRequestFilter::GroupId(GroupId(1)))))
.times(1)
.return_once(|_| {
Ok(vec![Group {
id: GroupId(1),
display_name: "group_1".into(),
creation_date: chrono::Utc.timestamp_opt(42, 42).unwrap().naive_utc(),
users: vec![UserId::new("bob"), UserId::new("john")],
uuid: uuid!("04ac75e0-2900-3e21-926c-2f732c26b3fc"),
attributes: Vec::new(),
}])
});
let mut ldap_handler = setup_bound_admin_handler(mock).await;
let request = make_group_search_request(
LdapFilter::Equality("groupid".to_string(), "1".to_string()),
vec!["dn"],
);
assert_eq!(
ldap_handler.do_search_or_dse(&request).await,
Ok(vec![
LdapOp::SearchResultEntry(LdapSearchResultEntry {
dn: "cn=group_1,ou=groups,dc=example,dc=com".to_string(),
attributes: vec![],
}),
make_search_success(),
])
);
}
#[tokio::test]
async fn test_search_groups_filter() {
let mut mock = MockTestBackendHandler::new();