mirror of
				https://github.com/nitnelave/lldap.git
				synced 2023-04-12 14:25:13 +00:00 
			
		
		
		
	Add tests to the handler
This commit is contained in:
		
							parent
							
								
									81593c9f84
								
							
						
					
					
						commit
						f198638f99
					
				@ -28,7 +28,7 @@ tracing-actix-web = "0.3.0-beta.2"
 | 
				
			|||||||
tracing-log = "*"
 | 
					tracing-log = "*"
 | 
				
			||||||
tracing-subscriber = "*"
 | 
					tracing-subscriber = "*"
 | 
				
			||||||
async-trait = "0.1.48"
 | 
					async-trait = "0.1.48"
 | 
				
			||||||
sea-query = "0.9.2"
 | 
					sea-query = { version = "0.9.2", features = [ "with-chrono" ] }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[dependencies.figment]
 | 
					[dependencies.figment]
 | 
				
			||||||
features = ["toml", "env"]
 | 
					features = ["toml", "env"]
 | 
				
			||||||
 | 
				
			|||||||
@ -1,11 +1,12 @@
 | 
				
			|||||||
use super::sql_tables::*;
 | 
					use super::sql_tables::*;
 | 
				
			||||||
 | 
					use crate::domain::sql_tables::Pool;
 | 
				
			||||||
use crate::infra::configuration::Configuration;
 | 
					use crate::infra::configuration::Configuration;
 | 
				
			||||||
use anyhow::{bail, Result};
 | 
					use anyhow::{bail, Result};
 | 
				
			||||||
use async_trait::async_trait;
 | 
					use async_trait::async_trait;
 | 
				
			||||||
use futures_util::StreamExt;
 | 
					use futures_util::StreamExt;
 | 
				
			||||||
use sea_query::{Expr, SqliteQueryBuilder, Query, SimpleExpr};
 | 
					use log::*;
 | 
				
			||||||
 | 
					use sea_query::{Expr, Order, Query, SimpleExpr, SqliteQueryBuilder};
 | 
				
			||||||
use sqlx::Row;
 | 
					use sqlx::Row;
 | 
				
			||||||
use crate::domain::sql_tables::Pool;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[cfg_attr(test, derive(PartialEq, Eq, Debug))]
 | 
					#[cfg_attr(test, derive(PartialEq, Eq, Debug))]
 | 
				
			||||||
pub struct BindRequest {
 | 
					pub struct BindRequest {
 | 
				
			||||||
@ -100,7 +101,11 @@ impl BackendHandler for SqlBackendHandler {
 | 
				
			|||||||
        if let Ok(row) = sqlx::query(&query).fetch_one(&self.sql_pool).await {
 | 
					        if let Ok(row) = sqlx::query(&query).fetch_one(&self.sql_pool).await {
 | 
				
			||||||
            if passwords_match(&request.password, &row.get::<String, _>("password")) {
 | 
					            if passwords_match(&request.password, &row.get::<String, _>("password")) {
 | 
				
			||||||
                return Ok(());
 | 
					                return Ok(());
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                debug!(r#"Invalid password for "{}""#, request.name);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            debug!(r#"No user found for "{}""#, request.name);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        bail!(r#"Authentication error for "{}""#, request.name)
 | 
					        bail!(r#"Authentication error for "{}""#, request.name)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -116,6 +121,7 @@ impl BackendHandler for SqlBackendHandler {
 | 
				
			|||||||
                .column(Users::Avatar)
 | 
					                .column(Users::Avatar)
 | 
				
			||||||
                .column(Users::CreationDate)
 | 
					                .column(Users::CreationDate)
 | 
				
			||||||
                .from(Users::Table)
 | 
					                .from(Users::Table)
 | 
				
			||||||
 | 
					                .order_by(Users::UserId, Order::Asc)
 | 
				
			||||||
                .to_owned();
 | 
					                .to_owned();
 | 
				
			||||||
            if let Some(filter) = request.filters {
 | 
					            if let Some(filter) = request.filters {
 | 
				
			||||||
                if filter != RequestFilter::And(Vec::new())
 | 
					                if filter != RequestFilter::And(Vec::new())
 | 
				
			||||||
@ -153,24 +159,162 @@ mockall::mock! {
 | 
				
			|||||||
#[cfg(test)]
 | 
					#[cfg(test)]
 | 
				
			||||||
mod tests {
 | 
					mod tests {
 | 
				
			||||||
    use super::*;
 | 
					    use super::*;
 | 
				
			||||||
 | 
					    use crate::domain::sql_tables::init_table;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    async fn get_in_memory_db() -> Pool {
 | 
				
			||||||
 | 
					        PoolOptions::new().connect("sqlite::memory:").await.unwrap()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    async fn get_initialized_db() -> Pool {
 | 
				
			||||||
 | 
					        let sql_pool = get_in_memory_db().await;
 | 
				
			||||||
 | 
					        init_table(&sql_pool).await.unwrap();
 | 
				
			||||||
 | 
					        sql_pool
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    async fn insert_user(sql_pool: &Pool, name: &str, pass: &str) {
 | 
				
			||||||
 | 
					        /*
 | 
				
			||||||
 | 
					        let query = Query::insert()
 | 
				
			||||||
 | 
					            .into_table(Users::Table)
 | 
				
			||||||
 | 
					            .columns(vec![
 | 
				
			||||||
 | 
					                Users::UserId,
 | 
				
			||||||
 | 
					                Users::Email,
 | 
				
			||||||
 | 
					                Users::DisplayName,
 | 
				
			||||||
 | 
					                Users::FirstName,
 | 
				
			||||||
 | 
					                Users::LastName,
 | 
				
			||||||
 | 
					                Users::CreationDate,
 | 
				
			||||||
 | 
					                Users::Password,
 | 
				
			||||||
 | 
					            ])
 | 
				
			||||||
 | 
					            .values_panic(vec![
 | 
				
			||||||
 | 
					                "bob".into(),
 | 
				
			||||||
 | 
					                "bob@bob".into(),
 | 
				
			||||||
 | 
					                "Bob Böbberson".into(),
 | 
				
			||||||
 | 
					                "Bob".into(),
 | 
				
			||||||
 | 
					                "Böbberson".into(),
 | 
				
			||||||
 | 
					                chrono::NaiveDateTime::from_timestamp(0, 0).into(),
 | 
				
			||||||
 | 
					                "bob00".into(),
 | 
				
			||||||
 | 
					            ])
 | 
				
			||||||
 | 
					            .to_string(SqliteQueryBuilder);
 | 
				
			||||||
 | 
					        sqlx::query(&query).execute(&sql_pool).await.unwrap();
 | 
				
			||||||
 | 
					        */
 | 
				
			||||||
 | 
					        sqlx::query(
 | 
				
			||||||
 | 
					            r#"INSERT INTO users
 | 
				
			||||||
 | 
					      (user_id, email, display_name, first_name, last_name, creation_date, password)
 | 
				
			||||||
 | 
					      VALUES (?, "em@ai.l", "Display Name", "Firstname", "Lastname", "1970-01-01 00:00:00", ?)"#,
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        .bind(name.to_string())
 | 
				
			||||||
 | 
					        .bind(pass.to_string())
 | 
				
			||||||
 | 
					        .execute(sql_pool)
 | 
				
			||||||
 | 
					        .await
 | 
				
			||||||
 | 
					        .unwrap();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #[tokio::test]
 | 
					    #[tokio::test]
 | 
				
			||||||
    async fn test_bind_admin() {
 | 
					    async fn test_bind_admin() {
 | 
				
			||||||
        let sql_pool = PoolOptions::new()
 | 
					        let sql_pool = get_in_memory_db().await;
 | 
				
			||||||
            .connect("sqlite::memory:")
 | 
					 | 
				
			||||||
            .await
 | 
					 | 
				
			||||||
            .unwrap();
 | 
					 | 
				
			||||||
        let mut config = Configuration::default();
 | 
					        let mut config = Configuration::default();
 | 
				
			||||||
        config.ldap_user_dn = "admin".to_string();
 | 
					        config.ldap_user_dn = "admin".to_string();
 | 
				
			||||||
        config.ldap_user_pass = "test".to_string();
 | 
					        config.ldap_user_pass = "test".to_string();
 | 
				
			||||||
        let handler = SqlBackendHandler::new(config, sql_pool);
 | 
					        let handler = SqlBackendHandler::new(config, sql_pool);
 | 
				
			||||||
        assert!(true);
 | 
					        handler
 | 
				
			||||||
        assert!(handler
 | 
					 | 
				
			||||||
            .bind(BindRequest {
 | 
					            .bind(BindRequest {
 | 
				
			||||||
                name: "admin".to_string(),
 | 
					                name: "admin".to_string(),
 | 
				
			||||||
                password: "test".to_string()
 | 
					                password: "test".to_string(),
 | 
				
			||||||
            })
 | 
					            })
 | 
				
			||||||
            .await
 | 
					            .await
 | 
				
			||||||
            .is_ok());
 | 
					            .unwrap();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #[tokio::test]
 | 
				
			||||||
 | 
					    async fn test_bind_user() {
 | 
				
			||||||
 | 
					        let sql_pool = get_initialized_db().await;
 | 
				
			||||||
 | 
					        insert_user(&sql_pool, "bob", "bob00").await;
 | 
				
			||||||
 | 
					        let config = Configuration::default();
 | 
				
			||||||
 | 
					        let handler = SqlBackendHandler::new(config, sql_pool);
 | 
				
			||||||
 | 
					        handler
 | 
				
			||||||
 | 
					            .bind(BindRequest {
 | 
				
			||||||
 | 
					                name: "bob".to_string(),
 | 
				
			||||||
 | 
					                password: "bob00".to_string(),
 | 
				
			||||||
 | 
					            })
 | 
				
			||||||
 | 
					            .await
 | 
				
			||||||
 | 
					            .unwrap();
 | 
				
			||||||
 | 
					        handler
 | 
				
			||||||
 | 
					            .bind(BindRequest {
 | 
				
			||||||
 | 
					                name: "andrew".to_string(),
 | 
				
			||||||
 | 
					                password: "bob00".to_string(),
 | 
				
			||||||
 | 
					            })
 | 
				
			||||||
 | 
					            .await
 | 
				
			||||||
 | 
					            .unwrap_err();
 | 
				
			||||||
 | 
					        handler
 | 
				
			||||||
 | 
					            .bind(BindRequest {
 | 
				
			||||||
 | 
					                name: "bob".to_string(),
 | 
				
			||||||
 | 
					                password: "wrong_password".to_string(),
 | 
				
			||||||
 | 
					            })
 | 
				
			||||||
 | 
					            .await
 | 
				
			||||||
 | 
					            .unwrap_err();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #[tokio::test]
 | 
				
			||||||
 | 
					    async fn test_list_users() {
 | 
				
			||||||
 | 
					        let sql_pool = get_initialized_db().await;
 | 
				
			||||||
 | 
					        insert_user(&sql_pool, "bob", "bob00").await;
 | 
				
			||||||
 | 
					        insert_user(&sql_pool, "patrick", "pass").await;
 | 
				
			||||||
 | 
					        insert_user(&sql_pool, "John", "Pa33w0rd!").await;
 | 
				
			||||||
 | 
					        let config = Configuration::default();
 | 
				
			||||||
 | 
					        let handler = SqlBackendHandler::new(config, sql_pool);
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            let users = handler
 | 
				
			||||||
 | 
					                .list_users(ListUsersRequest { filters: None })
 | 
				
			||||||
 | 
					                .await
 | 
				
			||||||
 | 
					                .unwrap()
 | 
				
			||||||
 | 
					                .into_iter()
 | 
				
			||||||
 | 
					                .map(|u| u.user_id)
 | 
				
			||||||
 | 
					                .collect::<Vec<_>>();
 | 
				
			||||||
 | 
					            assert_eq!(users, vec!["John", "bob", "patrick"]);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            let users = handler
 | 
				
			||||||
 | 
					                .list_users(ListUsersRequest {
 | 
				
			||||||
 | 
					                    filters: Some(RequestFilter::Equality(
 | 
				
			||||||
 | 
					                        "user_id".to_string(),
 | 
				
			||||||
 | 
					                        "bob".to_string(),
 | 
				
			||||||
 | 
					                    )),
 | 
				
			||||||
 | 
					                })
 | 
				
			||||||
 | 
					                .await
 | 
				
			||||||
 | 
					                .unwrap()
 | 
				
			||||||
 | 
					                .into_iter()
 | 
				
			||||||
 | 
					                .map(|u| u.user_id)
 | 
				
			||||||
 | 
					                .collect::<Vec<_>>();
 | 
				
			||||||
 | 
					            assert_eq!(users, vec!["bob"]);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            let users = handler
 | 
				
			||||||
 | 
					                .list_users(ListUsersRequest {
 | 
				
			||||||
 | 
					                    filters: Some(RequestFilter::Or(vec![
 | 
				
			||||||
 | 
					                        RequestFilter::Equality("user_id".to_string(), "bob".to_string()),
 | 
				
			||||||
 | 
					                        RequestFilter::Equality("user_id".to_string(), "John".to_string()),
 | 
				
			||||||
 | 
					                    ])),
 | 
				
			||||||
 | 
					                })
 | 
				
			||||||
 | 
					                .await
 | 
				
			||||||
 | 
					                .unwrap()
 | 
				
			||||||
 | 
					                .into_iter()
 | 
				
			||||||
 | 
					                .map(|u| u.user_id)
 | 
				
			||||||
 | 
					                .collect::<Vec<_>>();
 | 
				
			||||||
 | 
					            assert_eq!(users, vec!["John", "bob"]);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            let users = handler
 | 
				
			||||||
 | 
					                .list_users(ListUsersRequest {
 | 
				
			||||||
 | 
					                    filters: Some(RequestFilter::Not(Box::new(RequestFilter::Equality(
 | 
				
			||||||
 | 
					                        "user_id".to_string(),
 | 
				
			||||||
 | 
					                        "bob".to_string(),
 | 
				
			||||||
 | 
					                    )))),
 | 
				
			||||||
 | 
					                })
 | 
				
			||||||
 | 
					                .await
 | 
				
			||||||
 | 
					                .unwrap()
 | 
				
			||||||
 | 
					                .into_iter()
 | 
				
			||||||
 | 
					                .map(|u| u.user_id)
 | 
				
			||||||
 | 
					                .collect::<Vec<_>>();
 | 
				
			||||||
 | 
					            assert_eq!(users, vec!["John", "patrick"]);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,3 +1,4 @@
 | 
				
			|||||||
 | 
					use chrono::NaiveDateTime;
 | 
				
			||||||
use sea_query::*;
 | 
					use sea_query::*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub type Pool = sqlx::sqlite::SqlitePool;
 | 
					pub type Pool = sqlx::sqlite::SqlitePool;
 | 
				
			||||||
@ -92,11 +93,7 @@ pub async fn init_table(pool: &Pool) -> sqlx::Result<()> {
 | 
				
			|||||||
                    .not_null()
 | 
					                    .not_null()
 | 
				
			||||||
                    .primary_key(),
 | 
					                    .primary_key(),
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
            .col(
 | 
					            .col(ColumnDef::new(Memberships::GroupId).integer().not_null())
 | 
				
			||||||
                ColumnDef::new(Memberships::GroupId)
 | 
					 | 
				
			||||||
                    .integer()
 | 
					 | 
				
			||||||
                    .not_null(),
 | 
					 | 
				
			||||||
            )
 | 
					 | 
				
			||||||
            .foreign_key(
 | 
					            .foreign_key(
 | 
				
			||||||
                ForeignKey::create()
 | 
					                ForeignKey::create()
 | 
				
			||||||
                    .name("MembershipUserForeignKey")
 | 
					                    .name("MembershipUserForeignKey")
 | 
				
			||||||
@ -128,28 +125,27 @@ mod tests {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    #[actix_rt::test]
 | 
					    #[actix_rt::test]
 | 
				
			||||||
    async fn test_init_table() {
 | 
					    async fn test_init_table() {
 | 
				
			||||||
        let sql_pool = PoolOptions::new()
 | 
					        let sql_pool = PoolOptions::new().connect("sqlite::memory:").await.unwrap();
 | 
				
			||||||
            .connect("sqlite::memory:")
 | 
					 | 
				
			||||||
            .await
 | 
					 | 
				
			||||||
            .unwrap();
 | 
					 | 
				
			||||||
        init_table(&sql_pool).await.unwrap();
 | 
					        init_table(&sql_pool).await.unwrap();
 | 
				
			||||||
        sqlx::query(r#"INSERT INTO users
 | 
					        sqlx::query(r#"INSERT INTO users
 | 
				
			||||||
      (user_id, email, display_name, first_name, last_name, creation_date, password)
 | 
					      (user_id, email, display_name, first_name, last_name, creation_date, password)
 | 
				
			||||||
      VALUES ("bôb", "böb@bob.bob", "Bob Bobbersön", "Bob", "Bobberson", CURRENT_TIMESTAMP, "bob00")"#).execute(&sql_pool).await.unwrap();
 | 
					      VALUES ("bôb", "böb@bob.bob", "Bob Bobbersön", "Bob", "Bobberson", "1970-01-01 00:00:00", "bob00")"#).execute(&sql_pool).await.unwrap();
 | 
				
			||||||
        let row = sqlx::query(r#"SELECT display_name FROM users WHERE user_id = "bôb""#)
 | 
					        let row =
 | 
				
			||||||
 | 
					            sqlx::query(r#"SELECT display_name, creation_date FROM users WHERE user_id = "bôb""#)
 | 
				
			||||||
                .fetch_one(&sql_pool)
 | 
					                .fetch_one(&sql_pool)
 | 
				
			||||||
                .await
 | 
					                .await
 | 
				
			||||||
                .unwrap();
 | 
					                .unwrap();
 | 
				
			||||||
        assert_eq!(row.column(0).name(), "display_name");
 | 
					        assert_eq!(row.column(0).name(), "display_name");
 | 
				
			||||||
        assert_eq!(row.get::<String, _>("display_name"), "Bob Bobbersön");
 | 
					        assert_eq!(row.get::<String, _>("display_name"), "Bob Bobbersön");
 | 
				
			||||||
 | 
					        assert_eq!(
 | 
				
			||||||
 | 
					            row.get::<NaiveDateTime, _>("creation_date"),
 | 
				
			||||||
 | 
					            NaiveDateTime::from_timestamp(0, 0)
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #[actix_rt::test]
 | 
					    #[actix_rt::test]
 | 
				
			||||||
    async fn test_already_init_table() {
 | 
					    async fn test_already_init_table() {
 | 
				
			||||||
        let sql_pool = PoolOptions::new()
 | 
					        let sql_pool = PoolOptions::new().connect("sqlite::memory:").await.unwrap();
 | 
				
			||||||
            .connect("sqlite::memory:")
 | 
					 | 
				
			||||||
            .await
 | 
					 | 
				
			||||||
            .unwrap();
 | 
					 | 
				
			||||||
        init_table(&sql_pool).await.unwrap();
 | 
					        init_table(&sql_pool).await.unwrap();
 | 
				
			||||||
        init_table(&sql_pool).await.unwrap();
 | 
					        init_table(&sql_pool).await.unwrap();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -1,8 +1,8 @@
 | 
				
			|||||||
 | 
					use crate::domain::sql_tables::PoolOptions;
 | 
				
			||||||
use crate::infra::configuration::Configuration;
 | 
					use crate::infra::configuration::Configuration;
 | 
				
			||||||
use anyhow::Result;
 | 
					use anyhow::Result;
 | 
				
			||||||
use futures_util::TryFutureExt;
 | 
					use futures_util::TryFutureExt;
 | 
				
			||||||
use log::*;
 | 
					use log::*;
 | 
				
			||||||
use crate::domain::sql_tables::PoolOptions;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
mod domain;
 | 
					mod domain;
 | 
				
			||||||
mod infra;
 | 
					mod infra;
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user