From fc0a3684af98bbc610752505207ce20b3bdbdcc5 Mon Sep 17 00:00:00 2001 From: JesusPerez Date: Wed, 1 Sep 2021 19:30:10 +0100 Subject: [PATCH] chore: add app_auth_handlers --- app_auth_handlers/.gitignore | 10 ++ app_auth_handlers/Cargo.toml | 55 +++++++++++ app_auth_handlers/README.md | 13 +++ app_auth_handlers/TODO.md | 4 + app_auth_handlers/src/lib.rs | 186 +++++++++++++++++++++++++++++++++++ 5 files changed, 268 insertions(+) create mode 100644 app_auth_handlers/.gitignore create mode 100644 app_auth_handlers/Cargo.toml create mode 100644 app_auth_handlers/README.md create mode 100644 app_auth_handlers/TODO.md create mode 100644 app_auth_handlers/src/lib.rs diff --git a/app_auth_handlers/.gitignore b/app_auth_handlers/.gitignore new file mode 100644 index 0000000..c3a29c2 --- /dev/null +++ b/app_auth_handlers/.gitignore @@ -0,0 +1,10 @@ +/target +target +Cargo.lock +.cache +.temp +.env +*.log +.DS_Store +logs +tmp diff --git a/app_auth_handlers/Cargo.toml b/app_auth_handlers/Cargo.toml new file mode 100644 index 0000000..6275dcd --- /dev/null +++ b/app_auth_handlers/Cargo.toml @@ -0,0 +1,55 @@ +[package] +name = "app_auth_handlers" +version = "0.1.0" +authors = ["JesusPerez "] +edition = "2018" +publish = false + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +anyhow = "1.0.40" +base64 = "0.13.0" +casbin = "2.0.7" +chrono = "0.4" +dotenv = "0.15.0" +envmnt = "0.9.0" +error-chain = "0.12.4" +glob = "0.3.0" +json = "0.12.4" +once_cell = "1.7.2" +parking_lot = "0.11.1" +rand = "0.8.3" +regex = "1.4.3" +serde = { version = "1.0", features = ["derive"] } +serde_derive = "1.0.125" +serde_json = "1.0.64" +serde_yaml = "0.8.17" +slab = "0.4.3" +tempfile = "3.2.0" +tera = "1.8.0" +thiserror = "1.0.24" +toml = "0.5.8" +yaml-rust = "0.4" +tokio = { version = "1.5.0", features = ["full"] } +uuid = { version = "0.8", features = ["serde", "v4"] } +url = "2.2.1" +warp = { version = "0.3", features = ["default","websocket","tls","compression"] } +app_tools = { version = "0.1.0", path = "../../utils/app_tools" } +app_env = { version = "0.1.0", path = "../../defs/app_env" } +app_auth = { version = "0.1.0", path = "../../defs/app_auth" } +reqtasks = { version = "0.1.0", path = "../reqtasks" } + +[dev-dependencies] +pretty_env_logger = "0.4" +tracing-subscriber = "0.2.15" +tracing-log = "0.1" +serde_derive = "1.0.125" +handlebars = "3.0.0" +tokio = { version = "1.5.0", features = ["macros", "rt-multi-thread"] } +tokio-stream = { version = "0.1.5", features = ["net"] } +listenfd = "0.3" +envmnt = "0.9.0" + +[build-dependencies] +envmnt = "0.9.0" diff --git a/app_auth_handlers/README.md b/app_auth_handlers/README.md new file mode 100644 index 0000000..e5359eb --- /dev/null +++ b/app_auth_handlers/README.md @@ -0,0 +1,13 @@ +# App auth handlers library + +Handlers for request for auth management using [warp](https://github.com/seanmonstar/warp) + +## handlers + +- member_handler +- admin_handler + +- login_handler +- loginin_handler +- logout_handler + \ No newline at end of file diff --git a/app_auth_handlers/TODO.md b/app_auth_handlers/TODO.md new file mode 100644 index 0000000..4d72ce2 --- /dev/null +++ b/app_auth_handlers/TODO.md @@ -0,0 +1,4 @@ +# App auth handlers library + +- [ ] Review & test + diff --git a/app_auth_handlers/src/lib.rs b/app_auth_handlers/src/lib.rs new file mode 100644 index 0000000..937bc4a --- /dev/null +++ b/app_auth_handlers/src/lib.rs @@ -0,0 +1,186 @@ +use app_auth::{AppAuthDBs, AuthError, UserCtx, WebResult, LoginRequest, CheckinRequest }; +// use uuid::Uuid; +use std::collections::HashMap; + +use reqtasks::ReqTasks; +use app_env::profile::Profile; + +use warp::{ + http::{method::Method, HeaderMap, HeaderValue, StatusCode}, + Reply, Rejection // , reject, +}; + +#[allow(clippy::missing_errors_doc)] +pub async fn member_handler(user_ctx: UserCtx) -> WebResult { + Ok(format!("Member with id {}", user_ctx.user_id)) +} + +#[allow(clippy::missing_errors_doc)] +pub async fn admin_handler(user_ctx: UserCtx) -> WebResult { + Ok(format!("Admin with id {}", user_ctx.user_id)) +} + +#[allow(clippy::missing_errors_doc)] +pub async fn login_handler ( + header: HeaderMap, + method: Method, + db: AppAuthDBs +) -> Result { + let reqenv = ReqTasks::new(db.app, db.auth, header, method, "", "login_header", "auth",); + let lang = reqenv.lang(); + let mut ctx = reqenv.ctx(); + let req_module = ""; + let app_module: &str; + if ! req_module.is_empty() && req_module != reqenv.config().default_module.as_str() { + app_module = req_module; + } else { + app_module = ""; + } + let mut data_hash: HashMap = HashMap::new(); + data_hash.insert("lang".to_string(), lang.to_owned()); + // let allow_origin = reqenv.config().allow_origin; + // let mut res = String::from(""); + // let res = if let Some(name) = query.get("name") { + // submitted form + match reqenv + .render_page( + &mut ctx, + reqenv.config().templates_path.as_str(), + "login/index.html", + "index.html", + format!("login/{}.toml", lang.to_owned()) + .to_owned() + .as_str(), + &mut data_hash, + app_module, + ) + .await { + Ok(page) => + Ok(warp::http::Response::builder() + .body(page) + .into_response()), + /* + Ok(warp::reply::with_header( + warp::http::Response::new(page), + // "Access-Control-Allow-Origin", + // &allow_origin)), + */ + Err(err) => + Ok(warp::http::Response::builder() + .body(err.to_string()) + .into_response()), + /* + Ok(warp::reply::with_header( + warp::http::Response::new(err.to_string()), + "Access-Control-Allow-Origin", + &allow_origin)), + */ + } +} +#[allow(clippy::missing_errors_doc)] +pub async fn loginin_handler( + body: LoginRequest, + header: HeaderMap, + method: Method, + db: AppAuthDBs, +) -> Result { + let reqenv = ReqTasks::new(db.app, db.auth, header, method, "/loginin", "loginin_header", "auth",); + let prfx = "ui"; +// ) -> WebResult { + // let name = body.name; + // println!("{}", &name); + // dbg!(&reqenv.auth_store.users.read().await); + // let allow_origin = reqenv.config().allow_origin; + match &reqenv.token_session(&body).await { + Ok(token) => // Ok(token.to_string()),o + match reqenv.check_authentication(token.to_owned()).await { + Ok(usrctx) => { + let mut path = format!("{}/profiles/{}/{}/defs.yaml",reqenv.config().resources_path,&body.mapkey,&usrctx.user_id); + if ! std::path::Path::new(&path).exists() { + path = format!("{}/profiles/{}/defs.yaml",reqenv.config().resources_path,&prfx); + } + let content = Profile::load_fs_content(path.into()); + // let lang = opts.lang.unwrap_or_else(|| String::from("es")); + // let section = opts.section.unwrap_or_else(|| String::from("")); + // let lang_items = LangItems::new("langs/ta",&lang,"yaml"); + // let result = lang_items.get_items_str(§ion); + let res = Profile::to_yaml(content); // String::from(""); + let str_defs = serde_json::to_string(&res).unwrap_or_else(|_| String::from("")); + Ok(warp::http::Response::builder() + // .header("Access-Control-Allow-Origin",&allow_origin) + .body(format!("{{ \"token\": \"{}\", \"defs\": {}}}",&token,&str_defs)) + .into_response()) + }, + Err(_e) => { + Ok(warp::http::Response::builder() + .status(StatusCode::NOT_FOUND) + // .header("Access-Control-Allow-Origin",&allow_origin) + .body(AuthError::UserNotFoundError.to_string()) + .into_response()) + } + }, + Err(_) => + Ok(warp::http::Response::builder() + .status(StatusCode::NOT_FOUND) + // .header("Access-Control-Allow-Origin",&allow_origin) + .body(AuthError::UserNotFoundError.to_string()) + .into_response()) + // Err(reject::custom(AuthError::UserNotFoundError)) + } +} +#[allow(clippy::missing_errors_doc)] +pub async fn checkin_handler( + body: CheckinRequest, + header: HeaderMap, + method: Method, + db: AppAuthDBs, +) -> Result { + let reqenv = ReqTasks::new(db.app, db.auth, header, method, "/checkin", "checkin_header", "auth",); +// ) -> WebResult { + // let name = &body.data; + // println!("{}", &name); + //dbg!("{}", &body); + // dbg!(&reqenv.auth_store.users.read().await); + // let allow_origin = reqenv.config().allow_origin; + match &reqenv.check_authentication(body.data.to_owned()).await { + Ok(usrctx) => { // Ok(token.to_string()), + let mut path = format!("{}/profiles/{}/{}/defs.yaml",reqenv.config().resources_path,&body.mapkey,&usrctx.user_id); + if ! std::path::Path::new(&path).exists() { + path = format!("{}/profiles/{}/defs.yaml",reqenv.config().resources_path,&body.mapkey); + } + let content = Profile::load_fs_content(path.into()); + let res = Profile::to_yaml(content); + let str_defs = serde_json::to_string(&res).unwrap_or_else(|_| String::from("")); + Ok(warp::http::Response::builder() + // .header("Access-Control-Allow-Origin",&allow_origin) + .body(format!("{{ \"token\": \"{}\", \"defs\": {}}}",&body.data,&str_defs)) + .into_response()) + }, + Err(_) => + Ok(warp::http::Response::builder() + .status(StatusCode::NOT_FOUND) + //.header("Access-Control-Allow-Origin",&allow_origin) + .body(AuthError::UserNotFoundError.to_string()) + .into_response()) + // Err(reject::custom(AuthError::UserNotFoundError)) + } +} + +#[allow(clippy::missing_errors_doc,clippy::unnecessary_operation)] +pub async fn logout_handler( + user_ctx: UserCtx, + header: HeaderMap, + method: Method, + db: AppAuthDBs, +) -> Result { +//-> WebResult { + let reqenv = ReqTasks::new(db.app, db.auth, header, method, "", "logout_header", "auth",); + // let allow_origin = reqenv.config().allow_origin; + &reqenv.auth_store.sessions.write().await.remove(&user_ctx.token); + Ok(warp::http::Response::builder() + .status(StatusCode::OK) + //.header("Access-Control-Allow-Origin",&allow_origin) + .body("success".to_string()) + .into_response()) +} +