Implement additionalGroups functionality (#2)

This commit is contained in:
2025-03-19 02:51:58 +01:00
parent fac8e44b24
commit 582a770e41
7 changed files with 139 additions and 3 deletions

View File

@@ -10,8 +10,9 @@ use cynic::http::{CynicReqwestError, ReqwestExt};
use cynic::{GraphQlError, GraphQlResponse, MutationBuilder, QueryBuilder};
use lldap_auth::login::{ClientSimpleLoginRequest, ServerLoginResponse};
use queries::{
CreateUser, CreateUserVariables, DeleteUser, DeleteUserVariables, GetUser, GetUserVariables,
User,
AddUserToGroup, AddUserToGroupVariables, CreateUser, CreateUserVariables, DeleteUser,
DeleteUserVariables, GetGroups, GetUser, GetUserVariables, Group, RemoveUserFromGroup,
RemoveUserFromGroupVariables, User,
};
#[derive(thiserror::Error, Debug)]
@@ -137,6 +138,47 @@ impl LldapClient {
Ok(())
}
pub async fn get_groups(&self) -> Result<Vec<Group>> {
let operation = GetGroups::build(());
let response = self
.client
.post(format!("{}/api/graphql", self.url))
.run_graphql(operation)
.await?;
Ok(check_graphql_errors(response)?.groups)
}
pub async fn add_user_to_group(&self, username: &str, group: i32) -> Result<()> {
let operation = AddUserToGroup::build(AddUserToGroupVariables { username, group });
let response = self
.client
.post(format!("{}/api/graphql", self.url))
.run_graphql(operation)
.await?;
check_graphql_errors(response)?;
Ok(())
}
pub async fn remove_user_from_group(&self, username: &str, group: i32) -> Result<()> {
let operation =
RemoveUserFromGroup::build(RemoveUserFromGroupVariables { username, group });
let response = self
.client
.post(format!("{}/api/graphql", self.url))
.run_graphql(operation)
.await?;
check_graphql_errors(response)?;
Ok(())
}
pub async fn update_password(&self, username: &str, password: &str) -> Result<()> {
let mut rng = rand::rngs::OsRng;
let registration_start_request =

View File

@@ -199,7 +199,7 @@ impl Reconcile for ServiceUser {
let lldap_client = ctx.lldap_config.build_client().await?;
trace!(name, "Creating user if needed");
let _user = match lldap_client.get_user(&username).await {
let user = match lldap_client.get_user(&username).await {
Err(lldap::Error::GraphQl(err))
if err.message == format!("Entity not found: `{username}`") =>
{
@@ -218,6 +218,42 @@ impl Reconcile for ServiceUser {
Err(err) => Err(err),
}?;
let groups = lldap_client.get_groups().await?;
// TODO: Error when invalid name
let needed_groups: Vec<_> = self
.spec
.additional_groups
.iter()
.filter_map(|additional_group| {
groups
.iter()
.find(|group| &group.display_name == additional_group)
.map(|group| group.id)
})
.collect();
let current_groups: Vec<_> = user.groups.iter().map(|group| group.id).collect();
let remove = current_groups
.iter()
.filter(|group| !needed_groups.contains(group));
for &group in remove {
trace!(name, username, group, "Removing user from group");
lldap_client
.remove_user_from_group(&username, group)
.await?;
}
let add = needed_groups
.iter()
.filter(|group| !current_groups.contains(group));
for &group in add {
trace!(name, username, group, "Adding user to group");
lldap_client.add_user_to_group(&username, group).await?;
}
trace!(name, "Updating password");
let password = secret.get().data.as_ref().unwrap().get("password").unwrap();
let password = from_utf8(&password.0).unwrap();