chore: add app_file
This commit is contained in:
parent
82061f4a8d
commit
06846cc8f9
24
README.md
24
README.md
@ -56,7 +56,6 @@ An authorization library based in [Casbin](https://casbin.org/) [Rust library](h
|
||||
|
||||
<pre>
|
||||
app_auth/
|
||||
├── Cargo.lock
|
||||
├── Cargo.toml
|
||||
├── README.md
|
||||
├── TODO.md
|
||||
@ -70,8 +69,9 @@ Dedicated to load configuration, enviroment settings, profiles, collections, etc
|
||||
|
||||
<pre>
|
||||
app_env/
|
||||
├── Cargo.lock
|
||||
├── Cargo.toml
|
||||
├── README.md
|
||||
├── TODO.md
|
||||
└── src
|
||||
├── appdata.rs
|
||||
├── appenv.rs
|
||||
@ -88,7 +88,6 @@ Define common applications errors
|
||||
|
||||
<pre>
|
||||
app_errors/
|
||||
├── Cargo.lock
|
||||
├── Cargo.toml
|
||||
├── README.md
|
||||
├── TODO.md
|
||||
@ -102,7 +101,6 @@ To handle common application files and storages.
|
||||
|
||||
<pre>
|
||||
app_file/
|
||||
├── Cargo.lock
|
||||
├── Cargo.toml
|
||||
├── README.md
|
||||
├── TODO.md
|
||||
@ -115,17 +113,17 @@ app_file/
|
||||
Basic definitions and utilities
|
||||
|
||||
<pre>
|
||||
kloud/
|
||||
├── Cargo.lock
|
||||
kloud
|
||||
├── Cargo.toml
|
||||
├── README.md
|
||||
├── TODO.md
|
||||
└── src
|
||||
├── datacontext.rs
|
||||
├── defs.rs
|
||||
├── lang.rs
|
||||
├── lib.rs
|
||||
└── utils.rs
|
||||
├── src
|
||||
│ ├── datacontext.rs
|
||||
│ ├── defs.rs
|
||||
│ ├── kloud.rs
|
||||
│ ├── lang.rs
|
||||
│ ├── lib.rs
|
||||
│ └── utils.rs
|
||||
</pre>
|
||||
|
||||
## Author
|
||||
@ -134,4 +132,4 @@ kloud/
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
MIT
|
||||
|
10
app_file/.gitignore
vendored
Normal file
10
app_file/.gitignore
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
/target
|
||||
target
|
||||
Cargo.lock
|
||||
.cache
|
||||
.temp
|
||||
.env
|
||||
*.log
|
||||
.DS_Store
|
||||
logs
|
||||
tmp
|
55
app_file/Cargo.toml
Normal file
55
app_file/Cargo.toml
Normal file
@ -0,0 +1,55 @@
|
||||
[package]
|
||||
name = "app_file"
|
||||
version = "0.1.0"
|
||||
authors = ["JesusPerez <jpl@jesusperez.pro>"]
|
||||
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 = "../app_env" }
|
||||
|
||||
[dev-dependencies]
|
||||
pretty_env_logger = "0.4"
|
||||
tracing-subscriber = "0.2.15"
|
||||
tracing-log = "0.1"
|
||||
serde_derive = "1.0.125"
|
||||
handlebars = "4.1.2"
|
||||
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"
|
5
app_file/README.md
Normal file
5
app_file/README.md
Normal file
@ -0,0 +1,5 @@
|
||||
# App File library
|
||||
|
||||
This is **types** collection library
|
||||
|
||||
## app_file
|
3
app_file/TODO.md
Normal file
3
app_file/TODO.md
Normal file
@ -0,0 +1,3 @@
|
||||
# App File library
|
||||
|
||||
- [ ]
|
201
app_file/src/lib.rs
Normal file
201
app_file/src/lib.rs
Normal file
@ -0,0 +1,201 @@
|
||||
use std::collections::HashMap;
|
||||
use std::fs;
|
||||
use std::sync::Arc;
|
||||
use thiserror::Error;
|
||||
use serde::{Deserialize,Serialize};
|
||||
use tokio::sync::RwLock;
|
||||
use casbin::prelude::*;
|
||||
use warp::{Rejection};
|
||||
|
||||
use app_env::{AppStore,config::Config};
|
||||
use app_tools::{trim_newline,from_base64};
|
||||
|
||||
pub const BEARER_PREFIX: &str = "Bearer ";
|
||||
|
||||
pub type WebResult<T> = std::result::Result<T, Rejection>;
|
||||
|
||||
#[derive(Deserialize,Serialize,Clone,Debug,Default)]
|
||||
pub struct UserCtx {
|
||||
pub user_id: String,
|
||||
pub token: String,
|
||||
}
|
||||
|
||||
#[derive(Deserialize,Serialize,Clone,Debug,Default)]
|
||||
pub struct User {
|
||||
pub user_id: String,
|
||||
pub name: String,
|
||||
pub role: String,
|
||||
}
|
||||
|
||||
#[derive(Deserialize,Serialize,Clone,Debug,Default)]
|
||||
pub struct UserShadow {
|
||||
pub user_id: String,
|
||||
pub passwd: String,
|
||||
}
|
||||
|
||||
|
||||
#[derive(Deserialize, Debug,Default)]
|
||||
pub struct LoginRequest {
|
||||
pub name: String,
|
||||
pub passwd: String,
|
||||
}
|
||||
|
||||
#[allow(clippy::pub_enum_variant_names)]
|
||||
#[derive(Error, Debug)]
|
||||
pub enum AuthError {
|
||||
#[error("error")]
|
||||
SomeError(),
|
||||
#[error("no authorization header found")]
|
||||
NoAuthHeaderFoundError,
|
||||
#[error("wrong authorization header format")]
|
||||
InvalidAuthHeaderFormatError,
|
||||
#[error("no user found for this token")]
|
||||
InvalidTokenError,
|
||||
#[error("error during authorization")]
|
||||
AuthorizationError,
|
||||
#[error("user is not unauthorized")]
|
||||
UnauthorizedError,
|
||||
#[error("no user found with this name")]
|
||||
UserNotFoundError,
|
||||
}
|
||||
// impl warp::reject::Reject for anyhow::Error {}
|
||||
impl warp::reject::Reject for AuthError {}
|
||||
|
||||
// impl From<::Error> for warp::reject::Rejection {}
|
||||
|
||||
// https://github.com/seanmonstar/warp/issues/307
|
||||
#[derive(Debug)]
|
||||
pub struct CustomReject(anyhow::Error);
|
||||
impl warp::reject::Reject for CustomReject {}
|
||||
|
||||
#[must_use]
|
||||
// pub(crate) fn custom_reject(error: impl Into<anyhow::Error>) -> warp::Rejection {
|
||||
pub fn custom_reject(error: impl Into<anyhow::Error>) -> warp::Rejection {
|
||||
warp::reject::custom(CustomReject(error.into()))
|
||||
}
|
||||
|
||||
pub type UserMap = Arc<RwLock<HashMap<String, User>>>;
|
||||
pub type UserShadowMap = Arc<RwLock<HashMap<String, UserShadow>>>;
|
||||
pub type Sessions = Arc<RwLock<HashMap<String, String>>>;
|
||||
pub type SharedEnforcer = Arc<Enforcer>;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct AuthStore {
|
||||
pub users: UserMap,
|
||||
pub shadows: UserShadowMap,
|
||||
pub sessions: Sessions,
|
||||
pub enforcer: Arc<casbin::Enforcer>, // SharedEnforcer,
|
||||
}
|
||||
|
||||
impl AuthStore {
|
||||
#[must_use]
|
||||
pub fn new(config: &Config, enforcer: SharedEnforcer) -> Self {
|
||||
Self {
|
||||
users: Arc::new(RwLock::new(AuthStore::create_user_map(config))),
|
||||
shadows: Arc::new(RwLock::new(AuthStore::create_shadows_map(config))),
|
||||
sessions: Arc::new(RwLock::new(HashMap::new())),
|
||||
enforcer,
|
||||
}
|
||||
}
|
||||
#[must_use]
|
||||
pub fn load_users_from_fs(store: &str,target: &str) -> HashMap<String, User> {
|
||||
let mut usrs_content = fs::read_to_string(target).unwrap_or_else(|_|String::from(""));
|
||||
trim_newline(&mut usrs_content);
|
||||
let data_content = from_base64(&usrs_content);
|
||||
if ! data_content.contains("role") {
|
||||
println!("Error no 'role' in users from store: {}", &store);
|
||||
return HashMap::new()
|
||||
}
|
||||
let usrs: HashMap<String, User> = toml::from_str(&data_content).unwrap_or_else(|e| {
|
||||
println!("Error loading users from store: {} error: {}", &store,e);
|
||||
HashMap::new()
|
||||
});
|
||||
usrs
|
||||
}
|
||||
#[must_use]
|
||||
pub fn load_shadows_from_fs(store: &str,target: &str) -> HashMap<String, UserShadow> {
|
||||
let mut shadow_content = fs::read_to_string(target).unwrap_or_else(|_|String::from(""));
|
||||
trim_newline(&mut shadow_content);
|
||||
let data_content = from_base64(&shadow_content);
|
||||
if ! data_content.contains("passwd") {
|
||||
println!("Error no 'passwd' in shadows from store: {}", &store);
|
||||
return HashMap::new()
|
||||
}
|
||||
let shadows: HashMap<String, UserShadow> = toml::from_str(&data_content).unwrap_or_else(|e| {
|
||||
println!("Error loading users shadows from store: {} error: {}", &store,e);
|
||||
HashMap::new()
|
||||
});
|
||||
shadows
|
||||
}
|
||||
#[must_use]
|
||||
pub fn create_user_map(config: &Config) -> HashMap<String, User> {
|
||||
// TODO load form YAML o CONFIG
|
||||
let mut usrs = HashMap::new();
|
||||
match config.usrs_store.as_str() {
|
||||
"fs" => {
|
||||
usrs = AuthStore::load_users_from_fs(&config.usrs_store,&config.usrs_store_target);
|
||||
if !usrs.is_empty() {
|
||||
println!("Users loaded successfully ({})", &usrs.len());
|
||||
}
|
||||
},
|
||||
_ => println!("Store {} not set for users store: ", config.usrs_store),
|
||||
}
|
||||
usrs
|
||||
}
|
||||
#[must_use]
|
||||
pub fn create_shadows_map(config: &Config) -> HashMap<String, UserShadow> {
|
||||
// TODO load form YAML o CONFIG
|
||||
let mut shadows = HashMap::new();
|
||||
match config.usrs_shadow_store.as_str() {
|
||||
"fs" => {
|
||||
shadows = AuthStore::load_shadows_from_fs(&config.usrs_shadow_store,&config.usrs_shadow_target);
|
||||
if !shadows.is_empty() {
|
||||
println!("Users info successfully ({})",&shadows.len());
|
||||
}
|
||||
},
|
||||
_ => println!("Store {} not set for shadow store: ", config.usrs_shadow_store),
|
||||
}
|
||||
shadows
|
||||
}
|
||||
// map.insert(
|
||||
// String::from("21"),
|
||||
// User {
|
||||
// user_id: String::from("21"),
|
||||
// name: String::from("herbert"),
|
||||
// role: String::from("member"),
|
||||
// },
|
||||
// );
|
||||
// map.insert(
|
||||
// String::from("100"),
|
||||
// User {
|
||||
// user_id: String::from("100"),
|
||||
// name: String::from("jesus"),
|
||||
// role: String::from("admin"),
|
||||
// },
|
||||
// );
|
||||
// map.insert(
|
||||
// String::from("1"),
|
||||
// User {
|
||||
// user_id: String::from("1"),
|
||||
// name: String::from("gordon"),
|
||||
// role: String::from("anonymous"),
|
||||
// },
|
||||
// );
|
||||
// map
|
||||
// }
|
||||
|
||||
pub async fn create_enforcer(model_path: &'static str, policy_path: &'static str) -> SharedEnforcer {
|
||||
// Arc::new(Enforcer::new(super::super::MODEL_PATH, super::super::POLICY_PATH)
|
||||
Arc::new(Enforcer::new(model_path, policy_path)
|
||||
.await
|
||||
.expect("can read casbin model and policy files")
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct AppAuthDBs {
|
||||
pub app: AppStore,
|
||||
pub auth: AuthStore,
|
||||
}
|
Loading…
Reference in New Issue
Block a user