Migrate to actix

This commit is contained in:
Pierre HUBERT 2022-03-30 10:14:39 +02:00
parent d75242d213
commit 70df96f286
7 changed files with 613 additions and 1392 deletions

1915
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -6,12 +6,13 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
rocket = "0.5.0-rc.1" clap = { version = "3.1.6", features = ["derive", "env"] }
rocket_dyn_templates = { version = "0.1.0-rc.1", features = ["tera"] } actix-web = "4"
include_dir = "0.7.2" include_dir = "0.7.2"
log = "0.4.16" log = "0.4.16"
serde_json = "1.0.79" serde_json = "1.0.79"
env_logger = "0.9.0" env_logger = "0.9.0"
serde = { version = "1.0.136", features = ["derive"] } serde = { version = "1.0.136", features = ["derive"] }
bcrypt = "0.12.1" bcrypt = "0.12.1"
uuid = { version = "0.8.2", features = ["v4"] } uuid = { version = "0.8.2", features = ["v4"] }
mime_guess = "2.0.4"

View File

@ -1,22 +1,20 @@
use std::path::PathBuf; use std::path::Path;
use actix_web::{HttpResponse, web};
use include_dir::{Dir, include_dir}; use include_dir::{Dir, include_dir};
use rocket::http::{ContentType, Status};
/// Assets directory /// Assets directory
static ASSETS_DIR: Dir = include_dir!("$CARGO_MANIFEST_DIR/assets"); static ASSETS_DIR: Dir = include_dir!("$CARGO_MANIFEST_DIR/assets");
#[get("/<file..>")] pub async fn assets_route(path: web::Path<String>) -> HttpResponse {
pub fn assets_route(file: PathBuf) -> (Status, (ContentType, &'static [u8])) { let path: &Path = path.as_ref().as_ref();
match ASSETS_DIR.get_file(file) { match ASSETS_DIR.get_file(path) {
None => None => HttpResponse::NotFound().body("404 Not found"),
(Status::NotFound, (ContentType::Text, "404 Not found".as_bytes())),
Some(file) => { Some(file) => {
(Status::Ok, ( let res = mime_guess::from_path(path).first_or_octet_stream();
ContentType::from_extension(file.path().extension().unwrap_or_default() HttpResponse::Ok()
.to_string_lossy().as_ref()) .content_type(res.to_string())
.unwrap_or(ContentType::Binary), .body(file.contents())
file.contents()))
} }
} }
} }

View File

@ -1,11 +1,20 @@
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use rocket::serde::Deserialize;
use clap::Parser;
use crate::constants::USERS_LIST_FILE; use crate::constants::USERS_LIST_FILE;
#[derive(Debug, Deserialize)] /// Basic OIDC provider
#[serde(crate = "rocket::serde")] #[derive(Parser, Debug)]
#[clap(author, version, about, long_about = None)]
pub struct AppConfig { pub struct AppConfig {
storage_path: PathBuf, /// Listen address
#[clap(short, long, env, default_value = "0.0.0.0:8000")]
pub listen_address: String,
/// Storage path
#[clap(short, long, env)]
pub storage_path: String,
} }
impl AppConfig { impl AppConfig {
@ -14,6 +23,6 @@ impl AppConfig {
} }
pub fn users_file(&self) -> PathBuf { pub fn users_file(&self) -> PathBuf {
self.storage_path.join(USERS_LIST_FILE) self.storage_path().join(USERS_LIST_FILE)
} }
} }

View File

@ -7,7 +7,7 @@ pub struct EntityManager<E> {
list: Vec<E>, list: Vec<E>,
} }
impl<E> EntityManager<E> where E: rocket::serde::Serialize + rocket::serde::DeserializeOwned + Eq + Clone { impl<E> EntityManager<E> where E: serde::Serialize + serde::de::DeserializeOwned + Eq + Clone {
/// Open entity /// Open entity
pub fn open_or_create<A: AsRef<Path>>(path: A) -> Res<Self> { pub fn open_or_create<A: AsRef<Path>>(path: A) -> Res<Self> {
if !path.as_ref().is_file() { if !path.as_ref().is_file() {

View File

@ -1,7 +1,3 @@
#[macro_use]
extern crate rocket;
pub mod data; pub mod data;
pub mod utils; pub mod utils;
pub mod constants; pub mod constants;

View File

@ -1,31 +1,22 @@
#[macro_use] use actix_web::{App, HttpServer, web, get};
extern crate rocket; use clap::Parser;
use rocket::fairing::AdHoc;
use basic_oidc::constants::{DEFAULT_ADMIN_PASSWORD, DEFAULT_ADMIN_USERNAME}; use basic_oidc::constants::{DEFAULT_ADMIN_PASSWORD, DEFAULT_ADMIN_USERNAME};
use basic_oidc::controllers::assets_controller::assets_route;
use basic_oidc::data::app_config::AppConfig; use basic_oidc::data::app_config::AppConfig;
use basic_oidc::data::entity_manager::EntityManager; use basic_oidc::data::entity_manager::EntityManager;
use basic_oidc::data::user::{hash_password, User}; use basic_oidc::data::user::{hash_password, User};
use basic_oidc::controllers::assets_controller::assets_route;
#[get("/health")] #[get("/health")]
fn index() -> &'static str { async fn health() -> &'static str {
"Running" "Running"
} }
#[rocket::main] #[actix_web::main]
async fn main() -> Result<(), rocket::Error> { async fn main() -> std::io::Result<()> {
//env_logger::init_from_env(env_logger::Env::new().default_filter_or("info")); env_logger::init_from_env(env_logger::Env::new().default_filter_or("info"));
let rocket = rocket::build() let config: AppConfig = AppConfig::parse();
.mount("/", routes![index])
.mount("/assets", routes![assets_route])
.attach(AdHoc::config::<AppConfig>());
let figment = rocket.figment();
// Initialize application
let config: AppConfig = figment.extract().expect("config");
if !config.storage_path().exists() { if !config.storage_path().exists() {
log::error!( log::error!(
@ -55,5 +46,14 @@ async fn main() -> Result<(), rocket::Error> {
.expect("Failed to create initial user!"); .expect("Failed to create initial user!");
} }
rocket.launch().await log::info!("Server will listen on {}", config.listen_address);
HttpServer::new(|| {
App::new()
.service(health)
.route("/assets/{path:.*}", web::get().to(assets_route))
})
.bind(config.listen_address)?
.run()
.await
} }