From 893388d555839d079d2aa3d687c5c7254f5d3e6e Mon Sep 17 00:00:00 2001 From: Schuhmacher Date: Mon, 7 Apr 2025 10:56:19 +0200 Subject: [PATCH] ldap tests --- crates/ldap/src/ldap.rs | 21 +++++++++++-------- crates/ldap/src/lib.rs | 45 +++++++++++++++++++++++++++++++++++++++++ crates/ldap/src/main.rs | 37 +++++++++++++++++++++++++++++++++ 3 files changed, 95 insertions(+), 8 deletions(-) create mode 100644 crates/ldap/src/main.rs diff --git a/crates/ldap/src/ldap.rs b/crates/ldap/src/ldap.rs index de0b418..2b6c914 100644 --- a/crates/ldap/src/ldap.rs +++ b/crates/ldap/src/ldap.rs @@ -13,21 +13,26 @@ struct LoginRequest { // HTTP POST endpoint for user login #[post("/login")] async fn login(credentials: web::Json) -> impl Responder { + // Get LDAP server and base DN from environment variables or use defaults + let ldap_server = env::var("LDAP_SERVER").unwrap_or("ldap://127.0.0.1:389".to_string()); + let base_dn = env::var("LDAP_BASE_DN").unwrap_or("dc=schule,dc=local".to_string()); + // Authenticate user and return appropriate response - match authenticate_user(&credentials.username, &credentials.password) { + match authenticate_user(&ldap_server, &base_dn, &credentials.username, &credentials.password) { Ok(true) => HttpResponse::Ok().body("Login erfolgreich"), // Login successful _ => HttpResponse::Unauthorized().body("Login fehlgeschlagen"), // Login failed } } // Function to authenticate user against LDAP server -fn authenticate_user(username: &str, password: &str) -> Result> { - // Get LDAP server and base DN from environment variables or use defaults - let ldap_server = env::var("LDAP_SERVER").unwrap_or("ldap://127.0.0.1:389".to_string()); - let base_dn = env::var("LDAP_BASE_DN").unwrap_or("dc=schule,dc=local".to_string()); - +fn authenticate_user( + ldap_server: &str, + base_dn: &str, + username: &str, + password: &str, +) -> Result> { // Establish connection to LDAP server - let ldap = LdapConn::new(&ldap_server)?; + let ldap = LdapConn::new(ldap_server)?; // Search for the user in the LDAP directory let (rs, _res) = ldap @@ -44,7 +49,7 @@ fn authenticate_user(username: &str, password: &str) -> Result Result> { + // Establish connection to LDAP server + let ldap = LdapConn::new(ldap_server)?; + + // Search for the user in the LDAP directory + let (rs, _res) = ldap + .search( + &format!("ou=users,{}", base_dn), // Search under "ou=users" + Scope::Subtree, // Search all levels + &format!("(uid={})", username), // Filter by username + vec!["dn"], // Retrieve the distinguished name (DN) + )? + .success()?; + + // If user is found, attempt to authenticate with their DN and password + if let Some(entry) = rs.into_iter().next() { + let user_dn = SearchEntry::construct(entry).dn; // Extract user DN + + // Reconnect and bind with user credentials + let user_ldap = LdapConn::new(ldap_server)?; + let auth_result = user_ldap.simple_bind(&user_dn, password)?.success(); + return Ok(auth_result.is_ok()); // Return true if authentication succeeds + } + + Ok(false) // Return false if user is not found +} diff --git a/crates/ldap/src/main.rs b/crates/ldap/src/main.rs new file mode 100644 index 0000000..24c61b3 --- /dev/null +++ b/crates/ldap/src/main.rs @@ -0,0 +1,37 @@ +use actix_web::{post, web, App, HttpResponse, HttpServer, Responder}; +use serde::Deserialize; +use ldap::authenticate_user; // Import the library function +use std::env; + +// Struct to deserialize login request payload +#[derive(Deserialize)] +struct LoginRequest { + username: String, + password: String, +} + +// HTTP POST endpoint for user login +#[post("/login")] +async fn login(credentials: web::Json) -> impl Responder { + // Get LDAP server and base DN from environment variables or use defaults + let ldap_server = env::var("LDAP_SERVER").unwrap_or("ldap://127.0.0.1:389".to_string()); + let base_dn = env::var("LDAP_BASE_DN").unwrap_or("dc=schule,dc=local".to_string()); + + // Authenticate user and return appropriate response + match authenticate_user(&ldap_server, &base_dn, &credentials.username, &credentials.password) { + Ok(true) => HttpResponse::Ok().body("Login erfolgreich"), // Login successful + _ => HttpResponse::Unauthorized().body("Login fehlgeschlagen"), // Login failed + } +} + +// Main function to start the Actix Web server +#[actix_web::main] +async fn main() -> std::io::Result<()> { + env_logger::init(); // Initialize logger + + // Start HTTP server and bind to localhost:8080 + HttpServer::new(|| App::new().service(login)) + .bind(("127.0.0.1", 8080))? + .run() + .await +}