Initial commit.

This commit is contained in:
Florian THIERRY
2026-07-13 21:57:58 +02:00
commit b5a95b0fa3
49 changed files with 11243 additions and 0 deletions
+9
View File
@@ -0,0 +1,9 @@
HTTPS_ENABLED=false
JWT_SECRET=jwt-secret
SQLITE_DATABASE_NAME=lumiere.sqlite
BCRYPT_SALT=salt
SNAPSHOT_RESOURCES_CRON_FREQUENCY="*/5 * * * * *"
SERVER_MODE=real # real | mocked
#MOCKED_DAEMON_START_SUCCESS=true
#MOCKED_DAEMON_STOP_SUCCESS=true
#MOCKED_DAEMON_RESTART_SUCCESS=true
+3486
View File
File diff suppressed because it is too large Load Diff
+24
View File
@@ -0,0 +1,24 @@
[package]
name = "lumiere"
version = "1.0.0"
edition = "2024"
[[bin]]
name = "lumiere"
path = "src/main.rs"
[dependencies]
lumiere-domain = { path = "../domain" }
lumiere-application = { path = "../application" }
lumiere-infrastructure = { path = "../infrastructure" }
lumiere-exposition = { path = "../exposition" }
actix-web = { version = "4.13.0", features = ["rustls-0_23"] }
diesel = { version = "2.0", features = ["sqlite"] }
dotenv = "0.15.0"
env_logger = "0.11.10"
log = "0.4.29"
rusqlite = { version = "0.39.0", features = ["bundled"] }
rustls = "0.23.37"
rustls-pemfile = "2.2.0"
tokio-cron-scheduler = "0.15.1"
@@ -0,0 +1,80 @@
use crate::server_mode::ServerMode;
use crate::server_mode::ServerMode::Mocked;
use diesel::SqliteConnection;
use log::{debug, info};
use rusqlite::Connection;
use std::env;
use std::io::{Error, ErrorKind};
use std::sync::{Arc, Mutex};
use surveillant_systeme_application::configuration::service::ConfigurationService;
use surveillant_systeme_application::user::service::UserService;
use surveillant_systeme_infrastructure::common::database_connection::DatabaseConnection;
use surveillant_systeme_infrastructure::common::database_initialisation::initialise_database_tables;
use surveillant_systeme_infrastructure::configuration::adapter::ConfigurationSqliteAdapter;
use surveillant_systeme_infrastructure::configuration::repository::ConfigurationSqliteRepository;
use surveillant_systeme_infrastructure::user::adapter::UserSqliteAdapter;
use surveillant_systeme_infrastructure::user::diesel_adapter::UserDieselAdapter;
use surveillant_systeme_infrastructure::user::diesel_repository::UserDieselRepository;
use surveillant_systeme_infrastructure::user::repository::UserSqliteRepository;
pub struct ApplicationContext {
pub database_connection: Arc<Mutex<Connection>>,
pub configuration_service: ConfigurationService,
pub user_service: UserService,
}
impl ApplicationContext {
pub fn init() -> Result<Self, Error> {
let database_connection = DatabaseConnection::init();
let application_context = Self::new(database_connection.connection, database_connection.diesel_connection);
if database_connection.database_has_been_created {
initialise_database_tables(&application_context.database_connection)
.map_err(|error| Error::new(
ErrorKind::Other,
format!("Unable to initialise database tables… {}", error)
))?;
application_context.configuration_service.create_initialisation_code().expect("Unable to create initialisation code…");
}
application_context.display_initialisation_code_if_required()?;
Ok(application_context)
}
fn new(connection: Connection, diesel_connection: SqliteConnection) -> Self {
let arc_mutex_connection = Arc::new(Mutex::new(connection));
let arc_mutex_diesel_connection = Arc::new(Mutex::new(diesel_connection));
let configuration_repository = ConfigurationSqliteRepository::new(arc_mutex_connection.clone());
let configuration_adapter = Box::new(ConfigurationSqliteAdapter::new(configuration_repository.clone()));
let configuration_service = ConfigurationService::new(configuration_adapter.clone());
let user_repository = UserDieselRepository::new(arc_mutex_diesel_connection.clone());
let user_adapter = Box::new(UserDieselAdapter::new(user_repository.clone()));
// let user_repository = UserSqliteRepository::new(arc_mutex_connection.clone());
// let user_adapter = Box::new(UserSqliteAdapter::new(user_repository.clone()));
let user_service = UserService::new(configuration_service.clone(), user_adapter.clone());
Self {
database_connection: arc_mutex_connection.clone(),
configuration_service,
user_service,
}
}
fn display_initialisation_code_if_required(&self) -> Result<(), Error> {
let initialisation_code_opt = self.configuration_service.get_initialisation_code()?;
let is_initialised = initialisation_code_opt.is_none();
if is_initialised {
debug!("Database is already initialised.");
} else {
info!("Database is not initialised yet.");
let initialisation_code = initialisation_code_opt.unwrap();
info!("Here is the initialisation code: {}", initialisation_code);
}
Ok(())
}
}
+63
View File
@@ -0,0 +1,63 @@
mod application_context;
mod server_mode;
use crate::application_context::ApplicationContext;
use actix_web::{web, App, HttpServer};
use dotenv::dotenv;
use log::info;
use rustls::ServerConfig;
use std::env;
use std::fs::File;
use std::io::{BufReader, Error};
use std::sync::Arc;
use surveillant_systeme_exposition::init;
use tokio_cron_scheduler::{Job, JobScheduler};
#[actix_web::main]
async fn main() -> std::io::Result<()>{
dotenv().ok();
unsafe { env::set_var("RUST_LOG", "debug"); }
check_all_variables_are_set();
env_logger::init();
let application_context = ApplicationContext::init()?;
let tls_config = init_tls_configuration()?;
let server = HttpServer::new(
move || App::new().configure(init)
.app_data(web::Data::new(Arc::new(application_context.user_service.clone())))
)
.bind_rustls_0_23(("0.0.0.0", 19000), tls_config)
.expect("Unable to start server");
server.run().await
}
fn init_tls_configuration() -> Result<ServerConfig, Error> {
let mut certs_file = BufReader::new(File::open("./certs/lumiere.crt")?);
let mut key_file = BufReader::new(File::open("./certs/lumiere.key")?);
let tls_certs = rustls_pemfile::certs(&mut certs_file)
.collect::<Result<Vec<_>, _>>().expect("Unable to read the TLS certificate…");
let tls_key = rustls_pemfile::pkcs8_private_keys(&mut key_file)
.next()
.unwrap()
.expect("Unable to read the private key for TLS configuration…");
let tls_config = rustls::ServerConfig::builder()
.with_no_client_auth()
.with_single_cert(tls_certs, rustls::pki_types::PrivateKeyDer::Pkcs8(tls_key))
.unwrap();
Ok(tls_config)
}
fn check_all_variables_are_set() {
info!("Checking all variables exist…");
let variables = vec!["JWT_SECRET", "SQLITE_DATABASE_NAME", "BCRYPT_SALT"];
variables.iter().for_each(|variable| {
env::var(variable).expect(format!("{} should be defined!", variable).as_str());
});
info!("All variables are set correctly.");
}
+17
View File
@@ -0,0 +1,17 @@
use crate::server_mode::ServerMode::{Mocked, Real};
pub enum ServerMode {
Mocked,
Real
}
impl ServerMode {
pub fn from_string(value: String) -> Option<ServerMode> {
match value.as_str() {
"mocked" => Some(Mocked),
"real" => Some(Real),
_ => None
}
}
}