Pour tout problème contactez-nous par mail : support@froggit.fr | La FAQ :grey_question: | Rejoignez-nous sur le Chat :speech_balloon:

Skip to content
Snippets Groups Projects
main.rs 5.71 KiB
Newer Older
Pierre Jarriges's avatar
Pierre Jarriges committed
//! # WEB SERVER FOR THE KUADRADO SOFTWARE WEBSITE
mod app_state;
mod crypto;
Pierre Jarriges's avatar
Pierre Jarriges committed
mod env;
Pierre Jarriges's avatar
Pierre Jarriges committed
mod init_admin;
mod middleware;
mod model;
mod service;
Pierre Jarriges's avatar
Pierre Jarriges committed
mod standard_static_files;
mod tls;
Pierre Jarriges's avatar
Pierre Jarriges committed
mod view;
mod view_resource;
Pierre Jarriges's avatar
Pierre Jarriges committed
use actix_files::Files;
use actix_web::{
Pierre Jarriges's avatar
Pierre Jarriges committed
    middleware::{normalize::TrailingSlash, Logger, NormalizePath},
    web::{get, resource, scope, to, Data},
Pierre Jarriges's avatar
Pierre Jarriges committed
    App, HttpResponse, HttpServer,
};
use actix_web_middleware_redirect_https::RedirectHTTPS;
Pierre Jarriges's avatar
Pierre Jarriges committed
use app_state::AppState;
Pierre Jarriges's avatar
Pierre Jarriges committed
use env::get_log_level;
use env_logger::Env;
Pierre Jarriges's avatar
Pierre Jarriges committed
use middleware::AuthenticatedAdminMiddleware;
Pierre Jarriges's avatar
Pierre Jarriges committed
use service::*;
Pierre Jarriges's avatar
Pierre Jarriges committed
use standard_static_files::{favicon, robots, sitemap};
use std::env::var as env_var;
use tls::get_tls_config;
Pierre Jarriges's avatar
Pierre Jarriges committed
use view::get_view;
use view_resource::{ViewResourceDescriptor, ViewResourceManager};
Pierre Jarriges's avatar
Pierre Jarriges committed

#[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");

Pierre Jarriges's avatar
Pierre Jarriges committed
    let app_state = AppState::with_default_admin_user().await;

Pierre Jarriges's avatar
Pierre Jarriges committed
    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())
Pierre Jarriges's avatar
Pierre Jarriges committed
            .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))
Pierre Jarriges's avatar
Pierre Jarriges committed
            // .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)
            .service(get_all_articles)
Pierre Jarriges's avatar
Pierre Jarriges committed
            /////////////////////////////////////////////////////////////////////////////////////////////////////////////
            // 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)))
            /////////////////////////////////////////////////////////////////////////////////////////////////////////////
Pierre Jarriges's avatar
Pierre Jarriges committed
            // 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),
            )
            /////////////////////////////////////////////////////////////////////////////////////////////////////////////
Pierre Jarriges's avatar
Pierre Jarriges committed
            // 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
}