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