server: Add a Uuid attribute to every user and group
This commit is contained in:
committed by
nitnelave
parent
cbde363fde
commit
c72c1fdf2c
@@ -25,7 +25,7 @@ use lldap_auth::{login, password_reset, registration, JWTClaims};
|
||||
use crate::{
|
||||
domain::{
|
||||
error::DomainError,
|
||||
handler::{BackendHandler, BindRequest, GroupIdAndName, LoginHandler, UserId},
|
||||
handler::{BackendHandler, BindRequest, GroupDetails, LoginHandler, UserId},
|
||||
opaque_handler::OpaqueHandler,
|
||||
},
|
||||
infra::{
|
||||
@@ -37,12 +37,12 @@ use crate::{
|
||||
type Token<S> = jwt::Token<jwt::Header, JWTClaims, S>;
|
||||
type SignedToken = Token<jwt::token::Signed>;
|
||||
|
||||
fn create_jwt(key: &Hmac<Sha512>, user: String, groups: HashSet<GroupIdAndName>) -> SignedToken {
|
||||
fn create_jwt(key: &Hmac<Sha512>, user: String, groups: HashSet<GroupDetails>) -> SignedToken {
|
||||
let claims = JWTClaims {
|
||||
exp: Utc::now() + chrono::Duration::days(1),
|
||||
iat: Utc::now(),
|
||||
user,
|
||||
groups: groups.into_iter().map(|g| g.1).collect(),
|
||||
groups: groups.into_iter().map(|g| g.display_name).collect(),
|
||||
};
|
||||
let header = jwt::Header {
|
||||
algorithm: jwt::AlgorithmType::Hs512,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use crate::domain::handler::{BackendHandler, GroupId, GroupIdAndName, UserId};
|
||||
use crate::domain::handler::{BackendHandler, GroupDetails, GroupId, UserId};
|
||||
use juniper::{graphql_object, FieldResult, GraphQLInputObject};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use tracing::{debug, debug_span, Instrument};
|
||||
@@ -184,6 +184,7 @@ pub struct User<Handler: BackendHandler> {
|
||||
_phantom: std::marker::PhantomData<Box<Handler>>,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
impl<Handler: BackendHandler> Default for User<Handler> {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
@@ -257,6 +258,7 @@ impl<Handler: BackendHandler> From<DomainUserAndGroups> for User<Handler> {
|
||||
pub struct Group<Handler: BackendHandler> {
|
||||
group_id: i32,
|
||||
display_name: String,
|
||||
creation_date: chrono::DateTime<chrono::Utc>,
|
||||
members: Option<Vec<String>>,
|
||||
_phantom: std::marker::PhantomData<Box<Handler>>,
|
||||
}
|
||||
@@ -291,11 +293,12 @@ impl<Handler: BackendHandler + Sync> Group<Handler> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<Handler: BackendHandler> From<GroupIdAndName> for Group<Handler> {
|
||||
fn from(group_id_and_name: GroupIdAndName) -> Self {
|
||||
impl<Handler: BackendHandler> From<GroupDetails> for Group<Handler> {
|
||||
fn from(group_details: GroupDetails) -> Self {
|
||||
Self {
|
||||
group_id: group_id_and_name.0 .0,
|
||||
display_name: group_id_and_name.1,
|
||||
group_id: group_details.group_id.0,
|
||||
display_name: group_details.display_name,
|
||||
creation_date: group_details.creation_date,
|
||||
members: None,
|
||||
_phantom: std::marker::PhantomData,
|
||||
}
|
||||
@@ -307,6 +310,7 @@ impl<Handler: BackendHandler> From<DomainGroup> for Group<Handler> {
|
||||
Self {
|
||||
group_id: group.id.0,
|
||||
display_name: group.display_name,
|
||||
creation_date: group.creation_date,
|
||||
members: Some(group.users.into_iter().map(UserId::into_string).collect()),
|
||||
_phantom: std::marker::PhantomData,
|
||||
}
|
||||
@@ -320,6 +324,7 @@ mod tests {
|
||||
domain::handler::{MockTestBackendHandler, UserRequestFilter},
|
||||
infra::auth_service::ValidationResults,
|
||||
};
|
||||
use chrono::TimeZone;
|
||||
use juniper::{
|
||||
execute, graphql_value, DefaultScalarValue, EmptyMutation, EmptySubscription, GraphQLType,
|
||||
RootNode, Variables,
|
||||
@@ -361,7 +366,12 @@ mod tests {
|
||||
})
|
||||
});
|
||||
let mut groups = HashSet::new();
|
||||
groups.insert(GroupIdAndName(GroupId(3), "Bobbersons".to_string()));
|
||||
groups.insert(GroupDetails {
|
||||
group_id: GroupId(3),
|
||||
display_name: "Bobbersons".to_string(),
|
||||
creation_date: chrono::Utc.timestamp_nanos(42),
|
||||
uuid: crate::uuid!("a1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8"),
|
||||
});
|
||||
mock.expect_get_user_groups()
|
||||
.with(eq(UserId::new("bob")))
|
||||
.return_once(|_| Ok(groups));
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
use crate::{
|
||||
domain::{
|
||||
handler::{
|
||||
BackendHandler, BindRequest, Group, GroupIdAndName, GroupRequestFilter, LoginHandler,
|
||||
User, UserId, UserRequestFilter,
|
||||
BackendHandler, BindRequest, Group, GroupDetails, GroupRequestFilter, LoginHandler,
|
||||
User, UserId, UserRequestFilter, Uuid,
|
||||
},
|
||||
opaque_handler::OpaqueHandler,
|
||||
},
|
||||
@@ -153,7 +153,7 @@ fn get_user_attribute(
|
||||
attribute: &str,
|
||||
dn: &str,
|
||||
base_dn_str: &str,
|
||||
groups: Option<&[GroupIdAndName]>,
|
||||
groups: Option<&[GroupDetails]>,
|
||||
ignored_user_attributes: &[String],
|
||||
) -> Result<Option<Vec<String>>> {
|
||||
let attribute = attribute.to_ascii_lowercase();
|
||||
@@ -166,13 +166,19 @@ fn get_user_attribute(
|
||||
],
|
||||
"dn" | "distinguishedname" => vec![dn.to_string()],
|
||||
"uid" => vec![user.user_id.to_string()],
|
||||
"entryuuid" => vec![user.uuid.to_string()],
|
||||
"mail" => vec![user.email.clone()],
|
||||
"givenname" => vec![user.first_name.clone()],
|
||||
"sn" => vec![user.last_name.clone()],
|
||||
"memberof" => groups
|
||||
.into_iter()
|
||||
.flatten()
|
||||
.map(|id_and_name| format!("uid={},ou=groups,{}", &id_and_name.1, base_dn_str))
|
||||
.map(|id_and_name| {
|
||||
format!(
|
||||
"uid={},ou=groups,{}",
|
||||
&id_and_name.display_name, base_dn_str
|
||||
)
|
||||
})
|
||||
.collect(),
|
||||
"cn" | "displayname" => vec![user.display_name.clone()],
|
||||
"createtimestamp" | "modifytimestamp" => vec![user.creation_date.to_rfc3339()],
|
||||
@@ -233,7 +239,7 @@ fn make_ldap_search_user_result_entry(
|
||||
user: User,
|
||||
base_dn_str: &str,
|
||||
attributes: &[String],
|
||||
groups: Option<&[GroupIdAndName]>,
|
||||
groups: Option<&[GroupDetails]>,
|
||||
ignored_user_attributes: &[String],
|
||||
) -> Result<LdapSearchResultEntry> {
|
||||
let dn = format!("uid={},ou=people,{}", user.user_id.as_str(), base_dn_str);
|
||||
@@ -278,6 +284,7 @@ fn get_group_attribute(
|
||||
group.display_name, base_dn_str
|
||||
)],
|
||||
"cn" | "uid" => vec![group.display_name.clone()],
|
||||
"entryuuid" => vec![group.uuid.to_string()],
|
||||
"member" | "uniquemember" => group
|
||||
.users
|
||||
.iter()
|
||||
@@ -363,24 +370,18 @@ fn is_subtree(subtree: &[(String, String)], base_tree: &[(String, String)]) -> b
|
||||
true
|
||||
}
|
||||
|
||||
fn map_field(field: &str) -> Result<String> {
|
||||
fn map_field(field: &str) -> Result<&'static str> {
|
||||
assert!(field == field.to_ascii_lowercase());
|
||||
Ok(if field == "uid" {
|
||||
"user_id".to_string()
|
||||
} else if field == "mail" {
|
||||
"email".to_string()
|
||||
} else if field == "cn" || field == "displayname" {
|
||||
"display_name".to_string()
|
||||
} else if field == "givenname" {
|
||||
"first_name".to_string()
|
||||
} else if field == "sn" {
|
||||
"last_name".to_string()
|
||||
} else if field == "avatar" {
|
||||
"avatar".to_string()
|
||||
} else if field == "creationdate" || field == "createtimestamp" || field == "modifytimestamp" {
|
||||
"creation_date".to_string()
|
||||
} else {
|
||||
bail!("Unknown field: {}", field);
|
||||
Ok(match field {
|
||||
"uid" => "user_id",
|
||||
"mail" => "email",
|
||||
"cn" | "displayname" => "display_name",
|
||||
"givenname" => "first_name",
|
||||
"sn" => "last_name",
|
||||
"avatar" => "avatar",
|
||||
"creationdate" | "createtimestamp" | "modifytimestamp" => "creation_date",
|
||||
"entryuuid" => "uuid",
|
||||
_ => bail!("Unknown field: {}", field),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -499,7 +500,7 @@ impl<Backend: BackendHandler + LoginHandler + OpaqueHandler> LdapHandler<Backend
|
||||
let is_in_group = |name| {
|
||||
user_groups
|
||||
.as_ref()
|
||||
.map(|groups| groups.iter().any(|g| g.1 == name))
|
||||
.map(|groups| groups.iter().any(|g| g.display_name == name))
|
||||
.unwrap_or(false)
|
||||
};
|
||||
self.user_info = Some((
|
||||
@@ -845,29 +846,36 @@ impl<Backend: BackendHandler + LoginHandler + OpaqueHandler> LdapHandler<Backend
|
||||
LdapFilter::Equality(field, value) => {
|
||||
let field = &field.to_ascii_lowercase();
|
||||
let value = &value.to_ascii_lowercase();
|
||||
if field == "member" || field == "uniquemember" {
|
||||
let user_name = get_user_id_from_distinguished_name(
|
||||
value,
|
||||
&self.base_dn,
|
||||
&self.base_dn_str,
|
||||
)?;
|
||||
Ok(GroupRequestFilter::Member(user_name))
|
||||
} else if field == "objectclass" {
|
||||
if value == "groupofuniquenames" || value == "groupofnames" {
|
||||
Ok(GroupRequestFilter::And(vec![]))
|
||||
} else {
|
||||
Ok(GroupRequestFilter::Not(Box::new(GroupRequestFilter::And(
|
||||
vec![],
|
||||
))))
|
||||
match field.as_str() {
|
||||
"member" | "uniquemember" => {
|
||||
let user_name = get_user_id_from_distinguished_name(
|
||||
value,
|
||||
&self.base_dn,
|
||||
&self.base_dn_str,
|
||||
)?;
|
||||
Ok(GroupRequestFilter::Member(user_name))
|
||||
}
|
||||
} else {
|
||||
let mapped_field = map_field(field);
|
||||
if mapped_field.is_ok()
|
||||
&& (mapped_field.as_ref().unwrap() == "display_name"
|
||||
|| mapped_field.as_ref().unwrap() == "user_id")
|
||||
{
|
||||
Ok(GroupRequestFilter::DisplayName(value.clone()))
|
||||
} else {
|
||||
"objectclass" => {
|
||||
if value == "groupofuniquenames" || value == "groupofnames" {
|
||||
Ok(GroupRequestFilter::And(vec![]))
|
||||
} else {
|
||||
Ok(GroupRequestFilter::Not(Box::new(GroupRequestFilter::And(
|
||||
vec![],
|
||||
))))
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
match map_field(field) {
|
||||
Ok("display_name") | Ok("user_id") => {
|
||||
return Ok(GroupRequestFilter::DisplayName(value.clone()));
|
||||
}
|
||||
Ok("uuid") => {
|
||||
return Ok(GroupRequestFilter::Uuid(Uuid::try_from(
|
||||
value.as_str(),
|
||||
)?));
|
||||
}
|
||||
_ => (),
|
||||
};
|
||||
if !self.ignored_group_attributes.contains(field) {
|
||||
warn!(
|
||||
r#"Ignoring unknown group attribute "{:?}" in filter.\n\
|
||||
@@ -928,32 +936,37 @@ impl<Backend: BackendHandler + LoginHandler + OpaqueHandler> LdapHandler<Backend
|
||||
))),
|
||||
LdapFilter::Equality(field, value) => {
|
||||
let field = &field.to_ascii_lowercase();
|
||||
if field == "memberof" {
|
||||
let group_name = get_group_id_from_distinguished_name(
|
||||
&value.to_ascii_lowercase(),
|
||||
&self.base_dn,
|
||||
&self.base_dn_str,
|
||||
)?;
|
||||
Ok(UserRequestFilter::MemberOf(group_name))
|
||||
} else if field == "objectclass" {
|
||||
if value == "person"
|
||||
|| value == "inetOrgPerson"
|
||||
|| value == "posixAccount"
|
||||
|| value == "mailAccount"
|
||||
{
|
||||
Ok(UserRequestFilter::And(vec![]))
|
||||
} else {
|
||||
Ok(UserRequestFilter::Not(Box::new(UserRequestFilter::And(
|
||||
vec![],
|
||||
))))
|
||||
match field.as_str() {
|
||||
"memberof" => {
|
||||
let group_name = get_group_id_from_distinguished_name(
|
||||
&value.to_ascii_lowercase(),
|
||||
&self.base_dn,
|
||||
&self.base_dn_str,
|
||||
)?;
|
||||
Ok(UserRequestFilter::MemberOf(group_name))
|
||||
}
|
||||
} else {
|
||||
match map_field(field) {
|
||||
"objectclass" => {
|
||||
if value == "person"
|
||||
|| value == "inetOrgPerson"
|
||||
|| value == "posixAccount"
|
||||
|| value == "mailAccount"
|
||||
{
|
||||
Ok(UserRequestFilter::And(vec![]))
|
||||
} else {
|
||||
Ok(UserRequestFilter::Not(Box::new(UserRequestFilter::And(
|
||||
vec![],
|
||||
))))
|
||||
}
|
||||
}
|
||||
_ => match map_field(field) {
|
||||
Ok(field) => {
|
||||
if field == "user_id" {
|
||||
Ok(UserRequestFilter::UserId(UserId::new(value)))
|
||||
} else {
|
||||
Ok(UserRequestFilter::Equality(field, value.clone()))
|
||||
Ok(UserRequestFilter::Equality(
|
||||
field.to_string(),
|
||||
value.clone(),
|
||||
))
|
||||
}
|
||||
}
|
||||
Err(_) => {
|
||||
@@ -968,7 +981,7 @@ impl<Backend: BackendHandler + LoginHandler + OpaqueHandler> LdapHandler<Backend
|
||||
vec![],
|
||||
))))
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
LdapFilter::Present(field) => {
|
||||
@@ -990,8 +1003,12 @@ impl<Backend: BackendHandler + LoginHandler + OpaqueHandler> LdapHandler<Backend
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::domain::{error::Result, handler::*, opaque_handler::*};
|
||||
use crate::{
|
||||
domain::{error::Result, handler::*, opaque_handler::*},
|
||||
uuid,
|
||||
};
|
||||
use async_trait::async_trait;
|
||||
use chrono::TimeZone;
|
||||
use ldap3_server::proto::{LdapDerefAliases, LdapSearchScope};
|
||||
use mockall::predicate::eq;
|
||||
use std::collections::HashSet;
|
||||
@@ -1011,8 +1028,8 @@ mod tests {
|
||||
async fn list_users(&self, filters: Option<UserRequestFilter>, get_groups: bool) -> Result<Vec<UserAndGroups>>;
|
||||
async fn list_groups(&self, filters: Option<GroupRequestFilter>) -> Result<Vec<Group>>;
|
||||
async fn get_user_details(&self, user_id: &UserId) -> Result<User>;
|
||||
async fn get_group_details(&self, group_id: GroupId) -> Result<GroupIdAndName>;
|
||||
async fn get_user_groups(&self, user: &UserId) -> Result<HashSet<GroupIdAndName>>;
|
||||
async fn get_group_details(&self, group_id: GroupId) -> Result<GroupDetails>;
|
||||
async fn get_user_groups(&self, user: &UserId) -> Result<HashSet<GroupDetails>>;
|
||||
async fn create_user(&self, request: CreateUserRequest) -> Result<()>;
|
||||
async fn update_user(&self, request: UpdateUserRequest) -> Result<()>;
|
||||
async fn update_group(&self, request: UpdateGroupRequest) -> Result<()>;
|
||||
@@ -1079,7 +1096,12 @@ mod tests {
|
||||
.with(eq(UserId::new("test")))
|
||||
.return_once(|_| {
|
||||
let mut set = HashSet::new();
|
||||
set.insert(GroupIdAndName(GroupId(42), group));
|
||||
set.insert(GroupDetails {
|
||||
group_id: GroupId(42),
|
||||
display_name: group,
|
||||
creation_date: chrono::Utc.timestamp(42, 42),
|
||||
uuid: uuid!("a1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8"),
|
||||
});
|
||||
Ok(set)
|
||||
});
|
||||
let mut ldap_handler =
|
||||
@@ -1155,7 +1177,12 @@ mod tests {
|
||||
.with(eq(UserId::new("test")))
|
||||
.return_once(|_| {
|
||||
let mut set = HashSet::new();
|
||||
set.insert(GroupIdAndName(GroupId(42), "lldap_admin".to_string()));
|
||||
set.insert(GroupDetails {
|
||||
group_id: GroupId(42),
|
||||
display_name: "lldap_admin".to_string(),
|
||||
creation_date: chrono::Utc.timestamp(42, 42),
|
||||
uuid: uuid!("a1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8"),
|
||||
});
|
||||
Ok(set)
|
||||
});
|
||||
let mut ldap_handler =
|
||||
@@ -1237,7 +1264,12 @@ mod tests {
|
||||
user_id: UserId::new("bob"),
|
||||
..Default::default()
|
||||
},
|
||||
groups: Some(vec![GroupIdAndName(GroupId(42), "rockstars".to_string())]),
|
||||
groups: Some(vec![GroupDetails {
|
||||
group_id: GroupId(42),
|
||||
display_name: "rockstars".to_string(),
|
||||
creation_date: chrono::Utc.timestamp(42, 42),
|
||||
uuid: uuid!("a1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8"),
|
||||
}]),
|
||||
}])
|
||||
});
|
||||
let mut ldap_handler = setup_bound_readonly_handler(mock).await;
|
||||
@@ -1386,6 +1418,7 @@ mod tests {
|
||||
display_name: "Bôb Böbberson".to_string(),
|
||||
first_name: "Bôb".to_string(),
|
||||
last_name: "Böbberson".to_string(),
|
||||
uuid: uuid!("698e1d5f-7a40-3151-8745-b9b8a37839da"),
|
||||
..Default::default()
|
||||
},
|
||||
groups: None,
|
||||
@@ -1397,6 +1430,7 @@ mod tests {
|
||||
display_name: "Jimminy Cricket".to_string(),
|
||||
first_name: "Jim".to_string(),
|
||||
last_name: "Cricket".to_string(),
|
||||
uuid: uuid!("04ac75e0-2900-3e21-926c-2f732c26b3fc"),
|
||||
creation_date: Utc.ymd(2014, 7, 8).and_hms(9, 10, 11),
|
||||
},
|
||||
groups: None,
|
||||
@@ -1415,6 +1449,7 @@ mod tests {
|
||||
"sn",
|
||||
"cn",
|
||||
"createTimestamp",
|
||||
"entryUuid",
|
||||
],
|
||||
);
|
||||
assert_eq!(
|
||||
@@ -1459,7 +1494,11 @@ mod tests {
|
||||
LdapPartialAttribute {
|
||||
atype: "createTimestamp".to_string(),
|
||||
vals: vec!["1970-01-01T00:00:00+00:00".to_string()]
|
||||
}
|
||||
},
|
||||
LdapPartialAttribute {
|
||||
atype: "entryUuid".to_string(),
|
||||
vals: vec!["698e1d5f-7a40-3151-8745-b9b8a37839da".to_string()]
|
||||
},
|
||||
],
|
||||
}),
|
||||
LdapOp::SearchResultEntry(LdapSearchResultEntry {
|
||||
@@ -1501,7 +1540,11 @@ mod tests {
|
||||
LdapPartialAttribute {
|
||||
atype: "createTimestamp".to_string(),
|
||||
vals: vec!["2014-07-08T09:10:11+00:00".to_string()]
|
||||
}
|
||||
},
|
||||
LdapPartialAttribute {
|
||||
atype: "entryUuid".to_string(),
|
||||
vals: vec!["04ac75e0-2900-3e21-926c-2f732c26b3fc".to_string()]
|
||||
},
|
||||
],
|
||||
}),
|
||||
make_search_success(),
|
||||
@@ -1520,12 +1563,16 @@ mod tests {
|
||||
Group {
|
||||
id: GroupId(1),
|
||||
display_name: "group_1".to_string(),
|
||||
creation_date: chrono::Utc.timestamp(42, 42),
|
||||
users: vec![UserId::new("bob"), UserId::new("john")],
|
||||
uuid: uuid!("04ac75e0-2900-3e21-926c-2f732c26b3fc"),
|
||||
},
|
||||
Group {
|
||||
id: GroupId(3),
|
||||
display_name: "BestGroup".to_string(),
|
||||
creation_date: chrono::Utc.timestamp(42, 42),
|
||||
users: vec![UserId::new("john")],
|
||||
uuid: uuid!("04ac75e0-2900-3e21-926c-2f732c26b3fc"),
|
||||
},
|
||||
])
|
||||
});
|
||||
@@ -1533,7 +1580,7 @@ mod tests {
|
||||
let request = make_search_request(
|
||||
"ou=groups,dc=example,dc=cOm",
|
||||
LdapFilter::And(vec![]),
|
||||
vec!["objectClass", "dn", "cn", "uniqueMember"],
|
||||
vec!["objectClass", "dn", "cn", "uniqueMember", "entryUuid"],
|
||||
);
|
||||
assert_eq!(
|
||||
ldap_handler.do_search_or_dse(&request).await,
|
||||
@@ -1560,6 +1607,10 @@ mod tests {
|
||||
"uid=john,ou=people,dc=example,dc=com".to_string(),
|
||||
]
|
||||
},
|
||||
LdapPartialAttribute {
|
||||
atype: "entryUuid".to_string(),
|
||||
vals: vec!["04ac75e0-2900-3e21-926c-2f732c26b3fc".to_string()],
|
||||
},
|
||||
],
|
||||
}),
|
||||
LdapOp::SearchResultEntry(LdapSearchResultEntry {
|
||||
@@ -1581,6 +1632,10 @@ mod tests {
|
||||
atype: "uniqueMember".to_string(),
|
||||
vals: vec!["uid=john,ou=people,dc=example,dc=com".to_string()]
|
||||
},
|
||||
LdapPartialAttribute {
|
||||
atype: "entryUuid".to_string(),
|
||||
vals: vec!["04ac75e0-2900-3e21-926c-2f732c26b3fc".to_string()],
|
||||
},
|
||||
],
|
||||
}),
|
||||
make_search_success(),
|
||||
@@ -1609,7 +1664,9 @@ mod tests {
|
||||
Ok(vec![Group {
|
||||
display_name: "group_1".to_string(),
|
||||
id: GroupId(1),
|
||||
creation_date: chrono::Utc.timestamp(42, 42),
|
||||
users: vec![],
|
||||
uuid: uuid!("04ac75e0-2900-3e21-926c-2f732c26b3fc"),
|
||||
}])
|
||||
});
|
||||
let mut ldap_handler = setup_bound_admin_handler(mock).await;
|
||||
@@ -1658,7 +1715,9 @@ mod tests {
|
||||
Ok(vec![Group {
|
||||
display_name: "group_1".to_string(),
|
||||
id: GroupId(1),
|
||||
creation_date: chrono::Utc.timestamp(42, 42),
|
||||
users: vec![],
|
||||
uuid: uuid!("04ac75e0-2900-3e21-926c-2f732c26b3fc"),
|
||||
}])
|
||||
});
|
||||
let mut ldap_handler = setup_bound_admin_handler(mock).await;
|
||||
@@ -1932,7 +1991,9 @@ mod tests {
|
||||
Ok(vec![Group {
|
||||
id: GroupId(1),
|
||||
display_name: "group_1".to_string(),
|
||||
creation_date: chrono::Utc.timestamp(42, 42),
|
||||
users: vec![UserId::new("bob"), UserId::new("john")],
|
||||
uuid: uuid!("04ac75e0-2900-3e21-926c-2f732c26b3fc"),
|
||||
}])
|
||||
});
|
||||
let mut ldap_handler = setup_bound_admin_handler(mock).await;
|
||||
@@ -1989,7 +2050,6 @@ mod tests {
|
||||
}
|
||||
#[tokio::test]
|
||||
async fn test_search_wildcards() {
|
||||
use chrono::TimeZone;
|
||||
let mut mock = MockTestBackendHandler::new();
|
||||
|
||||
mock.expect_list_users().returning(|_, _| {
|
||||
@@ -2011,7 +2071,9 @@ mod tests {
|
||||
Ok(vec![Group {
|
||||
id: GroupId(1),
|
||||
display_name: "group_1".to_string(),
|
||||
creation_date: chrono::Utc.timestamp(42, 42),
|
||||
users: vec![UserId::new("bob"), UserId::new("john")],
|
||||
uuid: uuid!("04ac75e0-2900-3e21-926c-2f732c26b3fc"),
|
||||
}])
|
||||
});
|
||||
let mut ldap_handler = setup_bound_admin_handler(mock).await;
|
||||
|
||||
@@ -38,8 +38,8 @@ mockall::mock! {
|
||||
async fn list_users(&self, filters: Option<UserRequestFilter>, get_groups: bool) -> Result<Vec<UserAndGroups>>;
|
||||
async fn list_groups(&self, filters: Option<GroupRequestFilter>) -> Result<Vec<Group>>;
|
||||
async fn get_user_details(&self, user_id: &UserId) -> Result<User>;
|
||||
async fn get_group_details(&self, group_id: GroupId) -> Result<GroupIdAndName>;
|
||||
async fn get_user_groups(&self, user: &UserId) -> Result<HashSet<GroupIdAndName>>;
|
||||
async fn get_group_details(&self, group_id: GroupId) -> Result<GroupDetails>;
|
||||
async fn get_user_groups(&self, user: &UserId) -> Result<HashSet<GroupDetails>>;
|
||||
async fn create_user(&self, request: CreateUserRequest) -> Result<()>;
|
||||
async fn update_user(&self, request: UpdateUserRequest) -> Result<()>;
|
||||
async fn update_group(&self, request: UpdateGroupRequest) -> Result<()>;
|
||||
|
||||
Reference in New Issue
Block a user