mirror of
https://github.com/nitnelave/lldap.git
synced 2023-04-12 14:25:13 +00:00
Reorganize and tidy up
This commit is contained in:
parent
f989cd52ec
commit
4af242c798
29
Cargo.lock
generated
29
Cargo.lock
generated
@ -2323,7 +2323,7 @@ dependencies = [
|
|||||||
"peg",
|
"peg",
|
||||||
"tokio-util",
|
"tokio-util",
|
||||||
"tracing",
|
"tracing",
|
||||||
"uuid 1.3.0",
|
"uuid 1.3.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -2463,7 +2463,7 @@ dependencies = [
|
|||||||
"tracing-forest",
|
"tracing-forest",
|
||||||
"tracing-log",
|
"tracing-log",
|
||||||
"tracing-subscriber",
|
"tracing-subscriber",
|
||||||
"uuid 1.3.0",
|
"uuid 0.8.2",
|
||||||
"webpki-roots",
|
"webpki-roots",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -2589,6 +2589,12 @@ dependencies = [
|
|||||||
"digest 0.10.6",
|
"digest 0.10.6",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "md5"
|
||||||
|
version = "0.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "memchr"
|
name = "memchr"
|
||||||
version = "2.5.0"
|
version = "2.5.0"
|
||||||
@ -3557,7 +3563,7 @@ dependencies = [
|
|||||||
"thiserror",
|
"thiserror",
|
||||||
"tracing",
|
"tracing",
|
||||||
"url",
|
"url",
|
||||||
"uuid 1.3.0",
|
"uuid 1.3.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -3581,7 +3587,7 @@ checksum = "d2fbe015dbdaa7d8829d71c1e14fb6289e928ac256b93dfda543c85cd89d6f03"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"sea-query-derive",
|
"sea-query-derive",
|
||||||
"uuid 1.3.0",
|
"uuid 1.3.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -3593,7 +3599,7 @@ dependencies = [
|
|||||||
"chrono",
|
"chrono",
|
||||||
"sea-query",
|
"sea-query",
|
||||||
"sqlx",
|
"sqlx",
|
||||||
"uuid 1.3.0",
|
"uuid 1.3.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -3977,7 +3983,7 @@ dependencies = [
|
|||||||
"thiserror",
|
"thiserror",
|
||||||
"tokio-stream",
|
"tokio-stream",
|
||||||
"url",
|
"url",
|
||||||
"uuid 1.3.0",
|
"uuid 1.3.1",
|
||||||
"webpki-roots",
|
"webpki-roots",
|
||||||
"whoami",
|
"whoami",
|
||||||
]
|
]
|
||||||
@ -4300,7 +4306,7 @@ dependencies = [
|
|||||||
"actix-web",
|
"actix-web",
|
||||||
"pin-project",
|
"pin-project",
|
||||||
"tracing",
|
"tracing",
|
||||||
"uuid 1.3.0",
|
"uuid 1.3.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -4498,15 +4504,18 @@ name = "uuid"
|
|||||||
version = "0.8.2"
|
version = "0.8.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7"
|
checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7"
|
||||||
|
dependencies = [
|
||||||
|
"getrandom 0.2.8",
|
||||||
|
"md5",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "uuid"
|
name = "uuid"
|
||||||
version = "1.3.0"
|
version = "1.3.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1674845326ee10d37ca60470760d4288a6f80f304007d92e5c53bab78c9cfd79"
|
checksum = "5b55a3fef2a1e3b3a00ce878640918820d3c51081576ac657d23af9fc7928fdb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"getrandom 0.2.8",
|
"getrandom 0.2.8",
|
||||||
"md-5",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -143,3 +143,7 @@ version = "0.11"
|
|||||||
version = "*"
|
version = "*"
|
||||||
default-features = false
|
default-features = false
|
||||||
features = ["json", "blocking", "rustls-tls"]
|
features = ["json", "blocking", "rustls-tls"]
|
||||||
|
|
||||||
|
[dev-dependencies.uuid]
|
||||||
|
version = "*"
|
||||||
|
features = ["v4"]
|
27
server/tests/common/auth.rs
Normal file
27
server/tests/common/auth.rs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
use crate::common::env;
|
||||||
|
use reqwest::blocking::Client;
|
||||||
|
|
||||||
|
pub fn get_token(client: &Client) -> String {
|
||||||
|
let username = env::admin_dn();
|
||||||
|
let password = env::admin_password();
|
||||||
|
let base_url = env::http_url();
|
||||||
|
let response = client
|
||||||
|
.post(format!("{base_url}/auth/simple/login"))
|
||||||
|
.header(reqwest::header::CONTENT_TYPE, "application/json")
|
||||||
|
.body(
|
||||||
|
serde_json::to_string(&lldap_auth::login::ClientSimpleLoginRequest {
|
||||||
|
username: username,
|
||||||
|
password: password,
|
||||||
|
})
|
||||||
|
.expect("Failed to encode the username/password as json to log in"),
|
||||||
|
)
|
||||||
|
.send()
|
||||||
|
.expect("Failed to send auth request")
|
||||||
|
.error_for_status()
|
||||||
|
.expect("Auth attempt failed");
|
||||||
|
serde_json::from_str::<lldap_auth::login::ServerLoginResponse>(
|
||||||
|
&response.text().expect("Failed to get response as text"),
|
||||||
|
)
|
||||||
|
.expect("Failed to parse json")
|
||||||
|
.token
|
||||||
|
}
|
43
server/tests/common/env.rs
Normal file
43
server/tests/common/env.rs
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
use std::env::var;
|
||||||
|
|
||||||
|
pub const DB_KEY: &str = "LLDAP_DATABASE_URL";
|
||||||
|
|
||||||
|
pub fn database_url() -> String {
|
||||||
|
let url = var(DB_KEY).ok();
|
||||||
|
let url = url.unwrap_or("sqlite://e2e_test.db?mode=rwc".to_string());
|
||||||
|
url.to_string()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn ldap_url() -> String {
|
||||||
|
let port = var("LLDAP_LDAP_PORT").ok();
|
||||||
|
let port = port.unwrap_or("3890".to_string());
|
||||||
|
let mut url = String::from("ldap://localhost:");
|
||||||
|
url += &port;
|
||||||
|
url
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn http_url() -> String {
|
||||||
|
let port = var("LLDAP_HTTP_PORT").ok();
|
||||||
|
let port = port.unwrap_or("17170".to_string());
|
||||||
|
let mut url = String::from("http://localhost:");
|
||||||
|
url += &port;
|
||||||
|
url
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn admin_dn() -> String {
|
||||||
|
let user = var("LLDAP_LDAP_USER_DN").ok();
|
||||||
|
let user = user.unwrap_or("admin".to_string());
|
||||||
|
user.to_string()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn admin_password() -> String {
|
||||||
|
let pass = var("LLDAP_LDAP_USER_PASS").ok();
|
||||||
|
let pass = pass.unwrap_or("password".to_string());
|
||||||
|
pass.to_string()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn base_dn() -> String {
|
||||||
|
let dn = var("LLDAP_LDAP_BASE_DN").ok();
|
||||||
|
let dn = dn.unwrap_or("dc=example,dc=com".to_string());
|
||||||
|
dn.to_string()
|
||||||
|
}
|
@ -1,78 +1,12 @@
|
|||||||
use anyhow::{anyhow, bail, Context, Result};
|
use crate::common::auth::get_token;
|
||||||
|
use crate::common::env;
|
||||||
|
use crate::common::graphql::*;
|
||||||
use assert_cmd::prelude::*;
|
use assert_cmd::prelude::*;
|
||||||
use graphql_client::GraphQLQuery;
|
|
||||||
use reqwest::blocking::{Client, ClientBuilder};
|
use reqwest::blocking::{Client, ClientBuilder};
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::{HashMap, HashSet};
|
||||||
use std::process::{Child, Command};
|
use std::process::{Child, Command};
|
||||||
use std::{env::var, fs::canonicalize, thread, time::Duration};
|
use std::{fs::canonicalize, thread, time::Duration};
|
||||||
|
use uuid::Uuid;
|
||||||
const DB_KEY: &str = "LLDAP_DATABASE_URL";
|
|
||||||
|
|
||||||
#[derive(GraphQLQuery)]
|
|
||||||
#[graphql(
|
|
||||||
schema_path = "../schema.graphql",
|
|
||||||
query_path = "tests/queries/add_user_to_group.graphql",
|
|
||||||
response_derives = "Debug",
|
|
||||||
variables_derives = "Debug,Clone",
|
|
||||||
custom_scalars_module = "crate::infra::graphql"
|
|
||||||
)]
|
|
||||||
struct AddUserToGroup;
|
|
||||||
|
|
||||||
#[derive(GraphQLQuery)]
|
|
||||||
#[graphql(
|
|
||||||
schema_path = "../schema.graphql",
|
|
||||||
query_path = "tests/queries/create_user.graphql",
|
|
||||||
response_derives = "Debug",
|
|
||||||
variables_derives = "Debug,Clone",
|
|
||||||
custom_scalars_module = "crate::infra::graphql"
|
|
||||||
)]
|
|
||||||
struct CreateUser;
|
|
||||||
|
|
||||||
#[derive(GraphQLQuery)]
|
|
||||||
#[graphql(
|
|
||||||
schema_path = "../schema.graphql",
|
|
||||||
query_path = "tests/queries/create_group.graphql",
|
|
||||||
response_derives = "Debug",
|
|
||||||
variables_derives = "Debug,Clone",
|
|
||||||
custom_scalars_module = "crate::infra::graphql"
|
|
||||||
)]
|
|
||||||
struct CreateGroup;
|
|
||||||
|
|
||||||
#[derive(GraphQLQuery)]
|
|
||||||
#[graphql(
|
|
||||||
schema_path = "../schema.graphql",
|
|
||||||
query_path = "tests/queries/list_users.graphql",
|
|
||||||
response_derives = "Debug",
|
|
||||||
custom_scalars_module = "crate::infra::graphql"
|
|
||||||
)]
|
|
||||||
pub struct ListUsers;
|
|
||||||
|
|
||||||
#[derive(GraphQLQuery)]
|
|
||||||
#[graphql(
|
|
||||||
schema_path = "../schema.graphql",
|
|
||||||
query_path = "tests/queries/list_groups.graphql",
|
|
||||||
response_derives = "Debug",
|
|
||||||
custom_scalars_module = "crate::infra::graphql"
|
|
||||||
)]
|
|
||||||
struct ListGroups;
|
|
||||||
|
|
||||||
#[derive(GraphQLQuery)]
|
|
||||||
#[graphql(
|
|
||||||
schema_path = "../schema.graphql",
|
|
||||||
query_path = "tests/queries/delete_group.graphql",
|
|
||||||
response_derives = "Debug",
|
|
||||||
custom_scalars_module = "crate::infra::graphql"
|
|
||||||
)]
|
|
||||||
struct DeleteGroupQuery;
|
|
||||||
|
|
||||||
#[derive(GraphQLQuery)]
|
|
||||||
#[graphql(
|
|
||||||
schema_path = "../schema.graphql",
|
|
||||||
query_path = "tests/queries/delete_user.graphql",
|
|
||||||
response_derives = "Debug",
|
|
||||||
custom_scalars_module = "crate::infra::graphql"
|
|
||||||
)]
|
|
||||||
struct DeleteUserQuery;
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct User {
|
pub struct User {
|
||||||
@ -101,11 +35,11 @@ impl LLDAPFixture {
|
|||||||
let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME")).expect("cargo bin found");
|
let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME")).expect("cargo bin found");
|
||||||
|
|
||||||
let path = canonicalize("..").expect("canonical path");
|
let path = canonicalize("..").expect("canonical path");
|
||||||
let db_url = get_database_url();
|
let db_url = env::database_url();
|
||||||
println!("Running from directory: {:?}", path);
|
println!("Running from directory: {:?}", path);
|
||||||
println!("Using database: {db_url}");
|
println!("Using database: {db_url}");
|
||||||
cmd.current_dir(path.clone());
|
cmd.current_dir(path.clone());
|
||||||
cmd.env(DB_KEY, db_url);
|
cmd.env(env::DB_KEY, db_url);
|
||||||
cmd.arg("run");
|
cmd.arg("run");
|
||||||
cmd.arg("--verbose");
|
cmd.arg("--verbose");
|
||||||
let child = cmd.spawn().expect("Unable to start server");
|
let child = cmd.spawn().expect("Unable to start server");
|
||||||
@ -127,7 +61,7 @@ impl LLDAPFixture {
|
|||||||
.redirect(reqwest::redirect::Policy::none())
|
.redirect(reqwest::redirect::Policy::none())
|
||||||
.build()
|
.build()
|
||||||
.expect("failed to make http client");
|
.expect("failed to make http client");
|
||||||
let token = get_token(&client).expect("failed to get token");
|
let token = get_token(&client);
|
||||||
Self {
|
Self {
|
||||||
client,
|
client,
|
||||||
token,
|
token,
|
||||||
@ -244,99 +178,11 @@ impl Drop for LLDAPFixture {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_database_url() -> String {
|
pub fn new_id(prefix: Option<&str>) -> String {
|
||||||
let url = var(DB_KEY).ok();
|
let id = Uuid::new_v4();
|
||||||
let url = url.unwrap_or("sqlite://e2e_test.db?mode=rwc".to_string());
|
let id = format!("{}-lldap-test", id.to_simple());
|
||||||
url.to_string()
|
match prefix {
|
||||||
}
|
Some(prefix) => format!("{}{}", prefix, id),
|
||||||
|
None => id,
|
||||||
pub fn get_ldap_url() -> String {
|
}
|
||||||
let port = option_env!("LLDAP_LDAP_PORT");
|
|
||||||
let port = port.unwrap_or("3890");
|
|
||||||
let mut url = String::from("ldap://localhost:");
|
|
||||||
url += port;
|
|
||||||
url
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_http_url() -> String {
|
|
||||||
let port = option_env!("LLDAP_HTTP_PORT");
|
|
||||||
let port = port.unwrap_or("17170");
|
|
||||||
let mut url = String::from("http://localhost:");
|
|
||||||
url += port;
|
|
||||||
url
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_admin_dn() -> String {
|
|
||||||
let user = option_env!("LLDAP_LDAP_USER_DN");
|
|
||||||
let user = user.unwrap_or("admin");
|
|
||||||
user.to_string()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_admin_password() -> String {
|
|
||||||
let pass = option_env!("LLDAP_LDAP_USER_PASS");
|
|
||||||
let pass = pass.unwrap_or("password");
|
|
||||||
pass.to_string()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_base_dn() -> String {
|
|
||||||
let dn = option_env!("LLDAP_LDAP_BASE_DN");
|
|
||||||
let dn = dn.unwrap_or("dc=example,dc=com");
|
|
||||||
dn.to_string()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_token(client: &Client) -> Result<String> {
|
|
||||||
let username = get_admin_dn();
|
|
||||||
let password = get_admin_password();
|
|
||||||
let base_url = get_http_url();
|
|
||||||
let response = client
|
|
||||||
.post(format!("{base_url}/auth/simple/login"))
|
|
||||||
.header(reqwest::header::CONTENT_TYPE, "application/json")
|
|
||||||
.body(
|
|
||||||
serde_json::to_string(&lldap_auth::login::ClientSimpleLoginRequest {
|
|
||||||
username: username,
|
|
||||||
password: password,
|
|
||||||
})
|
|
||||||
.expect("Failed to encode the username/password as json to log in"),
|
|
||||||
)
|
|
||||||
.send()?
|
|
||||||
.error_for_status()?;
|
|
||||||
Ok(serde_json::from_str::<lldap_auth::login::ServerLoginResponse>(&response.text()?)?.token)
|
|
||||||
}
|
|
||||||
pub fn post<QueryType>(
|
|
||||||
client: &Client,
|
|
||||||
token: &String,
|
|
||||||
variables: QueryType::Variables,
|
|
||||||
) -> Result<QueryType::ResponseData>
|
|
||||||
where
|
|
||||||
QueryType: GraphQLQuery + 'static,
|
|
||||||
{
|
|
||||||
let unwrap_graphql_response = |graphql_client::Response { data, errors, .. }| {
|
|
||||||
data.ok_or_else(|| {
|
|
||||||
anyhow!(
|
|
||||||
"Errors: [{}]",
|
|
||||||
errors
|
|
||||||
.unwrap_or_default()
|
|
||||||
.iter()
|
|
||||||
.map(ToString::to_string)
|
|
||||||
.collect::<Vec<_>>()
|
|
||||||
.join(", ")
|
|
||||||
)
|
|
||||||
})
|
|
||||||
};
|
|
||||||
let url = get_http_url() + "/api/graphql";
|
|
||||||
let auth_header = format!("Bearer {}", token);
|
|
||||||
client
|
|
||||||
.post(url)
|
|
||||||
.header(reqwest::header::AUTHORIZATION, auth_header)
|
|
||||||
// Request body.
|
|
||||||
.json(&QueryType::build_query(variables))
|
|
||||||
.send()
|
|
||||||
.context("while sending a request to the LLDAP server")?
|
|
||||||
.error_for_status()
|
|
||||||
.context("error from an LLDAP response")?
|
|
||||||
// Parse response as Json.
|
|
||||||
.json::<graphql_client::Response<QueryType::ResponseData>>()
|
|
||||||
.context("while parsing backend response")
|
|
||||||
.and_then(unwrap_graphql_response)
|
|
||||||
.context("GraphQL error from an LLDAP response")
|
|
||||||
}
|
}
|
||||||
|
109
server/tests/common/graphql.rs
Normal file
109
server/tests/common/graphql.rs
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
use crate::common::env;
|
||||||
|
use anyhow::{anyhow, Context, Result};
|
||||||
|
use graphql_client::GraphQLQuery;
|
||||||
|
use reqwest::blocking::Client;
|
||||||
|
|
||||||
|
#[derive(GraphQLQuery)]
|
||||||
|
#[graphql(
|
||||||
|
schema_path = "../schema.graphql",
|
||||||
|
query_path = "tests/queries/add_user_to_group.graphql",
|
||||||
|
response_derives = "Debug",
|
||||||
|
variables_derives = "Debug,Clone",
|
||||||
|
custom_scalars_module = "crate::infra::graphql"
|
||||||
|
)]
|
||||||
|
pub struct AddUserToGroup;
|
||||||
|
|
||||||
|
#[derive(GraphQLQuery)]
|
||||||
|
#[graphql(
|
||||||
|
schema_path = "../schema.graphql",
|
||||||
|
query_path = "tests/queries/create_user.graphql",
|
||||||
|
response_derives = "Debug",
|
||||||
|
variables_derives = "Debug,Clone",
|
||||||
|
custom_scalars_module = "crate::infra::graphql"
|
||||||
|
)]
|
||||||
|
pub struct CreateUser;
|
||||||
|
|
||||||
|
#[derive(GraphQLQuery)]
|
||||||
|
#[graphql(
|
||||||
|
schema_path = "../schema.graphql",
|
||||||
|
query_path = "tests/queries/create_group.graphql",
|
||||||
|
response_derives = "Debug",
|
||||||
|
variables_derives = "Debug,Clone",
|
||||||
|
custom_scalars_module = "crate::infra::graphql"
|
||||||
|
)]
|
||||||
|
pub struct CreateGroup;
|
||||||
|
|
||||||
|
#[derive(GraphQLQuery)]
|
||||||
|
#[graphql(
|
||||||
|
schema_path = "../schema.graphql",
|
||||||
|
query_path = "tests/queries/list_users.graphql",
|
||||||
|
response_derives = "Debug",
|
||||||
|
custom_scalars_module = "crate::infra::graphql"
|
||||||
|
)]
|
||||||
|
pub struct ListUsers;
|
||||||
|
|
||||||
|
#[derive(GraphQLQuery)]
|
||||||
|
#[graphql(
|
||||||
|
schema_path = "../schema.graphql",
|
||||||
|
query_path = "tests/queries/list_groups.graphql",
|
||||||
|
response_derives = "Debug",
|
||||||
|
custom_scalars_module = "crate::infra::graphql"
|
||||||
|
)]
|
||||||
|
pub struct ListGroups;
|
||||||
|
|
||||||
|
#[derive(GraphQLQuery)]
|
||||||
|
#[graphql(
|
||||||
|
schema_path = "../schema.graphql",
|
||||||
|
query_path = "tests/queries/delete_group.graphql",
|
||||||
|
response_derives = "Debug",
|
||||||
|
custom_scalars_module = "crate::infra::graphql"
|
||||||
|
)]
|
||||||
|
pub struct DeleteGroupQuery;
|
||||||
|
|
||||||
|
#[derive(GraphQLQuery)]
|
||||||
|
#[graphql(
|
||||||
|
schema_path = "../schema.graphql",
|
||||||
|
query_path = "tests/queries/delete_user.graphql",
|
||||||
|
response_derives = "Debug",
|
||||||
|
custom_scalars_module = "crate::infra::graphql"
|
||||||
|
)]
|
||||||
|
pub struct DeleteUserQuery;
|
||||||
|
|
||||||
|
pub fn post<QueryType>(
|
||||||
|
client: &Client,
|
||||||
|
token: &String,
|
||||||
|
variables: QueryType::Variables,
|
||||||
|
) -> Result<QueryType::ResponseData>
|
||||||
|
where
|
||||||
|
QueryType: GraphQLQuery + 'static,
|
||||||
|
{
|
||||||
|
let unwrap_graphql_response = |graphql_client::Response { data, errors, .. }| {
|
||||||
|
data.ok_or_else(|| {
|
||||||
|
anyhow!(
|
||||||
|
"Errors: [{}]",
|
||||||
|
errors
|
||||||
|
.unwrap_or_default()
|
||||||
|
.iter()
|
||||||
|
.map(ToString::to_string)
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.join(", ")
|
||||||
|
)
|
||||||
|
})
|
||||||
|
};
|
||||||
|
let url = env::http_url() + "/api/graphql";
|
||||||
|
let auth_header = format!("Bearer {}", token);
|
||||||
|
client
|
||||||
|
.post(url)
|
||||||
|
.header(reqwest::header::AUTHORIZATION, auth_header)
|
||||||
|
// Request body.
|
||||||
|
.json(&QueryType::build_query(variables))
|
||||||
|
.send()
|
||||||
|
.context("while sending a request to the LLDAP server")?
|
||||||
|
.error_for_status()
|
||||||
|
.context("error from an LLDAP response")?
|
||||||
|
// Parse response as Json.
|
||||||
|
.json::<graphql_client::Response<QueryType::ResponseData>>()
|
||||||
|
.context("while parsing backend response")
|
||||||
|
.and_then(unwrap_graphql_response)
|
||||||
|
.context("GraphQL error from an LLDAP response")
|
||||||
|
}
|
@ -1 +1,4 @@
|
|||||||
|
pub mod auth;
|
||||||
|
pub mod env;
|
||||||
pub mod fixture;
|
pub mod fixture;
|
||||||
|
pub mod graphql;
|
||||||
|
@ -1,19 +1,27 @@
|
|||||||
use crate::common::fixture::{LLDAPFixture, User};
|
use crate::common::{
|
||||||
use graphql_client::GraphQLQuery;
|
auth::get_token,
|
||||||
use ldap3::{LdapConn, Scope, SearchEntry};
|
fixture::{new_id, LLDAPFixture, User},
|
||||||
use reqwest::blocking::{Client, ClientBuilder};
|
graphql::{post, ListUsers},
|
||||||
|
};
|
||||||
|
use reqwest::blocking::ClientBuilder;
|
||||||
use serial_test::file_serial;
|
use serial_test::file_serial;
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::HashSet;
|
||||||
mod common;
|
mod common;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[file_serial]
|
#[file_serial]
|
||||||
fn list_users() {
|
fn list_users() {
|
||||||
let mut fixture = LLDAPFixture::new();
|
let mut fixture = LLDAPFixture::new();
|
||||||
|
let prefix = "graphql-list_users-";
|
||||||
|
let user1_name = new_id(Some(prefix));
|
||||||
|
let user2_name = new_id(Some(prefix));
|
||||||
|
let user3_name = new_id(Some(prefix));
|
||||||
|
let group1_name = new_id(Some(prefix));
|
||||||
|
let group2_name = new_id(Some(prefix));
|
||||||
let initial_state = vec![
|
let initial_state = vec![
|
||||||
User::new("user1", vec!["group-one"]),
|
User::new(&user1_name, vec![&group1_name]),
|
||||||
User::new("user2", vec!["group-one", "group-two"]),
|
User::new(&user2_name, vec![&group1_name, &group2_name]),
|
||||||
User::new("user3", vec![]),
|
User::new(&user3_name, vec![]),
|
||||||
];
|
];
|
||||||
fixture.load_state(&initial_state);
|
fixture.load_state(&initial_state);
|
||||||
|
|
||||||
@ -23,20 +31,11 @@ fn list_users() {
|
|||||||
.redirect(reqwest::redirect::Policy::none())
|
.redirect(reqwest::redirect::Policy::none())
|
||||||
.build()
|
.build()
|
||||||
.expect("failed to make http client");
|
.expect("failed to make http client");
|
||||||
let token = common::fixture::get_token(&client).expect("failed to get token");
|
let token = get_token(&client);
|
||||||
let result = common::fixture::post::<ListUsers>(&client, &token, list_users::Variables {})
|
let result = post::<ListUsers>(&client, &token, common::graphql::list_users::Variables {})
|
||||||
.expect("failed to list users");
|
.expect("failed to list users");
|
||||||
let users: HashSet<String> = result.users.iter().map(|user| user.id.clone()).collect();
|
let users: HashSet<String> = result.users.iter().map(|user| user.id.clone()).collect();
|
||||||
assert!(users.contains("user1"));
|
assert!(users.contains(&user1_name));
|
||||||
assert!(users.contains("user2"));
|
assert!(users.contains(&user2_name));
|
||||||
assert!(users.contains("user3"));
|
assert!(users.contains(&user3_name));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(GraphQLQuery)]
|
|
||||||
#[graphql(
|
|
||||||
schema_path = "../schema.graphql",
|
|
||||||
query_path = "tests/queries/list_users.graphql",
|
|
||||||
response_derives = "Debug",
|
|
||||||
custom_scalars_module = "crate::infra::graphql"
|
|
||||||
)]
|
|
||||||
struct ListUsers;
|
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::HashSet;
|
||||||
|
|
||||||
use crate::common::fixture::{LLDAPFixture, User};
|
use crate::common::{
|
||||||
|
env,
|
||||||
|
fixture::{new_id, LLDAPFixture, User},
|
||||||
|
};
|
||||||
use ldap3::{LdapConn, Scope, SearchEntry};
|
use ldap3::{LdapConn, Scope, SearchEntry};
|
||||||
use serial_test::file_serial;
|
use serial_test::file_serial;
|
||||||
mod common;
|
mod common;
|
||||||
@ -9,29 +12,26 @@ mod common;
|
|||||||
#[file_serial]
|
#[file_serial]
|
||||||
fn gitea() {
|
fn gitea() {
|
||||||
let mut fixture = LLDAPFixture::new();
|
let mut fixture = LLDAPFixture::new();
|
||||||
let gitea_user_group = "gitea_user";
|
let gitea_user_group = new_id(Some("gitea_user-"));
|
||||||
|
let gitea_admin_group = new_id(Some("gitea_admin-"));
|
||||||
|
let gitea_user1 = new_id(Some("gitea1-"));
|
||||||
|
let gitea_user2 = new_id(Some("gitea2-"));
|
||||||
|
let gitea_user3 = new_id(Some("gitea3-"));
|
||||||
let initial_state = vec![
|
let initial_state = vec![
|
||||||
User::new("bob", vec![gitea_user_group, "gitea-admin"]),
|
User::new(&gitea_user1, vec![&gitea_user_group, &gitea_admin_group]),
|
||||||
User::new("alice", vec![gitea_user_group]),
|
User::new(&gitea_user2, vec![&gitea_user_group]),
|
||||||
User::new("james", vec![]),
|
User::new(&gitea_user3, vec![]),
|
||||||
];
|
];
|
||||||
fixture.load_state(&initial_state);
|
fixture.load_state(&initial_state);
|
||||||
|
|
||||||
let mut ldap = LdapConn::new(common::fixture::get_ldap_url().as_str())
|
let mut ldap =
|
||||||
.expect("failed to create ldap connection");
|
LdapConn::new(env::ldap_url().as_str()).expect("failed to create ldap connection");
|
||||||
let base_dn = common::fixture::get_base_dn();
|
let base_dn = env::base_dn();
|
||||||
let bind_dn = format!(
|
let bind_dn = format!("uid={},ou=people,{}", env::admin_dn(), base_dn);
|
||||||
"uid={},ou=people,{}",
|
ldap.simple_bind(bind_dn.as_str(), env::admin_password().as_str())
|
||||||
common::fixture::get_admin_dn(),
|
.expect("failed to bind to ldap");
|
||||||
base_dn
|
|
||||||
);
|
|
||||||
ldap.simple_bind(
|
|
||||||
bind_dn.as_str(),
|
|
||||||
common::fixture::get_admin_password().as_str(),
|
|
||||||
)
|
|
||||||
.expect("failed to bind to ldap");
|
|
||||||
|
|
||||||
let user_base = format!("ou=people,{}", common::fixture::get_base_dn());
|
let user_base = format!("ou=people,{}", base_dn);
|
||||||
let attrs = vec!["uid", "givenName", "sn", "mail", "jpegPhoto"];
|
let attrs = vec!["uid", "givenName", "sn", "mail", "jpegPhoto"];
|
||||||
let results = ldap
|
let results = ldap
|
||||||
.search(
|
.search(
|
||||||
@ -50,8 +50,8 @@ fn gitea() {
|
|||||||
let user = attrs.get("uid").unwrap().get(0).unwrap();
|
let user = attrs.get("uid").unwrap().get(0).unwrap();
|
||||||
found_users.insert(user.clone());
|
found_users.insert(user.clone());
|
||||||
}
|
}
|
||||||
assert!(found_users.contains("bob"));
|
assert!(found_users.contains(&gitea_user1));
|
||||||
assert!(found_users.contains("alice"));
|
assert!(found_users.contains(&gitea_user2));
|
||||||
assert!(!found_users.contains("james"));
|
assert!(!found_users.contains(&gitea_user3));
|
||||||
ldap.unbind().expect("failed to unbind ldap connection");
|
ldap.unbind().expect("failed to unbind ldap connection");
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::{HashMap, HashSet};
|
||||||
|
|
||||||
use crate::common::fixture::{LLDAPFixture, User};
|
use crate::common::{
|
||||||
|
env,
|
||||||
|
fixture::{new_id, LLDAPFixture, User},
|
||||||
|
};
|
||||||
use ldap3::{LdapConn, Scope, SearchEntry};
|
use ldap3::{LdapConn, Scope, SearchEntry};
|
||||||
use serial_test::file_serial;
|
use serial_test::file_serial;
|
||||||
mod common;
|
mod common;
|
||||||
@ -9,31 +12,30 @@ mod common;
|
|||||||
#[file_serial]
|
#[file_serial]
|
||||||
fn basic_users_search() {
|
fn basic_users_search() {
|
||||||
let mut fixture = LLDAPFixture::new();
|
let mut fixture = LLDAPFixture::new();
|
||||||
|
let prefix = "ldap-basic_users_search-";
|
||||||
|
let user1_name = new_id(Some(prefix));
|
||||||
|
let user2_name = new_id(Some(prefix));
|
||||||
|
let user3_name = new_id(Some(prefix));
|
||||||
|
let group1_name = new_id(Some(prefix));
|
||||||
|
let group2_name = new_id(Some(prefix));
|
||||||
let initial_state = vec![
|
let initial_state = vec![
|
||||||
User::new("user1", vec!["group-one"]),
|
User::new(&user1_name, vec![&group1_name]),
|
||||||
User::new("user2", vec!["group-one", "group-two"]),
|
User::new(&user2_name, vec![&group1_name, &group2_name]),
|
||||||
User::new("user3", vec![]),
|
User::new(&user3_name, vec![]),
|
||||||
];
|
];
|
||||||
fixture.load_state(&initial_state);
|
fixture.load_state(&initial_state);
|
||||||
|
|
||||||
let mut ldap = LdapConn::new(common::fixture::get_ldap_url().as_str())
|
let mut ldap =
|
||||||
.expect("failed to create ldap connection");
|
LdapConn::new(env::ldap_url().as_str()).expect("failed to create ldap connection");
|
||||||
let base_dn = common::fixture::get_base_dn();
|
let base_dn = env::base_dn();
|
||||||
let bind_dn = format!(
|
let bind_dn = format!("uid={},ou=people,{}", env::admin_dn(), base_dn);
|
||||||
"uid={},ou=people,{}",
|
ldap.simple_bind(bind_dn.as_str(), env::admin_password().as_str())
|
||||||
common::fixture::get_admin_dn(),
|
.expect("failed to bind to ldap");
|
||||||
base_dn
|
|
||||||
);
|
|
||||||
ldap.simple_bind(
|
|
||||||
bind_dn.as_str(),
|
|
||||||
common::fixture::get_admin_password().as_str(),
|
|
||||||
)
|
|
||||||
.expect("failed to bind to ldap");
|
|
||||||
|
|
||||||
let attrs = vec!["uid", "memberof"];
|
let attrs = vec!["uid", "memberof"];
|
||||||
let results = ldap
|
let results = ldap
|
||||||
.search(
|
.search(
|
||||||
common::fixture::get_base_dn().as_str(),
|
env::base_dn().as_str(),
|
||||||
Scope::Subtree,
|
Scope::Subtree,
|
||||||
"(objectclass=person)",
|
"(objectclass=person)",
|
||||||
attrs,
|
attrs,
|
||||||
@ -51,21 +53,21 @@ fn basic_users_search() {
|
|||||||
groups.extend(user_groups.clone());
|
groups.extend(user_groups.clone());
|
||||||
found_users.insert(user.clone(), groups);
|
found_users.insert(user.clone(), groups);
|
||||||
}
|
}
|
||||||
assert!(found_users.contains_key("user1"));
|
assert!(found_users.contains_key(&user1_name));
|
||||||
assert!(found_users
|
assert!(found_users
|
||||||
.get("user1")
|
.get(&user1_name)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.contains(format!("cn={},ou=groups,{}", "group-one", base_dn).as_str()));
|
.contains(format!("cn={},ou=groups,{}", &group1_name, base_dn).as_str()));
|
||||||
assert!(found_users.contains_key("user2"));
|
assert!(found_users.contains_key(&user2_name));
|
||||||
assert!(found_users
|
assert!(found_users
|
||||||
.get("user2")
|
.get(&user2_name)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.contains(format!("cn={},ou=groups,{}", "group-one", base_dn).as_str()));
|
.contains(format!("cn={},ou=groups,{}", &group1_name, base_dn).as_str()));
|
||||||
assert!(found_users
|
assert!(found_users
|
||||||
.get("user2")
|
.get(&user2_name)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.contains(format!("cn={},ou=groups,{}", "group-two", base_dn).as_str()));
|
.contains(format!("cn={},ou=groups,{}", &group2_name, base_dn).as_str()));
|
||||||
assert!(found_users.contains_key("user3"));
|
assert!(found_users.contains_key(&user3_name));
|
||||||
assert!(found_users.get("user3").unwrap().is_empty());
|
assert!(found_users.get(&user3_name).unwrap().is_empty());
|
||||||
ldap.unbind().expect("failed to unbind ldap connection");
|
ldap.unbind().expect("failed to unbind ldap connection");
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user