2021-05-14 07:38:36 +00:00
|
|
|
#![forbid(unsafe_code)]
|
2021-11-10 09:53:37 +00:00
|
|
|
#![forbid(non_ascii_idents)]
|
2021-07-05 08:00:13 +00:00
|
|
|
#![allow(clippy::nonstandard_macro_braces)]
|
|
|
|
|
2021-05-20 17:18:15 +00:00
|
|
|
use crate::{
|
2021-05-26 13:13:17 +00:00
|
|
|
domain::{
|
2022-06-06 14:48:22 +00:00
|
|
|
handler::{BackendHandler, CreateUserRequest, GroupRequestFilter},
|
2021-08-31 13:51:55 +00:00
|
|
|
sql_backend_handler::SqlBackendHandler,
|
|
|
|
sql_opaque_handler::register_password,
|
|
|
|
sql_tables::PoolOptions,
|
2021-05-26 13:13:17 +00:00
|
|
|
},
|
2021-11-11 09:15:00 +00:00
|
|
|
infra::{cli::*, configuration::Configuration, db_cleaner::Scheduler, mail},
|
2021-05-20 17:18:15 +00:00
|
|
|
};
|
2021-05-25 08:39:09 +00:00
|
|
|
use actix::Actor;
|
2021-10-20 06:05:26 +00:00
|
|
|
use anyhow::{anyhow, Context, Result};
|
2021-03-07 11:36:12 +00:00
|
|
|
use futures_util::TryFutureExt;
|
2021-03-02 19:51:33 +00:00
|
|
|
use log::*;
|
|
|
|
|
2021-03-11 09:14:15 +00:00
|
|
|
mod domain;
|
2021-03-02 19:13:58 +00:00
|
|
|
mod infra;
|
|
|
|
|
2021-05-26 17:22:41 +00:00
|
|
|
async fn create_admin_user(handler: &SqlBackendHandler, config: &Configuration) -> Result<()> {
|
2021-11-11 09:36:42 +00:00
|
|
|
let pass_length = config.ldap_user_pass.unsecure().len();
|
2021-10-20 06:05:26 +00:00
|
|
|
assert!(
|
2021-11-11 09:36:42 +00:00
|
|
|
pass_length >= 8,
|
2021-10-20 06:05:26 +00:00
|
|
|
"Minimum password length is 8 characters, got {} characters",
|
2021-11-11 09:36:42 +00:00
|
|
|
pass_length
|
2021-10-20 06:05:26 +00:00
|
|
|
);
|
2021-05-26 13:13:17 +00:00
|
|
|
handler
|
2021-08-31 13:51:55 +00:00
|
|
|
.create_user(CreateUserRequest {
|
2021-05-26 13:13:17 +00:00
|
|
|
user_id: config.ldap_user_dn.clone(),
|
2021-10-11 18:04:16 +00:00
|
|
|
display_name: Some("Administrator".to_string()),
|
2021-05-26 13:13:17 +00:00
|
|
|
..Default::default()
|
|
|
|
})
|
2021-07-05 07:42:54 +00:00
|
|
|
.and_then(|_| register_password(handler, &config.ldap_user_dn, &config.ldap_user_pass))
|
2021-05-26 13:13:17 +00:00
|
|
|
.await
|
2021-08-26 19:56:42 +00:00
|
|
|
.context("Error creating admin user")?;
|
2021-05-26 17:22:41 +00:00
|
|
|
let admin_group_id = handler
|
2021-08-31 13:57:01 +00:00
|
|
|
.create_group("lldap_admin")
|
2021-05-26 17:22:41 +00:00
|
|
|
.await
|
2021-08-26 19:56:42 +00:00
|
|
|
.context("Error creating admin group")?;
|
2021-05-26 17:22:41 +00:00
|
|
|
handler
|
2021-08-31 14:16:17 +00:00
|
|
|
.add_user_to_group(&config.ldap_user_dn, admin_group_id)
|
2021-05-26 17:22:41 +00:00
|
|
|
.await
|
2021-08-26 19:56:42 +00:00
|
|
|
.context("Error adding admin user to group")
|
2021-05-26 13:13:17 +00:00
|
|
|
}
|
|
|
|
|
2021-03-07 11:36:12 +00:00
|
|
|
async fn run_server(config: Configuration) -> Result<()> {
|
2021-04-11 20:07:28 +00:00
|
|
|
let sql_pool = PoolOptions::new()
|
2021-03-07 15:13:50 +00:00
|
|
|
.max_connections(5)
|
2021-03-12 08:33:43 +00:00
|
|
|
.connect(&config.database_url)
|
2021-11-03 07:01:55 +00:00
|
|
|
.await
|
|
|
|
.context("while connecting to the DB")?;
|
|
|
|
domain::sql_tables::init_table(&sql_pool)
|
|
|
|
.await
|
|
|
|
.context("while creating the tables")?;
|
2021-05-20 17:18:15 +00:00
|
|
|
let backend_handler = SqlBackendHandler::new(config.clone(), sql_pool.clone());
|
2021-10-20 06:05:26 +00:00
|
|
|
if let Err(e) = backend_handler.get_user_details(&config.ldap_user_dn).await {
|
|
|
|
warn!("Could not get admin user, trying to create it: {:#}", e);
|
|
|
|
create_admin_user(&backend_handler, &config)
|
|
|
|
.await
|
2021-11-03 07:01:55 +00:00
|
|
|
.map_err(|e| anyhow!("Error setting up admin login/account: {:#}", e))
|
|
|
|
.context("while creating the admin user")?;
|
2021-10-20 06:05:26 +00:00
|
|
|
}
|
2022-06-06 14:48:22 +00:00
|
|
|
if backend_handler
|
|
|
|
.list_groups(Some(GroupRequestFilter::DisplayName(
|
|
|
|
"lldap_readonly".to_string(),
|
|
|
|
)))
|
|
|
|
.await?
|
|
|
|
.is_empty()
|
|
|
|
{
|
|
|
|
warn!("Could not find readonly group, trying to create it");
|
|
|
|
backend_handler
|
|
|
|
.create_group("lldap_readonly")
|
|
|
|
.await
|
|
|
|
.context("while creating readonly group")?;
|
|
|
|
}
|
2021-03-07 15:13:50 +00:00
|
|
|
let server_builder = infra::ldap_server::build_ldap_server(
|
|
|
|
&config,
|
2021-03-11 09:14:15 +00:00
|
|
|
backend_handler.clone(),
|
2021-03-07 15:13:50 +00:00
|
|
|
actix_server::Server::build(),
|
2021-11-03 07:01:55 +00:00
|
|
|
)
|
|
|
|
.context("while binding the LDAP server")?;
|
2021-05-20 15:40:30 +00:00
|
|
|
infra::jwt_sql_tables::init_table(&sql_pool).await?;
|
2021-03-11 09:14:15 +00:00
|
|
|
let server_builder =
|
2021-11-03 07:01:55 +00:00
|
|
|
infra::tcp_server::build_tcp_server(&config, backend_handler, server_builder)
|
|
|
|
.await
|
|
|
|
.context("while binding the TCP server")?;
|
2021-05-25 08:39:09 +00:00
|
|
|
// Run every hour.
|
|
|
|
let scheduler = Scheduler::new("0 0 * * * * *", sql_pool);
|
|
|
|
scheduler.start();
|
2021-11-03 07:01:55 +00:00
|
|
|
server_builder
|
|
|
|
.workers(1)
|
|
|
|
.run()
|
|
|
|
.await
|
|
|
|
.context("while starting the server")?;
|
2021-03-07 11:36:12 +00:00
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2021-08-26 19:46:00 +00:00
|
|
|
fn run_server_command(opts: RunOpts) -> Result<()> {
|
2021-11-11 09:14:03 +00:00
|
|
|
debug!("CLI: {:#?}", &opts);
|
2021-03-02 19:51:33 +00:00
|
|
|
|
2021-11-11 09:14:03 +00:00
|
|
|
let config = infra::configuration::init(opts)?;
|
|
|
|
infra::logging::init(&config)?;
|
2021-03-02 21:03:58 +00:00
|
|
|
|
2021-11-11 09:14:03 +00:00
|
|
|
info!("Starting LLDAP....");
|
2021-03-02 22:07:01 +00:00
|
|
|
|
2021-03-07 11:36:12 +00:00
|
|
|
actix::run(
|
2021-11-03 07:01:55 +00:00
|
|
|
run_server(config).unwrap_or_else(|e| error!("Could not bring up the servers: {:#}", e)),
|
2021-03-07 11:36:12 +00:00
|
|
|
)?;
|
2021-03-02 22:07:01 +00:00
|
|
|
|
2021-03-02 19:51:33 +00:00
|
|
|
info!("End.");
|
|
|
|
Ok(())
|
2021-03-02 11:45:30 +00:00
|
|
|
}
|
2021-08-26 19:46:00 +00:00
|
|
|
|
2021-11-11 09:15:00 +00:00
|
|
|
fn send_test_email_command(opts: TestEmailOpts) -> Result<()> {
|
|
|
|
let to = opts.to.parse()?;
|
|
|
|
let config = infra::configuration::init(opts)?;
|
|
|
|
infra::logging::init(&config)?;
|
|
|
|
mail::send_test_email(to, &config.smtp_options)
|
|
|
|
}
|
|
|
|
|
2021-08-26 19:46:00 +00:00
|
|
|
fn main() -> Result<()> {
|
|
|
|
let cli_opts = infra::cli::init();
|
|
|
|
match cli_opts.command {
|
|
|
|
Command::ExportGraphQLSchema(opts) => infra::graphql::api::export_schema(opts),
|
|
|
|
Command::Run(opts) => run_server_command(opts),
|
2021-11-11 09:15:00 +00:00
|
|
|
Command::SendTestEmail(opts) => send_test_email_command(opts),
|
2021-08-26 19:46:00 +00:00
|
|
|
}
|
|
|
|
}
|