Newer
Older
//! # WEB SERVER FOR THE KUADRADO SOFTWARE WEBSITE
mod app_state;
mod crypto;
mod init_admin;
mod middleware;
mod model;
mod service;
middleware::{normalize::TrailingSlash, Logger, NormalizePath},
web::{get, resource, scope, to, Data},
App, HttpResponse, HttpServer,
};
use actix_web_middleware_redirect_https::RedirectHTTPS;
use standard_static_files::{favicon, robots, sitemap};
use std::env::var as env_var;
use tls::get_tls_config;
use view::get_view;
use view_resource::{ViewResourceDescriptor, ViewResourceManager};
#[actix_web::main]
async fn main() -> std::io::Result<()> {
env_logger::Builder::from_env(Env::default().default_filter_or(get_log_level())).init();
let server_port = env_var("SERVER_PORT").expect("SERVER_PORT is not defined.");
let server_port_tls = env_var("SERVER_PORT_TLS").expect("SERVER_PORT_TLS is not defined.");
let public_dir =
std::path::PathBuf::from(env_var("RESOURCES_DIR").expect("RESOURCES_DIR is not defined"))
.join("public");
let app_state = AppState::with_default_admin_user().await;
HttpServer::new(move || {
App::new()
.wrap(Logger::default())
// Redirect all requests to https
.wrap(RedirectHTTPS::with_replacements(&[(
format!(":{}", server_port),
format!(":{}", server_port_tls),
)]))
.wrap(actix_web::middleware::Compress::default())
.app_data(Data::new(app_state.clone()))
.app_data(Data::new(AuthenticatedAdminMiddleware::new(
"kuadrado-admin-auth",
)))
.app_data(Data::new(ViewResourceManager::with_views(vec![
ViewResourceDescriptor {
path_str: "admin-panel",
index_file_name: "index.html",
resource_name: "admin-panel",
apply_auth_middleware: true,
},
ViewResourceDescriptor {
path_str: "admin-login",
index_file_name: "index.html",
resource_name: "admin-login",
apply_auth_middleware: false,
},
ViewResourceDescriptor {
path_str: "404",
index_file_name: "404.html",
resource_name: "404",
apply_auth_middleware: false,
},
ViewResourceDescriptor {
path_str: "unauthorized",
index_file_name: "unauthorized.html",
resource_name: "unauthorized",
apply_auth_middleware: false,
},
])))
.wrap(NormalizePath::new(TrailingSlash::Trim))
// .app_data(JsonConfig::default().limit(1 << 25u8)) // Allow json payload to have size until ~32MB
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// REST API /////////////////////////////////////////////////////////////////////////////////////////////////
.service(admin_authentication)
.service(post_article)
.service(update_article)
.service(delete_article)
.service(get_articles_by_category)
.service(get_article)
.service(get_article_by_title)
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// STANDARD FILES ///////////////////////////////////////////////////////////////////////////////////////////
.service(resource("/favicon.ico").route(get().to(favicon)))
.service(resource("/robots.txt").route(get().to(robots)))
.service(resource("/sitemap.xml").route(get().to(sitemap)))
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// VIEWS ////////////////////////////////////////////////////////////////////////////////////////////////////
.service(
scope("/v")
.service(Files::new(
"/admin-panel/assets",
public_dir.join("views/admin-panel/assets"),
))
.service(Files::new(
"/admin-login/assets",
public_dir.join("views/admin-login/assets"),
))
// get_view will match any url to we put it at last
.service(get_view),
)
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// PUBLIC WEBSITE //////////////////////////////////////////////////////////////////////////////////////////////
.service(Files::new("/", &public_dir).index_file("index.html"))
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// empty 404 ////////////////////////////////////////////////////////////////////////////////////////////////
.default_service(to(|| {
HttpResponse::NotFound().body("<h1>404 - Page not found</h1>")
}))
})
.bind(format!("0.0.0.0:{}", env_var("SERVER_PORT").unwrap()))?
.bind_rustls(
format!("0.0.0.0:{}", env_var("SERVER_PORT_TLS").unwrap()),
get_tls_config(),
)?
.run()
.await
}