use std::{io, sync::Arc}; use actix_identity::IdentityMiddleware; use actix_session::{config::PersistentSession, storage::CookieSessionStore, SessionMiddleware}; use actix_web::{ cookie::{time::Duration, Key}, middleware, web::{self}, App, HttpServer, }; // Define our model module mod model; use model::user::User; // Define our repo module mod repo; use repo::todo_repository::TodoRepository; use repo::user_repository::UserRepository; // Define our routes module mod routes; use routes::{todo_routes, user_routes}; /// Starts the webserver and initializes required repos, etc. #[actix_web::main] async fn main() -> io::Result<()> { env_logger::init_from_env(env_logger::Env::new().default_filter_or("debug")); // TODO: Currently I do not handle the case where the cassandra server is // rebooted during the lifetime of the webserver and loses its configuration. // Normally this is not a real scenario because the tables should be persistent // througout reboots but idk, it would still be cool to handle this gracefully. // What would have to happen is a reinit of the repo classes after the connection // is regained to reinitialize the perhaps missing keyspaces/tables let cassandra_session = Arc::new(repo::init()); // TODO: web::Data is already an Arc //-> Investigate if we really need the session as an Arc as well let user = User::new("admin", "init_pw_hash", "init_salt"); let user_repo = web::Data::new(UserRepository::new(Arc::clone(&cassandra_session))); if let Err(err) = user_repo.create(&user) { log::debug!("Default user already exists: {err}"); } let todo_repo = web::Data::new(TodoRepository::new(Arc::clone(&cassandra_session))); // Secret key used to init session storage let key = Key::generate(); log::info!("Starting HTTP server: http://127.0.0.1:6969"); HttpServer::new(move || { App::new() .wrap(middleware::Compress::default()) .wrap(IdentityMiddleware::default()) .wrap( SessionMiddleware::builder(CookieSessionStore::default(), key.clone()) .cookie_secure(false) // Session lifetime .session_lifecycle(PersistentSession::default().session_ttl(Duration::days(7))) .build(), ) .wrap(middleware::Logger::default()) .app_data(user_repo.clone()) .app_data(todo_repo.clone()) .service(user_routes::get_user) .service(user_routes::put_user) .service(user_routes::post_user) .service(todo_routes::get_todo) .service(todo_routes::put_todo) .service(todo_routes::delete_todo) .service(routes::post_login) .service(routes::delete_logout) .default_service(web::to(routes::index)) }) .bind(("127.0.0.1", 6969))? .workers(2) // number of workers per bind default ist #cpus .run() .await }