fix: now checks to see what is needed to be added or removed.
This is more complex than the ``replace`` option but it should give more reliable results
This commit is contained in:
parent
cd710e5df7
commit
1dae2ecb26
1 changed files with 90 additions and 19 deletions
109
src/lib.rs
109
src/lib.rs
|
@ -8,6 +8,7 @@ use sqlx::{
|
||||||
sqlite::{SqliteConnectOptions, SqlitePoolOptions},
|
sqlite::{SqliteConnectOptions, SqlitePoolOptions},
|
||||||
Error, Pool, Sqlite,
|
Error, Pool, Sqlite,
|
||||||
};
|
};
|
||||||
|
use std::collections::HashSet;
|
||||||
use std::{
|
use std::{
|
||||||
env,
|
env,
|
||||||
str::FromStr,
|
str::FromStr,
|
||||||
|
@ -215,28 +216,23 @@ pub async fn update_group(config: &Config, group: &str, users: &[String], replac
|
||||||
// use the admin account
|
// use the admin account
|
||||||
ldap.simple_bind(&config.ldap_admin, &config.ldap_admin_pw)?.success()?;
|
ldap.simple_bind(&config.ldap_admin, &config.ldap_admin_pw)?.success()?;
|
||||||
|
|
||||||
let dn = format!("cn={},ou=groups,dc=skynet,dc=ie", group);
|
// we have two groups in teh LDAP that folks must be a member of
|
||||||
let members = users.iter().map(|uid| uid_to_dn(uid)).collect();
|
// ``groupname`` is the main group that we use to grant folks access to services
|
||||||
let mods = if replace {
|
// ``groupname-linux`` is specifically so that we can store some of the key linux data in the ldap, such as uid's
|
||||||
vec![Mod::Replace("member".to_string(), members)]
|
|
||||||
} else {
|
|
||||||
vec![Mod::Add("member".to_string(), members)]
|
|
||||||
};
|
|
||||||
|
|
||||||
if let Err(x) = ldap.modify(&dn, mods) {
|
{
|
||||||
println!("{:?}", x);
|
let dn = format!("cn={},ou=groups,dc=skynet,dc=ie", group);
|
||||||
|
let in_wolves = users.iter().map(|uid| uid_to_dn(uid)).collect::<HashSet<String>>();
|
||||||
|
let attribute = "member";
|
||||||
|
update_group_sub(&mut ldap, &dn, attribute, &in_wolves, replace);
|
||||||
}
|
}
|
||||||
|
|
||||||
let dn_linux = format!("cn={}-linux,ou=groups,dc=skynet,dc=ie", group);
|
{
|
||||||
let members_linux = users.iter().map(|uid| uid.to_string()).collect();
|
let dn = format!("cn={}-linux,ou=groups,dc=skynet,dc=ie", group);
|
||||||
let mods = if replace {
|
let in_wolves = users.iter().map(|uid| uid.to_string()).collect::<HashSet<String>>();
|
||||||
vec![Mod::Replace("memberUid".to_string(), members_linux)]
|
let attribute = "memberUid";
|
||||||
} else {
|
update_group_sub(&mut ldap, &dn, attribute, &in_wolves, replace);
|
||||||
vec![Mod::Add("memberUid".to_string(), members_linux)]
|
}
|
||||||
};
|
|
||||||
if let Err(x) = ldap.modify(&dn_linux, mods) {
|
|
||||||
println!("{:?}", x);
|
|
||||||
};
|
|
||||||
|
|
||||||
// tidy up
|
// tidy up
|
||||||
ldap.unbind()?;
|
ldap.unbind()?;
|
||||||
|
@ -244,6 +240,81 @@ pub async fn update_group(config: &Config, group: &str, users: &[String], replac
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn update_group_sub(ldap: &mut LdapConn, dn: &str, attribute: &str, in_wolves: &HashSet<String>, replace: bool) {
|
||||||
|
if replace {
|
||||||
|
let in_ldap = get_ldap_group(ldap, dn, attribute);
|
||||||
|
let modifications = members_to_modifications(in_wolves, &in_ldap, attribute);
|
||||||
|
|
||||||
|
// uid=gamesdev,ou=users,dc=skynet,dc=ie
|
||||||
|
// uid=gamesdev,ou=users,dc=skynet,dc=ie
|
||||||
|
// dbg!(&dn, &modifications);
|
||||||
|
if !modifications.is_empty() {
|
||||||
|
if let Err(x) = ldap.modify(dn, modifications) {
|
||||||
|
println!("{:?}", x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if let Err(x) = ldap.modify(dn, vec![Mod::Add(attribute.to_string(), in_wolves.to_owned())]) {
|
||||||
|
println!("{:?}", x);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_ldap_group(ldap: &mut LdapConn, dn: &str, attribute: &str) -> HashSet<String> {
|
||||||
|
match ldap.search(dn, Scope::Base, "(objectClass=*)", vec!["cn", attribute]) {
|
||||||
|
Ok(x) => {
|
||||||
|
if let Ok((rs, _res)) = x.success() {
|
||||||
|
for entry in rs {
|
||||||
|
let tmp = SearchEntry::construct(entry);
|
||||||
|
if tmp.attrs.contains_key(attribute) && !tmp.attrs[attribute].is_empty() {
|
||||||
|
return HashSet::from_iter(tmp.attrs[attribute].iter().cloned());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
dbg!(e);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
HashSet::new()
|
||||||
|
}
|
||||||
|
fn members_to_modifications(in_wolves: &HashSet<String>, in_ldap: &HashSet<String>, attribute: &str) -> Vec<Mod<String>> {
|
||||||
|
let mut add = HashSet::new();
|
||||||
|
let mut remove = HashSet::new();
|
||||||
|
|
||||||
|
// now we need a vec
|
||||||
|
let mut joined = HashSet::new();
|
||||||
|
for member in in_ldap {
|
||||||
|
joined.insert(member.to_owned());
|
||||||
|
}
|
||||||
|
for member in in_wolves {
|
||||||
|
joined.insert(member.to_owned());
|
||||||
|
}
|
||||||
|
|
||||||
|
for member in &joined {
|
||||||
|
// if its already in both then we dont need to do anything, nothign changes
|
||||||
|
if in_ldap.contains(member) && in_wolves.contains(member) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// if its in the ldap but not the database (from wolves) then we will need to remove from teh LDAP
|
||||||
|
if in_ldap.contains(member) && !in_wolves.contains(member) {
|
||||||
|
remove.insert(member.to_owned());
|
||||||
|
}
|
||||||
|
// if the person is member on wolves but not ldap then we need to add it to the LDAP
|
||||||
|
if !in_ldap.contains(member) && in_wolves.contains(member) {
|
||||||
|
add.insert(member.to_owned());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut modifications = vec![];
|
||||||
|
if !add.is_empty() {
|
||||||
|
modifications.push(Mod::Add(attribute.to_string(), add));
|
||||||
|
}
|
||||||
|
if !remove.is_empty() {
|
||||||
|
modifications.push(Mod::Delete(attribute.to_string(), remove));
|
||||||
|
}
|
||||||
|
|
||||||
|
modifications
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
pub struct LdapAuth {
|
pub struct LdapAuth {
|
||||||
user: String,
|
user: String,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue