153 lines
4.6 KiB
Rust
153 lines
4.6 KiB
Rust
use actix_files::NamedFile;
|
|
use actix_session::{SessionMiddleware, storage::RedisSessionStore};
|
|
use actix_web::{App, HttpResponse, HttpServer, cookie::Key, middleware::Logger, web};
|
|
use log::debug;
|
|
|
|
mod controller;
|
|
mod db;
|
|
mod error;
|
|
|
|
pub use db::Database;
|
|
pub use db::entity;
|
|
use log::info;
|
|
use migration::Migrator;
|
|
use migration::MigratorTrait;
|
|
|
|
#[derive(Clone)]
|
|
struct AppConfig {
|
|
ldap_auth: bool,
|
|
}
|
|
|
|
#[actix_web::main]
|
|
async fn main() -> std::io::Result<()> {
|
|
dotenvy::dotenv().ok();
|
|
env_logger::init_from_env(env_logger::Env::new().default_filter_or("info"));
|
|
|
|
let database_url = build_database_url();
|
|
|
|
let database = Database::new(database_url.into()).await.unwrap();
|
|
|
|
info!("Running migrations");
|
|
Migrator::up(database.connection(), None).await.unwrap();
|
|
info!("Migrations completed");
|
|
|
|
let redis_conn = connect_to_redis_database().await;
|
|
|
|
let app_config = AppConfig { ldap_auth: false };
|
|
|
|
// use dotenvy here to get SECRET_KEY
|
|
let secret_key = Key::generate();
|
|
debug!("Secret Key {:?}", secret_key.master());
|
|
|
|
HttpServer::new(move || {
|
|
let app = App::new()
|
|
.app_data(web::Data::new(database.clone()))
|
|
.app_data(web::Data::new(app_config.clone()))
|
|
.wrap(Logger::default())
|
|
.wrap(SessionMiddleware::new(
|
|
redis_conn.clone(),
|
|
secret_key.clone(),
|
|
))
|
|
.service(web::scope("/api/v1").configure(controller::register_controllers));
|
|
|
|
#[cfg(feature = "serve")]
|
|
let app = {
|
|
println!("running serve");
|
|
app.default_service(
|
|
web::get().to(async || NamedFile::open_async("./web/index.html").await),
|
|
)
|
|
};
|
|
|
|
app
|
|
})
|
|
.bind(("0.0.0.0", 8080))?
|
|
.run()
|
|
.await
|
|
}
|
|
|
|
async fn connect_to_redis_database() -> RedisSessionStore {
|
|
let redis_host = dotenvy::var("REDIS_HOST").expect("REDIS_HOST must be set in .env");
|
|
let redis_port = dotenvy::var("REDIS_PORT")
|
|
.map(|x| x.parse::<u16>().expect("REDIS_PORT is not a valid port"))
|
|
.unwrap_or(6379);
|
|
let redis_connection_string = format!("redis://{}:{}", redis_host, redis_port);
|
|
let store = RedisSessionStore::new(redis_connection_string)
|
|
.await
|
|
.unwrap();
|
|
|
|
return store;
|
|
}
|
|
|
|
fn build_database_url() -> String {
|
|
let db_user = dotenvy::var("DB_USER").unwrap_or("pgg".to_owned());
|
|
let db_name = dotenvy::var("DB_NAME").unwrap_or("pgg".to_owned());
|
|
let db_password = dotenvy::var("DB_PASSWORD").unwrap_or("pgg".to_owned());
|
|
let db_host = dotenvy::var("DB_HOST").expect("DB_HOST must be set in .env");
|
|
let db_port = dotenvy::var("DB_PORT")
|
|
.map(|x| x.parse::<u16>().expect("DB_PORT is not a valid port"))
|
|
.unwrap_or(5432);
|
|
|
|
let result = format!(
|
|
"postgresql://{}:{}@{}:{}/{}",
|
|
db_user, db_password, db_host, db_port, db_name
|
|
);
|
|
|
|
println!("Database URL: {}", result);
|
|
result
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
use temp_env::{with_vars, with_vars_unset};
|
|
|
|
#[test]
|
|
fn build_database_url_with_defaults() {
|
|
temp_env::with_vars(
|
|
[
|
|
("DB_USER", None::<&str>),
|
|
("DB_NAME", None::<&str>),
|
|
("DB_PASSWORD", None::<&str>),
|
|
("DB_HOST", Some("localhost")),
|
|
("DB_PORT", None::<&str>),
|
|
],
|
|
|| {
|
|
let expected_url = "postgresql://pgg:pgg@localhost:5432/pgg";
|
|
let actual_url = build_database_url();
|
|
assert_eq!(
|
|
actual_url, expected_url,
|
|
"Database URL should use default values for unset env vars."
|
|
);
|
|
},
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn build_database_url_with_all_vars() {
|
|
with_vars(
|
|
[
|
|
("DB_USER", Some("testuser")),
|
|
("DB_NAME", Some("testdb")),
|
|
("DB_PASSWORD", Some("testpass")),
|
|
("DB_HOST", Some("otherhost.internal")),
|
|
("DB_PORT", Some("5433")),
|
|
],
|
|
|| {
|
|
let expected_url = "postgresql://testuser:testpass@otherhost.internal:5433/testdb";
|
|
let actual_url = build_database_url();
|
|
assert_eq!(
|
|
actual_url, expected_url,
|
|
"Database URL should use all provided env vars."
|
|
);
|
|
},
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
#[should_panic(expected = "DB_HOST must be set in .env")]
|
|
fn build_database_url_missing_host_panics() {
|
|
with_vars_unset(["DB_HOST"], || {
|
|
build_database_url();
|
|
});
|
|
}
|
|
}
|