1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
use ntex::http::{header, StatusCode};
use ntex::web::middleware::Logger;
use ntex::web::ServiceConfig;
use ntex::{web, web::Route as NtexRoute};
use ntex_cors::Cors;

use crate::helpers::responder::Responder;
use crate::http::middlewares::base_middleware::BaseMiddleware;

use crate::http::middlewares::Middleware;

pub struct Controller {
    pub path: String,
    pub handler: fn(cfg: &mut ServiceConfig),
}

pub struct Route {
    pub prefix: String,
    pub middlewares: Vec<Middleware>,
    pub controllers: Vec<Controller>,
}

pub fn register_routes(config: &mut ServiceConfig, routes: Vec<Route>) {
    log::debug!("discovering routes...");

    for route in routes {
        for controller in &route.controllers {
            let path = route.prefix.as_str().to_owned() + controller.path.as_str();
            log::debug!(
                "route group: {}",
                if path.is_empty() { "/" } else { path.as_str() }
            );

            if path.is_empty() {
                config.service(web::scope("").configure(controller.handler));
            } else if !route.middlewares.is_empty() {
                let total = route.middlewares.len();

                if total == 1 {
                    let scope = web::scope(path.as_str())
                        .wrap(BaseMiddleware::new(
                            route.middlewares.first().unwrap().clone(),
                        ))
                        .configure(controller.handler);
                    config.service(scope);
                } else if total == 2 {
                    let scope = web::scope(path.as_str())
                        .wrap(BaseMiddleware::new(
                            route.middlewares.first().unwrap().clone(),
                        ))
                        .wrap(BaseMiddleware::new(
                            route.middlewares.last().unwrap().clone(),
                        ))
                        .configure(controller.handler);
                    config.service(scope);
                } else {
                    let scope = web::scope(path.as_str())
                        .wrap(BaseMiddleware::new(
                            route.middlewares.first().unwrap().clone(),
                        ))
                        .wrap(BaseMiddleware::new(
                            route.middlewares.get(1).unwrap().clone(),
                        ))
                        .wrap(BaseMiddleware::new(
                            route.middlewares.last().unwrap().clone(),
                        ))
                        .configure(controller.handler);
                    config.service(scope);
                }
            } else {
                config.service(web::scope(path.as_str()).configure(controller.handler));
            }
        }
    }

    log::debug!("route discovery finished :)");
}

pub fn setup_logger() -> Logger {
    Logger::new("%{r}a \"%r7\" %s %b \"%{Referer}i\" \"%{User-Agent}i\" %T")
        .exclude("/favicon.ico")
        .exclude("/system/docker-health-check")
}

pub fn setup_cors(origins: Vec<String>) -> Cors {
    let mut cors = Cors::new();

    for origin in origins {
        cors = cors.allowed_origin(origin.as_str());
    }

    cors.allowed_methods(vec!["GET", "POST", "PUT", "PATCH", "DELETE"])
        .allowed_headers(vec![header::AUTHORIZATION, header::ACCEPT])
        .allowed_header(header::CONTENT_TYPE)
        .max_age(3600)
}

pub fn ntex_default_service() -> NtexRoute {
    web::to(|| async {
        Responder::message("Requested Resource(s) Not Found", StatusCode::NOT_FOUND)
    })
}

pub fn register_middlewares(_config: &mut ServiceConfig) {
    // for middleware in middlewares() {
    // }
}