You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
142 lines
4.2 KiB
142 lines
4.2 KiB
#![forbid(unsafe_code)]
|
|
#[macro_use]
|
|
extern crate diesel;
|
|
#[macro_use]
|
|
extern crate derive_new;
|
|
#[macro_use]
|
|
extern crate validators_derive;
|
|
#[macro_use]
|
|
extern crate diesel_derive_newtype;
|
|
|
|
mod actions;
|
|
mod errors;
|
|
mod middlewares;
|
|
pub mod models;
|
|
mod routes;
|
|
mod schema;
|
|
mod services;
|
|
mod types;
|
|
mod utils;
|
|
|
|
use actix_files as fs;
|
|
use actix_identity::{CookieIdentityPolicy, IdentityService};
|
|
use actix_web::web::ServiceConfig;
|
|
use actix_web::{cookie::SameSite, web, App, HttpServer};
|
|
use rand::Rng;
|
|
use serde::Deserialize;
|
|
use std::io;
|
|
use tracing_actix_web::TracingLogger;
|
|
|
|
use types::DbPool;
|
|
|
|
build_info::build_info!(pub fn get_build_info);
|
|
|
|
#[derive(Deserialize, Debug, Clone)]
|
|
#[serde(rename_all = "lowercase")]
|
|
pub enum LoggerFormat {
|
|
Json,
|
|
Pretty,
|
|
}
|
|
|
|
#[derive(Deserialize, Debug, Clone)]
|
|
pub struct EnvConfig {
|
|
pub database_url: String,
|
|
pub http_host: String,
|
|
#[serde(default = "default_hash_cost")]
|
|
pub hash_cost: u32,
|
|
pub logger_format: LoggerFormat,
|
|
}
|
|
|
|
#[derive(Deserialize, Debug, Clone)]
|
|
pub struct AppConfig {
|
|
pub hash_cost: u32,
|
|
}
|
|
|
|
#[derive(Clone)]
|
|
pub struct AppData {
|
|
pub config: AppConfig,
|
|
pub pool: DbPool,
|
|
}
|
|
|
|
pub fn default_hash_cost() -> u32 {
|
|
8
|
|
}
|
|
|
|
pub fn configure_app(app_data: AppData) -> Box<dyn Fn(&mut ServiceConfig)> {
|
|
Box::new(move |cfg: &mut ServiceConfig| {
|
|
cfg.data(app_data.clone())
|
|
.service(
|
|
web::scope("/api")
|
|
.service(
|
|
web::scope("/users")
|
|
.route(
|
|
"",
|
|
web::get().to(routes::users::get_all_users),
|
|
)
|
|
.route(
|
|
"/search",
|
|
web::get().to(routes::users::search_users),
|
|
)
|
|
.route("", web::post().to(routes::users::add_user))
|
|
.route(
|
|
"/{user_id}",
|
|
web::get().to(routes::users::get_user),
|
|
),
|
|
)
|
|
.route(
|
|
"/pagination",
|
|
web::get().to(routes::users::get_users_paginated),
|
|
)
|
|
.route(
|
|
"/build-info",
|
|
web::get().to(routes::misc::build_info_req),
|
|
),
|
|
)
|
|
// .route("/api/users/get", web::get().to(user_controller.get_user.into()))
|
|
.service(web::scope("/api/public")) // public endpoint - not implemented yet
|
|
.service(routes::auth::login)
|
|
.service(routes::auth::logout)
|
|
.service(routes::auth::index)
|
|
// .service(routes::users::add_user)
|
|
.service(fs::Files::new("/", "./static"));
|
|
})
|
|
}
|
|
|
|
//TODO: capture the panic in this method
|
|
pub fn id_service(
|
|
private_key: &[u8],
|
|
) -> actix_identity::IdentityService<CookieIdentityPolicy> {
|
|
IdentityService::new(
|
|
CookieIdentityPolicy::new(&private_key)
|
|
.name("my-app-auth")
|
|
.secure(false)
|
|
.same_site(SameSite::Lax),
|
|
)
|
|
}
|
|
|
|
pub async fn run(addr: String, app_data: AppData) -> io::Result<()> {
|
|
let bi = get_build_info();
|
|
let _ = tracing::info!(
|
|
"Starting {} {}",
|
|
bi.crate_info.name,
|
|
bi.crate_info.version
|
|
);
|
|
println!(
|
|
r#"
|
|
__ .__ .___
|
|
_____ _____/ |_|__|__ ___ __| _/____ _____ ____
|
|
\__ \ _/ ___\ __\ \ \/ / ______ / __ |/ __ \ / \ / _ \
|
|
/ __ \\ \___| | | |> < /_____/ / /_/ \ ___/| Y Y ( <_> )
|
|
(____ /\___ >__| |__/__/\_ \ \____ |\___ >__|_| /\____/
|
|
\/ \/ \/ \/ \/ \/
|
|
"#
|
|
);
|
|
let private_key = rand::thread_rng().gen::<[u8; 32]>();
|
|
let app = move || {
|
|
App::new()
|
|
.configure(configure_app(app_data.clone()))
|
|
.wrap(id_service(&private_key))
|
|
.wrap(TracingLogger)
|
|
};
|
|
HttpServer::new(app).bind(addr)?.run().await
|
|
}
|