feat: split up into seperate modules before it gets too tangled up

This commit is contained in:
silver 2023-06-04 12:17:16 +01:00
parent 82ce0a864f
commit 9b52052add
4 changed files with 117 additions and 117 deletions

View file

@ -1,6 +1,8 @@
pub mod methods;
use dotenv::dotenv;
use sqlx::sqlite::{SqliteConnectOptions, SqlitePoolOptions};
use sqlx::{Error, Pool, Sqlite};
use std::env;
use std::str::FromStr;
use std::time::{SystemTime, UNIX_EPOCH};
@ -41,3 +43,39 @@ pub fn get_now() -> i64 {
0
}
}
#[derive(Clone)]
pub struct State {
pub db: Pool<Sqlite>,
pub config: Config,
}
#[derive(Debug, Clone)]
pub struct Config {
ldap_host: String,
pub database: String,
pub host_port: String,
}
pub fn get_config() -> Config {
dotenv().ok();
// reasonable defaults
let mut config = Config {
ldap_host: "".to_string(),
database: "database.db".to_string(),
host_port: "127.0.0.1:8087".to_string(),
};
if let Ok(x) = env::var("LDAP_HOST") {
config.ldap_host = x.trim().to_string();
}
if let Ok(x) = env::var("DATABASE") {
config.database = x.trim().to_string();
}
if let Ok(x) = env::var("HOST_PORT") {
config.host_port = x.trim().to_string();
}
config
}

View file

@ -1,21 +1,5 @@
use ldap3::{LdapConn, Mod, Scope, SearchEntry};
use ldap3::exop::PasswordModify;
use std::collections::HashSet;
// for teh webserver
use dotenv::dotenv;
use skynet_ldap_server::db_init;
use sqlx::{Pool, Sqlite};
use std::env;
use tide::prelude::{json, Deserialize};
use tide::Request;
#[derive(Clone)]
struct State {
db: Pool<Sqlite>,
config: Config,
}
use skynet_ldap_server::methods::change_details::post_update_ldap;
use skynet_ldap_server::{db_init, get_config, State};
#[async_std::main]
async fn main() -> tide::Result<()> {
@ -39,104 +23,6 @@ async fn main() -> tide::Result<()> {
Ok(())
}
#[derive(Debug, Clone)]
struct Config {
ldap_host: String,
database: String,
host_port: String,
}
fn get_config() -> Config {
dotenv().ok();
// reasonable defaults
let mut config = Config {
ldap_host: "".to_string(),
database: "database.db".to_string(),
host_port: "127.0.0.1:8087".to_string(),
};
if let Ok(x) = env::var("LDAP_HOST") {
config.ldap_host = x.trim().to_string();
}
if let Ok(x) = env::var("DATABASE") {
config.database = x.trim().to_string();
}
if let Ok(x) = env::var("HOST_PORT") {
config.host_port = x.trim().to_string();
}
config
}
#[derive(Debug, Deserialize)]
struct LdapUpdate {
user: String,
pass: String,
field: String,
value: String,
}
async fn post_update_ldap(mut req: Request<State>) -> tide::Result {
let LdapUpdate {
user,
pass,
field,
value,
} = req.body_json().await?;
let config = &req.state().config;
// easier to give each request its own connection
let mut ldap = LdapConn::new(&config.ldap_host)?;
let dn = format!("uid={},ou=users,dc=skynet,dc=ie", user);
ldap.simple_bind(&dn, &pass)?.success()?;
// always assume insecure
let mut pw_keep_same = false;
// get the users current password hash
let (rs, _res) = ldap.search(&dn, Scope::Base, "(objectClass=*)", vec!["userPassword"])?.success()?;
if !rs.is_empty() {
let tmp = SearchEntry::construct(rs[0].clone());
if !tmp.attrs["userPassword"].is_empty() && tmp.attrs["userPassword"][0].starts_with("{SSHA512}") {
pw_keep_same = true;
}
}
// check if the password field itself is being updated
let (pass_old, pass_new) = if &field != "userPassword" {
// if password is not being updated then just update the required field
let mods = vec![Mod::Replace(field, HashSet::from([value]))];
ldap.modify(&dn, mods)?.success()?;
// pass back the "old" and "new" passwords
(pass.clone(), pass.clone())
} else {
// password is going to be updated, even if the old value is not starting with "{SSHA512}"
pw_keep_same = false;
(pass.clone(), value)
};
if !pw_keep_same {
// really easy to update password once ye know how
let tmp = PasswordModify {
// none as we are staying on the same connection
user_id: None,
old_pass: Some(&pass_old),
new_pass: Some(&pass_new),
};
ldap.extended(tmp)?.success()?;
};
ldap.unbind()?;
Ok(json!({"result": "success"}).into())
}
/* Create new account

View file

@ -0,0 +1,75 @@
use crate::State;
use ldap3::exop::PasswordModify;
use ldap3::{LdapConn, Mod, Scope, SearchEntry};
use std::collections::HashSet;
use tide::prelude::{json, Deserialize};
use tide::Request;
#[derive(Debug, Deserialize)]
pub struct LdapUpdate {
user: String,
pass: String,
field: String,
value: String,
}
pub async fn post_update_ldap(mut req: Request<State>) -> tide::Result {
let LdapUpdate {
user,
pass,
field,
value,
} = req.body_json().await?;
let config = &req.state().config;
// easier to give each request its own connection
let mut ldap = LdapConn::new(&config.ldap_host)?;
let dn = format!("uid={},ou=users,dc=skynet,dc=ie", user);
ldap.simple_bind(&dn, &pass)?.success()?;
// always assume insecure
let mut pw_keep_same = false;
// get the users current password hash
let (rs, _res) = ldap.search(&dn, Scope::Base, "(objectClass=*)", vec!["userPassword"])?.success()?;
if !rs.is_empty() {
let tmp = SearchEntry::construct(rs[0].clone());
if !tmp.attrs["userPassword"].is_empty() && tmp.attrs["userPassword"][0].starts_with("{SSHA512}") {
pw_keep_same = true;
}
}
// check if the password field itself is being updated
let (pass_old, pass_new) = if &field != "userPassword" {
// if password is not being updated then just update the required field
let mods = vec![Mod::Replace(field, HashSet::from([value]))];
ldap.modify(&dn, mods)?.success()?;
// pass back the "old" and "new" passwords
(pass.clone(), pass.clone())
} else {
// password is going to be updated, even if the old value is not starting with "{SSHA512}"
pw_keep_same = false;
(pass.clone(), value)
};
if !pw_keep_same {
// really easy to update password once ye know how
let tmp = PasswordModify {
// none as we are staying on the same connection
user_id: None,
old_pass: Some(&pass_old),
new_pass: Some(&pass_new),
};
ldap.extended(tmp)?.success()?;
};
ldap.unbind()?;
Ok(json!({"result": "success"}).into())
}

1
src/methods/mod.rs Normal file
View file

@ -0,0 +1 @@
pub mod change_details;