diff --git a/Cargo.lock b/Cargo.lock index 0a9a73925..b309799a6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2944,6 +2944,7 @@ dependencies = [ "lazy_static", "log", "madmin", + "policy", "rand 0.8.5", "regex", "serde", @@ -4541,6 +4542,34 @@ dependencies = [ "miniz_oxide", ] +[[package]] +name = "policy" +version = "0.0.1" +dependencies = [ + "arc-swap", + "async-trait", + "base64-simd", + "common", + "crypto", + "futures", + "ipnetwork", + "itertools", + "jsonwebtoken", + "lazy_static", + "log", + "madmin", + "rand 0.8.5", + "regex", + "serde", + "serde_json", + "strum", + "test-case", + "thiserror 2.0.11", + "time", + "tokio", + "tracing", +] + [[package]] name = "polling" version = "3.7.4" @@ -5310,6 +5339,7 @@ dependencies = [ "mime_guess", "netif", "pin-project-lite", + "policy", "prost", "prost-build", "prost-types", diff --git a/Cargo.toml b/Cargo.toml index 72c912bdc..9e3e80616 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -42,6 +42,7 @@ flatbuffers = "24.12.23" futures = "0.3.31" futures-util = "0.3.31" common = { path = "./common/common" } +policy = {path = "./policy"} hex = "0.4.3" hyper = "1.6.0" hyper-util = { version = "0.1.10", features = [ diff --git a/e2e_test/src/reliant/node_interact_test.rs b/e2e_test/src/reliant/node_interact_test.rs index 1752be3bb..069bd448d 100644 --- a/e2e_test/src/reliant/node_interact_test.rs +++ b/e2e_test/src/reliant/node_interact_test.rs @@ -14,10 +14,7 @@ use protos::{ use rmp_serde::{Deserializer, Serializer}; use serde::{Deserialize, Serialize}; use std::{error::Error, io::Cursor}; -use tokio::io::AsyncWrite; use tokio::spawn; -use tokio::sync::mpsc; -use tonic::codegen::tokio_stream::wrappers::ReceiverStream; use tonic::codegen::tokio_stream::StreamExt; use tonic::Request; diff --git a/ecstore/src/peer.rs b/ecstore/src/peer.rs index ce153d042..5328cbc9b 100644 --- a/ecstore/src/peer.rs +++ b/ecstore/src/peer.rs @@ -95,7 +95,7 @@ impl S3PeerSys { for (i, client) in self.clients.iter().enumerate() { if let Some(v) = client.get_pools() { if v.contains(&pool_idx) { - per_pool_errs.push(errs[i].as_ref().map(|e| clone_err(e))); + per_pool_errs.push(errs[i].as_ref().map(clone_err)); } } } @@ -130,7 +130,7 @@ impl S3PeerSys { for (i, client) in self.clients.iter().enumerate() { if let Some(v) = client.get_pools() { if v.contains(&pool_idx) { - per_pool_errs.push(errs[i].as_ref().map(|e| clone_err(e))); + per_pool_errs.push(errs[i].as_ref().map(clone_err)); } } } @@ -781,7 +781,7 @@ pub async fn heal_bucket_local(bucket: &str, opts: &HealOpts) -> Result>(); + let errs_clone = errs.iter().map(|e| e.as_ref().map(clone_err)).collect::>(); futures.push(async move { if bs_clone.read().await[idx] == DRIVE_STATE_MISSING { info!("bucket not find, will recreate"); @@ -795,7 +795,7 @@ pub async fn heal_bucket_local(bucket: &str, opts: &HealOpts) -> Result], ignored_errs: &[Box]) - if let Some(&c) = error_counts.get(&max_err) { if let Some(&err_idx) = error_map.get(&max_err) { - let err = errs[err_idx].as_ref().map(|e| clone_err(e)); + let err = errs[err_idx].as_ref().map(clone_err); return (c, err); } diff --git a/ecstore/src/set_disk.rs b/ecstore/src/set_disk.rs index 142accb98..754681fe6 100644 --- a/ecstore/src/set_disk.rs +++ b/ecstore/src/set_disk.rs @@ -5429,7 +5429,7 @@ pub fn should_heal_object_on_disk( } } } - (false, err.as_ref().map(|e| clone_err(e))) + (false, err.as_ref().map(clone_err)) } async fn get_disks_info(disks: &[Option], eps: &[Endpoint]) -> Vec { diff --git a/ecstore/src/store.rs b/ecstore/src/store.rs index 4c86bd1c5..40e376aeb 100644 --- a/ecstore/src/store.rs +++ b/ecstore/src/store.rs @@ -665,7 +665,7 @@ impl ECStore { has_def_pool = true; if !is_err_object_not_found(err) && !is_err_version_not_found(err) { - return Err(clone_err(&err)); + return Err(clone_err(err)); } if pinfo.object_info.delete_marker && !pinfo.object_info.name.is_empty() { @@ -803,7 +803,7 @@ impl ECStore { } let _ = task.await; if let Some(err) = first_err.read().await.as_ref() { - return Err(clone_err(&err)); + return Err(clone_err(err)); } Ok(()) } @@ -1069,7 +1069,7 @@ impl Clone for PoolObjInfo { Self { index: self.index, object_info: self.object_info.clone(), - err: self.err.as_ref().map(|e| clone_err(e)), + err: self.err.as_ref().map(clone_err), } } } diff --git a/iam/Cargo.toml b/iam/Cargo.toml index fd4e85c47..5afc93c54 100644 --- a/iam/Cargo.toml +++ b/iam/Cargo.toml @@ -15,6 +15,7 @@ log.workspace = true time = { workspace = true, features = ["serde-human-readable"] } serde = { workspace = true, features = ["derive", "rc"] } ecstore = { path = "../ecstore" } +policy.workspace = true serde_json.workspace = true async-trait.workspace = true thiserror.workspace = true diff --git a/iam/src/cache.rs b/iam/src/cache.rs index b43944457..f16921162 100644 --- a/iam/src/cache.rs +++ b/iam/src/cache.rs @@ -7,14 +7,13 @@ use std::{ use arc_swap::{ArcSwap, AsRaw, Guard}; use log::warn; +use policy::{ + auth::UserIdentity, + policy::{Args, PolicyDoc}, +}; use time::OffsetDateTime; -use crate::{ - auth::UserIdentity, - policy::PolicyDoc, - store::{GroupInfo, MappedPolicy}, - sys::Args, -}; +use crate::store::{GroupInfo, MappedPolicy}; pub struct Cache { pub policy_docs: ArcSwap>, diff --git a/iam/src/error.rs b/iam/src/error.rs index f13b0da97..41b4f45d4 100644 --- a/iam/src/error.rs +++ b/iam/src/error.rs @@ -1,12 +1,11 @@ use ecstore::disk::error::clone_disk_err; use ecstore::disk::error::DiskError; - -use crate::policy; +use policy::policy::Error as PolicyError; #[derive(thiserror::Error, Debug)] pub enum Error { #[error(transparent)] - PolicyError(#[from] policy::Error), + PolicyError(#[from] PolicyError), #[error("ecsotre error: {0}")] EcstoreError(common::error::Error), diff --git a/iam/src/handler.rs b/iam/src/handler.rs deleted file mode 100644 index 1166c6874..000000000 --- a/iam/src/handler.rs +++ /dev/null @@ -1,154 +0,0 @@ -// use std::{borrow::Cow, collections::HashMap}; - -// use log::{info, warn}; - -// use crate::{ -// arn::ARN, -// auth::UserIdentity, -// cache::CacheInner, -// policy::{utils::get_values_from_claims, Args, Policy}, -// store::Store, -// Error, -// }; - -// pub(crate) struct Handler<'m, T> { -// cache: CacheInner, -// api: &'m T, -// roles: &'m HashMap>, -// } - -// impl<'m, T> Handler<'m, T> { -// pub fn new(cache: CacheInner, api: &'m T, roles: &'m HashMap>) -> Self { -// Self { cache, api, roles } -// } -// } - -// impl<'m, T> Handler<'m, T> -// where -// T: Store, -// { -// #[inline] -// fn get_user<'a>(&self, user_name: &'a str) -> Option<&UserIdentity> { -// self.cache -// .users -// .get(user_name) -// .or_else(|| self.cache.sts_accounts.get(user_name)) -// } - -// async fn get_policy(&self, name: &str, _groups: &[String]) -> crate::Result> { -// if name.is_empty() { -// return Err(Error::InvalidArgument); -// } - -// todo!() -// // self.api.policy_db_get(name, groups) -// } - -// /// 如果是临时用户,返回Ok(Some(partent_name))) -// /// 如果不是临时用户,返回Ok(None) -// fn is_temp_user<'a>(&self, user_name: &'a str) -> crate::Result> { -// let user = self -// .get_user(user_name) -// .ok_or_else(|| Error::NoSuchUser(user_name.to_owned()))?; - -// if user.credentials.is_temp() { -// Ok(Some(&user.credentials.parent_user)) -// } else { -// Ok(None) -// } -// } - -// /// 如果是临时用户,返回Ok(Some(partent_name))) -// /// 如果不是临时用户,返回Ok(None) -// fn is_service_account<'a>(&self, user_name: &'a str) -> crate::Result> { -// let user = self -// .get_user(user_name) -// .ok_or_else(|| Error::NoSuchUser(user_name.to_owned()))?; - -// if user.credentials.is_service_account() { -// Ok(Some(&user.credentials.parent_user)) -// } else { -// Ok(None) -// } -// } - -// // todo -// pub fn is_allowed_sts(&self, args: &Args, parent: &str) -> bool { -// warn!("unimplement is_allowed_sts"); -// false -// } - -// // todo -// pub async fn is_allowed_service_account<'a>(&self, args: &Args<'a>, parent: &str) -> bool { -// let Some(p) = args.claims.get(parent) else { -// return false; -// }; - -// if let Some(parent_in_chaim) = p.as_str() { -// if parent_in_chaim != parent { -// return false; -// } -// } else { -// return false; -// } - -// let is_owner_derived = parent == "rustfsadmin"; // todo ,使用全局变量 -// let role_arn = args.get_role_arn(); -// let mut svc_policies = None; - -// if is_owner_derived { -// } else if let Some(x) = role_arn { -// let Ok(arn) = x.parse::() else { -// info!("error parsing role ARN {x}"); -// return false; -// }; - -// svc_policies = self.roles.get(&arn).map(|x| Cow::from(x)); -// } else { -// let Ok(mut p) = self.get_policy(parent, &args.groups[..]).await else { return false }; -// if p.is_empty() { -// // todo iamPolicyClaimNameOpenID -// let (p1, _) = get_values_from_claims(&args.claims, ""); -// p = p1; -// } -// svc_policies = Some(Cow::Owned(p)); -// } - -// if is_owner_derived && svc_policies.as_ref().map(|x| x.as_ref().len()).unwrap_or_default() == 0 { -// return false; -// } - -// false -// } - -// pub async fn get_combined_policy(&self, _policies: &[String]) -> Policy { -// todo!() -// } - -// pub async fn is_allowed<'a>(&self, args: Args<'a>) -> bool { -// if args.is_owner { -// return true; -// } - -// match self.is_temp_user(&args.account) { -// Ok(Some(parent)) => return self.is_allowed_sts(&args, parent), -// Err(_) => return false, -// _ => {} -// } - -// match self.is_service_account(&args.account) { -// Ok(Some(parent)) => return self.is_allowed_service_account(&args, parent).await, -// Err(_) => return false, -// _ => {} -// } - -// let Ok(policies) = self.get_policy(&args.account, &args.groups).await else { return false }; - -// if policies.is_empty() { -// return false; -// } - -// let policy = self.get_combined_policy(&policies[..]).await; -// policy.is_allowed(&args) -// } -// } diff --git a/iam/src/lib.rs b/iam/src/lib.rs index f0844c227..88392bb98 100644 --- a/iam/src/lib.rs +++ b/iam/src/lib.rs @@ -1,23 +1,16 @@ -use auth::Credentials; use common::error::{Error, Result}; use ecstore::store::ECStore; use error::Error as IamError; use log::debug; use manager::IamCache; +use policy::auth::Credentials; use std::sync::{Arc, OnceLock}; use store::object::ObjectStore; use sys::IamSys; pub mod cache; -mod format; -mod handler; - -pub mod arn; -pub mod auth; pub mod error; pub mod manager; -pub mod policy; -pub mod service_type; pub mod store; pub mod utils; diff --git a/iam/src/manager.rs b/iam/src/manager.rs index 89cbec47f..ef855280a 100644 --- a/iam/src/manager.rs +++ b/iam/src/manager.rs @@ -1,15 +1,11 @@ use crate::{ - arn::ARN, - auth::{self, get_claims_from_token_with_secret, is_secret_key_valid, jwt_sign, Credentials, UserIdentity}, cache::{Cache, CacheEntity}, error::{is_err_no_such_group, is_err_no_such_policy, is_err_no_such_user, Error as IamError}, - format::Format, get_global_action_cred, - policy::{Policy, PolicyDoc, DEFAULT_POLICIES}, store::{object::IAM_CONFIG_PREFIX, GroupInfo, MappedPolicy, Store, UserType}, sys::{ - iam_policy_claim_name_sa, UpdateServiceAccountOpts, EMBEDDED_POLICY_TYPE, INHERITED_POLICY_TYPE, - MAX_SVCSESSION_POLICY_SIZE, SESSION_POLICY_NAME, SESSION_POLICY_NAME_EXTRACTED, STATUS_DISABLED, STATUS_ENABLED, + UpdateServiceAccountOpts, MAX_SVCSESSION_POLICY_SIZE, SESSION_POLICY_NAME, SESSION_POLICY_NAME_EXTRACTED, + STATUS_DISABLED, STATUS_ENABLED, }, }; use common::error::{Error, Result}; @@ -17,6 +13,12 @@ use ecstore::config::error::is_err_config_not_found; use ecstore::utils::{crypto::base64_encode, path::path_join_buf}; use log::{debug, warn}; use madmin::{AccountStatus, AddOrUpdateUserReq, GroupDesc}; +use policy::{ + arn::ARN, + auth::{self, get_claims_from_token_with_secret, is_secret_key_valid, jwt_sign, Credentials, UserIdentity}, + format::Format, + policy::{iam_policy_claim_name_sa, Policy, PolicyDoc, DEFAULT_POLICIES, EMBEDDED_POLICY_TYPE, INHERITED_POLICY_TYPE}, +}; use serde::{Deserialize, Serialize}; use serde_json::Value; use std::{ @@ -486,7 +488,6 @@ where if !is_secret_key_valid(&secret) { return Err(IamError::InvalidSecretKeyLength.into()); } - cr.secret_key = secret; } diff --git a/iam/src/policy.rs b/iam/src/policy.rs deleted file mode 100644 index e25dca909..000000000 --- a/iam/src/policy.rs +++ /dev/null @@ -1,49 +0,0 @@ -pub mod action; -mod doc; -mod effect; -mod function; -mod id; -#[allow(clippy::module_inception)] -mod policy; -pub mod resource; -pub mod statement; -pub(crate) mod utils; - -pub use action::ActionSet; -pub use doc::PolicyDoc; - -pub use effect::Effect; -pub use function::Functions; -pub use id::ID; -pub use policy::{default::DEFAULT_POLICIES, Policy}; -pub use resource::ResourceSet; - -pub use statement::Statement; - -#[derive(thiserror::Error, Debug)] -#[cfg_attr(test, derive(Eq, PartialEq))] -pub enum Error { - #[error("invalid Version '{0}'")] - InvalidVersion(String), - - #[error("invalid Effect '{0}'")] - InvalidEffect(String), - - #[error("both 'Action' and 'NotAction' are empty")] - NonAction, - - #[error("'Resource' is empty")] - NonResource, - - #[error("invalid key name: '{0}'")] - InvalidKeyName(String), - - #[error("invalid key: '{0}'")] - InvalidKey(String), - - #[error("invalid action: '{0}'")] - InvalidAction(String), - - #[error("invalid resource, type: '{0}', pattern: '{1}'")] - InvalidResource(String, String), -} diff --git a/iam/src/store.rs b/iam/src/store.rs index d993a2fb7..633ff2500 100644 --- a/iam/src/store.rs +++ b/iam/src/store.rs @@ -1,7 +1,8 @@ pub mod object; -use crate::{auth::UserIdentity, cache::Cache, policy::PolicyDoc}; +use crate::cache::Cache; use common::error::Result; +use policy::{auth::UserIdentity, policy::PolicyDoc}; use serde::{de::DeserializeOwned, Deserialize, Serialize}; use std::collections::{HashMap, HashSet}; use time::OffsetDateTime; diff --git a/iam/src/store/object.rs b/iam/src/store/object.rs index d4469abdd..20ab01289 100644 --- a/iam/src/store/object.rs +++ b/iam/src/store/object.rs @@ -1,11 +1,9 @@ use super::{GroupInfo, MappedPolicy, Store, UserType}; use crate::{ - auth::UserIdentity, cache::{Cache, CacheEntity}, error::{is_err_no_such_policy, is_err_no_such_user}, get_global_action_cred, manager::{extract_jwt_claims, get_default_policyes}, - policy::PolicyDoc, }; use common::error::{Error, Result}; use ecstore::{ @@ -21,6 +19,7 @@ use ecstore::{ }; use futures::future::join_all; use lazy_static::lazy_static; +use policy::{auth::UserIdentity, policy::PolicyDoc}; use serde::{de::DeserializeOwned, Serialize}; use std::{collections::HashMap, sync::Arc}; use tokio::sync::broadcast::{self, Receiver as B_Receiver}; diff --git a/iam/src/sys.rs b/iam/src/sys.rs index 8d83141a0..ee2a26b61 100644 --- a/iam/src/sys.rs +++ b/iam/src/sys.rs @@ -1,16 +1,3 @@ -use std::collections::HashMap; -use std::collections::HashSet; -use std::sync::Arc; - -use crate::arn::ARN; -use crate::auth::contains_reserved_chars; -use crate::auth::create_new_credentials_with_metadata; -use crate::auth::generate_credentials; -use crate::auth::is_access_key_valid; -use crate::auth::is_secret_key_valid; -use crate::auth::Credentials; -use crate::auth::UserIdentity; -use crate::auth::ACCOUNT_ON; use crate::error::is_err_no_such_account; use crate::error::is_err_no_such_temp_account; use crate::error::Error as IamError; @@ -18,9 +5,6 @@ use crate::get_global_action_cred; use crate::manager::extract_jwt_claims; use crate::manager::get_default_policyes; use crate::manager::IamCache; -use crate::policy::action::Action; -use crate::policy::Policy; -use crate::policy::PolicyDoc; use crate::store::MappedPolicy; use crate::store::Store; use crate::store::UserType; @@ -29,8 +13,25 @@ use ecstore::utils::crypto::base64_decode; use ecstore::utils::crypto::base64_encode; use madmin::AddOrUpdateUserReq; use madmin::GroupDesc; +use policy::arn::ARN; +use policy::auth::contains_reserved_chars; +use policy::auth::create_new_credentials_with_metadata; +use policy::auth::generate_credentials; +use policy::auth::is_access_key_valid; +use policy::auth::is_secret_key_valid; +use policy::auth::Credentials; +use policy::auth::UserIdentity; +use policy::auth::ACCOUNT_ON; +use policy::policy::iam_policy_claim_name_sa; +use policy::policy::Args; +use policy::policy::Policy; +use policy::policy::PolicyDoc; +use policy::policy::EMBEDDED_POLICY_TYPE; +use policy::policy::INHERITED_POLICY_TYPE; use serde_json::json; use serde_json::Value; +use std::collections::HashMap; +use std::sync::Arc; use time::OffsetDateTime; pub const MAX_SVCSESSION_POLICY_SIZE: usize = 4096; @@ -42,9 +43,6 @@ pub const POLICYNAME: &str = "policy"; pub const SESSION_POLICY_NAME: &str = "sessionPolicy"; pub const SESSION_POLICY_NAME_EXTRACTED: &str = "sessionPolicy-extracted"; -pub const EMBEDDED_POLICY_TYPE: &str = "embedded-policy"; -pub const INHERITED_POLICY_TYPE: &str = "inherited-policy"; - pub struct IamSys { store: Arc>, roles_map: HashMap, @@ -697,73 +695,3 @@ pub struct UpdateServiceAccountOpts { pub expiration: Option, pub status: Option, } - -pub fn iam_policy_claim_name_sa() -> String { - "sa-policy".to_string() -} - -/// DEFAULT_VERSION is the default version. -/// https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_version.html -pub const DEFAULT_VERSION: &str = "2012-10-17"; - -/// check the data is Validator -pub trait Validator { - type Error; - fn is_valid(&self) -> Result<()> { - Ok(()) - } -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct Args<'a> { - pub account: &'a str, - pub groups: &'a Option>, - pub action: Action, - pub bucket: &'a str, - pub conditions: &'a HashMap>, - pub is_owner: bool, - pub object: &'a str, - pub claims: &'a HashMap, - pub deny_only: bool, -} - -impl Args<'_> { - pub fn get_role_arn(&self) -> Option<&str> { - self.claims.get("roleArn").and_then(|x| x.as_str()) - } - pub fn get_policies(&self, policy_claim_name: &str) -> (HashSet, bool) { - get_policies_from_claims(self.claims, policy_claim_name) - } -} - -fn get_values_from_claims(claims: &HashMap, claim_name: &str) -> (HashSet, bool) { - let mut s = HashSet::new(); - if let Some(pname) = claims.get(claim_name) { - if let Some(pnames) = pname.as_array() { - for pname in pnames { - if let Some(pname_str) = pname.as_str() { - for pname in pname_str.split(',') { - let pname = pname.trim(); - if !pname.is_empty() { - s.insert(pname.to_string()); - } - } - } - } - return (s, true); - } else if let Some(pname_str) = pname.as_str() { - for pname in pname_str.split(',') { - let pname = pname.trim(); - if !pname.is_empty() { - s.insert(pname.to_string()); - } - } - return (s, true); - } - } - (s, false) -} - -fn get_policies_from_claims(claims: &HashMap, policy_claim_name: &str) -> (HashSet, bool) { - get_values_from_claims(claims, policy_claim_name) -} diff --git a/policy/Cargo.toml b/policy/Cargo.toml new file mode 100644 index 000000000..da2c4636c --- /dev/null +++ b/policy/Cargo.toml @@ -0,0 +1,36 @@ +[package] +name = "policy" +edition.workspace = true +license.workspace = true +repository.workspace = true +rust-version.workspace = true +version.workspace = true + +[lints] +workspace = true + +[dependencies] +tokio.workspace = true +log.workspace = true +time = { workspace = true, features = ["serde-human-readable"] } +serde = { workspace = true, features = ["derive", "rc"] } +serde_json.workspace = true +async-trait.workspace = true +thiserror.workspace = true +strum = { version = "0.27.1", features = ["derive"] } +arc-swap = "1.7.1" +crypto = { path = "../crypto" } +ipnetwork = { version = "0.21.1", features = ["serde"] } +itertools = "0.14.0" +futures.workspace = true +rand.workspace = true +base64-simd = "0.8.0" +jsonwebtoken = "9.3.0" +tracing.workspace = true +madmin.workspace = true +lazy_static.workspace = true +regex = "1.11.1" +common.workspace = true + +[dev-dependencies] +test-case.workspace = true diff --git a/iam/src/arn.rs b/policy/src/arn.rs similarity index 100% rename from iam/src/arn.rs rename to policy/src/arn.rs diff --git a/iam/src/auth.rs b/policy/src/auth.rs similarity index 100% rename from iam/src/auth.rs rename to policy/src/auth.rs diff --git a/iam/src/auth/credentials.rs b/policy/src/auth/credentials.rs similarity index 99% rename from iam/src/auth/credentials.rs rename to policy/src/auth/credentials.rs index 2313b10d4..9ce0c73ea 100644 --- a/iam/src/auth/credentials.rs +++ b/policy/src/auth/credentials.rs @@ -1,6 +1,5 @@ use crate::error::Error as IamError; -use crate::policy::Policy; -use crate::sys::{iam_policy_claim_name_sa, Validator, INHERITED_POLICY_TYPE}; +use crate::policy::{iam_policy_claim_name_sa, Policy, Validator, INHERITED_POLICY_TYPE}; use crate::utils; use crate::utils::extract_claims; use common::error::{Error, Result}; diff --git a/policy/src/error.rs b/policy/src/error.rs new file mode 100644 index 000000000..90c1f2c53 --- /dev/null +++ b/policy/src/error.rs @@ -0,0 +1,145 @@ +use crate::policy; + +#[derive(thiserror::Error, Debug)] +pub enum Error { + #[error(transparent)] + PolicyError(#[from] policy::Error), + + #[error("ecsotre error: {0}")] + EcstoreError(common::error::Error), + + #[error("{0}")] + StringError(String), + + #[error("crypto: {0}")] + CryptoError(#[from] crypto::Error), + + #[error("user '{0}' does not exist")] + NoSuchUser(String), + + #[error("account '{0}' does not exist")] + NoSuchAccount(String), + + #[error("service account '{0}' does not exist")] + NoSuchServiceAccount(String), + + #[error("temp account '{0}' does not exist")] + NoSuchTempAccount(String), + + #[error("group '{0}' does not exist")] + NoSuchGroup(String), + + #[error("policy does not exist")] + NoSuchPolicy, + + #[error("policy in use")] + PolicyInUse, + + #[error("group not empty")] + GroupNotEmpty, + + #[error("invalid arguments specified")] + InvalidArgument, + + #[error("not initialized")] + IamSysNotInitialized, + + #[error("invalid service type: {0}")] + InvalidServiceType(String), + + #[error("malformed credential")] + ErrCredMalformed, + + #[error("CredNotInitialized")] + CredNotInitialized, + + #[error("invalid access key length")] + InvalidAccessKeyLength, + + #[error("invalid secret key length")] + InvalidSecretKeyLength, + + #[error("access key contains reserved characters =,")] + ContainsReservedChars, + + #[error("group name contains reserved characters =,")] + GroupNameContainsReservedChars, + + #[error("jwt err {0}")] + JWTError(jsonwebtoken::errors::Error), + + #[error("no access key")] + NoAccessKey, + + #[error("invalid token")] + InvalidToken, + + #[error("invalid access_key")] + InvalidAccessKey, + #[error("action not allowed")] + IAMActionNotAllowed, + + #[error("invalid expiration")] + InvalidExpiration, + + #[error("no secret key with access key")] + NoSecretKeyWithAccessKey, + + #[error("no access key with secret key")] + NoAccessKeyWithSecretKey, + + #[error("policy too large")] + PolicyTooLarge, +} + +// pub fn is_err_no_such_user(e: &Error) -> bool { +// matches!(e, Error::NoSuchUser(_)) +// } + +pub fn is_err_no_such_policy(err: &common::error::Error) -> bool { + if let Some(e) = err.downcast_ref::() { + matches!(e, Error::NoSuchPolicy) + } else { + false + } +} + +pub fn is_err_no_such_user(err: &common::error::Error) -> bool { + if let Some(e) = err.downcast_ref::() { + matches!(e, Error::NoSuchUser(_)) + } else { + false + } +} + +pub fn is_err_no_such_account(err: &common::error::Error) -> bool { + if let Some(e) = err.downcast_ref::() { + matches!(e, Error::NoSuchAccount(_)) + } else { + false + } +} + +pub fn is_err_no_such_temp_account(err: &common::error::Error) -> bool { + if let Some(e) = err.downcast_ref::() { + matches!(e, Error::NoSuchTempAccount(_)) + } else { + false + } +} + +pub fn is_err_no_such_group(err: &common::error::Error) -> bool { + if let Some(e) = err.downcast_ref::() { + matches!(e, Error::NoSuchGroup(_)) + } else { + false + } +} + +pub fn is_err_no_such_service_account(err: &common::error::Error) -> bool { + if let Some(e) = err.downcast_ref::() { + matches!(e, Error::NoSuchServiceAccount(_)) + } else { + false + } +} diff --git a/iam/src/format.rs b/policy/src/format.rs similarity index 100% rename from iam/src/format.rs rename to policy/src/format.rs diff --git a/policy/src/lib.rs b/policy/src/lib.rs new file mode 100644 index 000000000..270aaa317 --- /dev/null +++ b/policy/src/lib.rs @@ -0,0 +1,7 @@ +pub mod arn; +pub mod auth; +pub mod error; +pub mod format; +pub mod policy; +pub mod service_type; +pub mod utils; diff --git a/policy/src/policy.rs b/policy/src/policy.rs new file mode 100644 index 000000000..04e9fd998 --- /dev/null +++ b/policy/src/policy.rs @@ -0,0 +1,128 @@ +pub mod action; +mod doc; +mod effect; +mod function; +mod id; +#[allow(clippy::module_inception)] +mod policy; +pub mod resource; +pub mod statement; +pub(crate) mod utils; + +use std::collections::{HashMap, HashSet}; + +use action::Action; +pub use action::ActionSet; +pub use doc::PolicyDoc; + +pub use effect::Effect; +pub use function::Functions; +pub use id::ID; +pub use policy::{default::DEFAULT_POLICIES, Policy}; +pub use resource::ResourceSet; + +use serde_json::Value; +pub use statement::Statement; + +use common::error::Result; + +pub const EMBEDDED_POLICY_TYPE: &str = "embedded-policy"; +pub const INHERITED_POLICY_TYPE: &str = "inherited-policy"; + +#[derive(thiserror::Error, Debug)] +#[cfg_attr(test, derive(Eq, PartialEq))] +pub enum Error { + #[error("invalid Version '{0}'")] + InvalidVersion(String), + + #[error("invalid Effect '{0}'")] + InvalidEffect(String), + + #[error("both 'Action' and 'NotAction' are empty")] + NonAction, + + #[error("'Resource' is empty")] + NonResource, + + #[error("invalid key name: '{0}'")] + InvalidKeyName(String), + + #[error("invalid key: '{0}'")] + InvalidKey(String), + + #[error("invalid action: '{0}'")] + InvalidAction(String), + + #[error("invalid resource, type: '{0}', pattern: '{1}'")] + InvalidResource(String, String), +} + +/// DEFAULT_VERSION is the default version. +/// https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_version.html +pub const DEFAULT_VERSION: &str = "2012-10-17"; + +/// check the data is Validator +pub trait Validator { + type Error; + fn is_valid(&self) -> Result<()> { + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct Args<'a> { + pub account: &'a str, + pub groups: &'a Option>, + pub action: Action, + pub bucket: &'a str, + pub conditions: &'a HashMap>, + pub is_owner: bool, + pub object: &'a str, + pub claims: &'a HashMap, + pub deny_only: bool, +} + +impl Args<'_> { + pub fn get_role_arn(&self) -> Option<&str> { + self.claims.get("roleArn").and_then(|x| x.as_str()) + } + pub fn get_policies(&self, policy_claim_name: &str) -> (HashSet, bool) { + get_policies_from_claims(self.claims, policy_claim_name) + } +} + +fn get_values_from_claims(claims: &HashMap, claim_name: &str) -> (HashSet, bool) { + let mut s = HashSet::new(); + if let Some(pname) = claims.get(claim_name) { + if let Some(pnames) = pname.as_array() { + for pname in pnames { + if let Some(pname_str) = pname.as_str() { + for pname in pname_str.split(',') { + let pname = pname.trim(); + if !pname.is_empty() { + s.insert(pname.to_string()); + } + } + } + } + return (s, true); + } else if let Some(pname_str) = pname.as_str() { + for pname in pname_str.split(',') { + let pname = pname.trim(); + if !pname.is_empty() { + s.insert(pname.to_string()); + } + } + return (s, true); + } + } + (s, false) +} + +fn get_policies_from_claims(claims: &HashMap, policy_claim_name: &str) -> (HashSet, bool) { + get_values_from_claims(claims, policy_claim_name) +} + +pub fn iam_policy_claim_name_sa() -> String { + "sa-policy".to_string() +} diff --git a/iam/src/policy/action.rs b/policy/src/policy/action.rs similarity index 99% rename from iam/src/policy/action.rs rename to policy/src/policy/action.rs index 8061c8d42..7ce762f95 100644 --- a/iam/src/policy/action.rs +++ b/policy/src/policy/action.rs @@ -3,9 +3,7 @@ use serde::{Deserialize, Serialize}; use std::{collections::HashSet, ops::Deref}; use strum::{EnumString, IntoStaticStr}; -use crate::sys::Validator; - -use super::{utils::wildcard, Error as IamError}; +use super::{utils::wildcard, Error as IamError, Validator}; #[derive(Serialize, Deserialize, Clone, Default, Debug)] pub struct ActionSet(pub HashSet); diff --git a/iam/src/policy/doc.rs b/policy/src/policy/doc.rs similarity index 100% rename from iam/src/policy/doc.rs rename to policy/src/policy/doc.rs diff --git a/iam/src/policy/effect.rs b/policy/src/policy/effect.rs similarity index 96% rename from iam/src/policy/effect.rs rename to policy/src/policy/effect.rs index e815fa4ff..04e6c8a2b 100644 --- a/iam/src/policy/effect.rs +++ b/policy/src/policy/effect.rs @@ -2,7 +2,7 @@ use common::error::{Error, Result}; use serde::{Deserialize, Serialize}; use strum::{EnumString, IntoStaticStr}; -use crate::sys::Validator; +use super::Validator; #[derive(Serialize, Clone, Deserialize, EnumString, IntoStaticStr, Default, Debug, PartialEq)] #[serde(try_from = "&str", into = "&str")] diff --git a/iam/src/policy/function.rs b/policy/src/policy/function.rs similarity index 100% rename from iam/src/policy/function.rs rename to policy/src/policy/function.rs diff --git a/iam/src/policy/function/addr.rs b/policy/src/policy/function/addr.rs similarity index 100% rename from iam/src/policy/function/addr.rs rename to policy/src/policy/function/addr.rs diff --git a/iam/src/policy/function/binary.rs b/policy/src/policy/function/binary.rs similarity index 100% rename from iam/src/policy/function/binary.rs rename to policy/src/policy/function/binary.rs diff --git a/iam/src/policy/function/bool_null.rs b/policy/src/policy/function/bool_null.rs similarity index 100% rename from iam/src/policy/function/bool_null.rs rename to policy/src/policy/function/bool_null.rs diff --git a/iam/src/policy/function/condition.rs b/policy/src/policy/function/condition.rs similarity index 100% rename from iam/src/policy/function/condition.rs rename to policy/src/policy/function/condition.rs diff --git a/iam/src/policy/function/date.rs b/policy/src/policy/function/date.rs similarity index 100% rename from iam/src/policy/function/date.rs rename to policy/src/policy/function/date.rs diff --git a/iam/src/policy/function/func.rs b/policy/src/policy/function/func.rs similarity index 100% rename from iam/src/policy/function/func.rs rename to policy/src/policy/function/func.rs diff --git a/iam/src/policy/function/key.rs b/policy/src/policy/function/key.rs similarity index 98% rename from iam/src/policy/function/key.rs rename to policy/src/policy/function/key.rs index 1f674b972..f4cde5093 100644 --- a/iam/src/policy/function/key.rs +++ b/policy/src/policy/function/key.rs @@ -1,5 +1,5 @@ use super::key_name::KeyName; -use crate::{policy::Error as PolicyError, sys::Validator}; +use crate::policy::{Error as PolicyError, Validator}; use common::error::Error; use serde::{Deserialize, Serialize}; diff --git a/iam/src/policy/function/key_name.rs b/policy/src/policy/function/key_name.rs similarity index 100% rename from iam/src/policy/function/key_name.rs rename to policy/src/policy/function/key_name.rs diff --git a/iam/src/policy/function/number.rs b/policy/src/policy/function/number.rs similarity index 100% rename from iam/src/policy/function/number.rs rename to policy/src/policy/function/number.rs diff --git a/iam/src/policy/function/string.rs b/policy/src/policy/function/string.rs similarity index 100% rename from iam/src/policy/function/string.rs rename to policy/src/policy/function/string.rs diff --git a/iam/src/policy/id.rs b/policy/src/policy/id.rs similarity index 95% rename from iam/src/policy/id.rs rename to policy/src/policy/id.rs index 19a589907..2f314ab42 100644 --- a/iam/src/policy/id.rs +++ b/policy/src/policy/id.rs @@ -2,7 +2,7 @@ use common::error::{Error, Result}; use serde::{Deserialize, Serialize}; use std::ops::Deref; -use crate::sys::Validator; +use super::Validator; #[derive(Serialize, Deserialize, Clone, Default, Debug)] pub struct ID(pub String); diff --git a/iam/src/policy/policy.rs b/policy/src/policy/policy.rs similarity index 97% rename from iam/src/policy/policy.rs rename to policy/src/policy/policy.rs index 19f329480..03a94ffff 100644 --- a/iam/src/policy/policy.rs +++ b/policy/src/policy/policy.rs @@ -1,5 +1,4 @@ -use super::{Effect, Error as IamError, Statement, ID}; -use crate::sys::{Args, Validator, DEFAULT_VERSION}; +use super::{Args, Effect, Error as IamError, Statement, Validator, DEFAULT_VERSION, ID}; use common::error::{Error, Result}; use serde::{Deserialize, Serialize}; use std::collections::HashSet; @@ -122,13 +121,10 @@ impl Validator for Policy { pub mod default { use std::{collections::HashSet, sync::LazyLock}; - use crate::{ - policy::{ - action::{Action, AdminAction, KmsAction, S3Action}, - resource::Resource, - ActionSet, Effect, Functions, ResourceSet, Statement, - }, - sys::DEFAULT_VERSION, + use crate::policy::{ + action::{Action, AdminAction, KmsAction, S3Action}, + resource::Resource, + ActionSet, Effect, Functions, ResourceSet, Statement, DEFAULT_VERSION, }; use super::Policy; @@ -323,7 +319,7 @@ pub mod default { #[cfg(test)] mod test { use super::*; - use common::error::{Error, Result}; + use common::error::Result; #[tokio::test] async fn test_parse_policy() -> Result<()> { diff --git a/iam/src/policy/resource.rs b/policy/src/policy/resource.rs similarity index 99% rename from iam/src/policy/resource.rs rename to policy/src/policy/resource.rs index 6ea279e29..9592590ae 100644 --- a/iam/src/policy/resource.rs +++ b/policy/src/policy/resource.rs @@ -6,12 +6,10 @@ use std::{ ops::Deref, }; -use crate::sys::Validator; - use super::{ function::key_name::KeyName, utils::{path, wildcard}, - Error as IamError, + Error as IamError, Validator, }; #[derive(Serialize, Deserialize, Clone, Default, Debug)] diff --git a/iam/src/policy/statement.rs b/policy/src/policy/statement.rs similarity index 95% rename from iam/src/policy/statement.rs rename to policy/src/policy/statement.rs index fcd9b8a17..3d38329f7 100644 --- a/iam/src/policy/statement.rs +++ b/policy/src/policy/statement.rs @@ -1,6 +1,4 @@ -use crate::sys::{Args, Validator}; - -use super::{action::Action, ActionSet, Effect, Error as IamError, Functions, ResourceSet, ID}; +use super::{action::Action, ActionSet, Args, Effect, Error as IamError, Functions, ResourceSet, Validator, ID}; use common::error::{Error, Result}; use serde::{Deserialize, Serialize}; diff --git a/iam/src/policy/utils.rs b/policy/src/policy/utils.rs similarity index 100% rename from iam/src/policy/utils.rs rename to policy/src/policy/utils.rs diff --git a/iam/src/policy/utils/path.rs b/policy/src/policy/utils/path.rs similarity index 100% rename from iam/src/policy/utils/path.rs rename to policy/src/policy/utils/path.rs diff --git a/iam/src/policy/utils/wildcard.rs b/policy/src/policy/utils/wildcard.rs similarity index 100% rename from iam/src/policy/utils/wildcard.rs rename to policy/src/policy/utils/wildcard.rs diff --git a/iam/src/service_type.rs b/policy/src/service_type.rs similarity index 100% rename from iam/src/service_type.rs rename to policy/src/service_type.rs diff --git a/policy/src/utils.rs b/policy/src/utils.rs new file mode 100644 index 000000000..c868a89a8 --- /dev/null +++ b/policy/src/utils.rs @@ -0,0 +1,110 @@ +use common::error::{Error, Result}; +use jsonwebtoken::{Algorithm, DecodingKey, EncodingKey, Header}; +use rand::{Rng, RngCore}; +use serde::{de::DeserializeOwned, Serialize}; + +pub fn gen_access_key(length: usize) -> Result { + const ALPHA_NUMERIC_TABLE: [char; 36] = [ + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', + 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', + ]; + + if length < 3 { + return Err(Error::msg("access key length is too short")); + } + + let mut result = String::with_capacity(length); + let mut rng = rand::thread_rng(); + + for _ in 0..length { + result.push(ALPHA_NUMERIC_TABLE[rng.gen_range(0..ALPHA_NUMERIC_TABLE.len())]); + } + + Ok(result) +} + +pub fn gen_secret_key(length: usize) -> Result { + use base64_simd::URL_SAFE_NO_PAD; + + if length < 8 { + return Err(Error::msg("secret key length is too short")); + } + let mut rng = rand::thread_rng(); + + let mut key = vec![0u8; URL_SAFE_NO_PAD.estimated_decoded_length(length)]; + rng.fill_bytes(&mut key); + + let encoded = URL_SAFE_NO_PAD.encode_to_string(&key); + let key_str = encoded.replace("/", "+"); + + Ok(key_str) +} + +pub fn generate_jwt(claims: &T, secret: &str) -> Result { + let header = Header::new(Algorithm::HS512); + jsonwebtoken::encode(&header, &claims, &EncodingKey::from_secret(secret.as_bytes())) +} + +pub fn extract_claims( + token: &str, + secret: &str, +) -> Result, jsonwebtoken::errors::Error> { + jsonwebtoken::decode::( + token, + &DecodingKey::from_secret(secret.as_bytes()), + &jsonwebtoken::Validation::new(Algorithm::HS512), + ) +} + +#[cfg(test)] +mod tests { + use super::{gen_access_key, gen_secret_key, generate_jwt}; + use serde::{Deserialize, Serialize}; + + #[test] + fn test_gen_access_key() { + let a = gen_access_key(10).unwrap(); + let b = gen_access_key(10).unwrap(); + + assert_eq!(a.len(), 10); + assert_eq!(b.len(), 10); + assert_ne!(a, b); + } + + #[test] + fn test_gen_secret_key() { + let a = gen_secret_key(10).unwrap(); + let b = gen_secret_key(10).unwrap(); + assert_ne!(a, b); + } + + #[derive(Debug, Serialize, Deserialize, PartialEq)] + struct Claims { + sub: String, + company: String, + } + + #[test] + fn test_generate_jwt() { + let claims = Claims { + sub: "user1".to_string(), + company: "example".to_string(), + }; + let secret = "my_secret"; + let token = generate_jwt(&claims, secret).unwrap(); + + assert!(!token.is_empty()); + } + + // #[test] + // fn test_extract_claims() { + // let claims = Claims { + // sub: "user1".to_string(), + // company: "example".to_string(), + // }; + // let secret = "my_secret"; + // let token = generate_jwt(&claims, secret).unwrap(); + // let decoded_claims = extract_claims::(&token, secret).unwrap(); + // assert_eq!(decoded_claims.claims, claims); + // } +} diff --git a/iam/tests/policy_is_allowed.rs b/policy/tests/policy_is_allowed.rs similarity index 98% rename from iam/tests/policy_is_allowed.rs rename to policy/tests/policy_is_allowed.rs index 45ed9607c..b72be6dcb 100644 --- a/iam/tests/policy_is_allowed.rs +++ b/policy/tests/policy_is_allowed.rs @@ -1,11 +1,8 @@ -use iam::policy::action::Action; -use iam::policy::action::ActionSet; -use iam::policy::action::S3Action::*; -use iam::policy::resource::ResourceSet; -use iam::policy::Effect::*; -use iam::policy::{Policy, Statement}; -use iam::sys::Args; -use iam::sys::DEFAULT_VERSION; +use policy::policy::action::Action; +use policy::policy::action::S3Action::*; +use policy::policy::ActionSet; +use policy::policy::Effect::*; +use policy::policy::*; use serde_json::Value; use std::collections::HashMap; use test_case::test_case; @@ -24,10 +21,10 @@ struct ArgsBuilder { } #[test_case( - Policy{ - version: DEFAULT_VERSION.into(), + policy::policy::Policy{ + version: policy::policy::DEFAULT_VERSION.into(), statements: vec![ - Statement{ + policy::policy::Statement{ effect: Allow, actions: ActionSet(vec![Action::S3Action(PutObjectAction), Action::S3Action(GetBucketLocationAction)].into_iter().collect()), resources: ResourceSet(vec!["arn:aws:s3:::*".try_into().unwrap()].into_iter().collect()), @@ -46,7 +43,7 @@ struct ArgsBuilder { )] #[test_case( Policy{ - version: iam::sys::DEFAULT_VERSION.into(), + version: DEFAULT_VERSION.into(), statements: vec![ Statement{ effect: Allow, @@ -581,7 +578,7 @@ struct ArgsBuilder { )] #[test_case( Policy{ - version: iam::sys::DEFAULT_VERSION.into(), + version: DEFAULT_VERSION.into(), statements: vec![ Statement{ effect: Deny, diff --git a/rustfs/Cargo.toml b/rustfs/Cargo.toml index 404257dc3..f0c8d1185 100644 --- a/rustfs/Cargo.toml +++ b/rustfs/Cargo.toml @@ -22,6 +22,7 @@ bytes.workspace = true clap.workspace = true common.workspace = true ecstore.workspace = true +policy.workspace =true flatbuffers.workspace = true futures.workspace = true futures-util.workspace = true diff --git a/rustfs/src/admin/handlers/policy.rs b/rustfs/src/admin/handlers/policy.rs index 40b8c98d5..4d650a593 100644 --- a/rustfs/src/admin/handlers/policy.rs +++ b/rustfs/src/admin/handlers/policy.rs @@ -2,8 +2,9 @@ use std::collections::HashMap; use crate::admin::{router::Operation, utils::has_space_be}; use http::{HeaderMap, StatusCode}; -use iam::{error::is_err_no_such_user, get_global_action_cred, policy::Policy, store::MappedPolicy}; +use iam::{error::is_err_no_such_user, get_global_action_cred, store::MappedPolicy}; use matchit::Params; +use policy::policy::Policy; use s3s::{header::CONTENT_TYPE, s3_error, Body, S3Error, S3ErrorCode, S3Request, S3Response, S3Result}; use serde::Deserialize; use serde_urlencoded::from_bytes; diff --git a/rustfs/src/admin/handlers/service_account.rs b/rustfs/src/admin/handlers/service_account.rs index 021e048ea..7d26e9bad 100644 --- a/rustfs/src/admin/handlers/service_account.rs +++ b/rustfs/src/admin/handlers/service_account.rs @@ -5,7 +5,6 @@ use hyper::StatusCode; use iam::{ error::is_err_no_such_service_account, get_global_action_cred, - policy::Policy, sys::{NewServiceAccountOpts, UpdateServiceAccountOpts}, }; use madmin::{ @@ -13,6 +12,7 @@ use madmin::{ ServiceAccountInfo, UpdateServiceAccountReq, }; use matchit::Params; +use policy::policy::Policy; use s3s::S3ErrorCode::InvalidRequest; use s3s::{header::CONTENT_TYPE, s3_error, Body, S3Error, S3ErrorCode, S3Request, S3Response, S3Result}; use serde::Deserialize; diff --git a/rustfs/src/admin/handlers/sts.rs b/rustfs/src/admin/handlers/sts.rs index cdd54286e..14efd2222 100644 --- a/rustfs/src/admin/handlers/sts.rs +++ b/rustfs/src/admin/handlers/sts.rs @@ -6,8 +6,9 @@ use crate::{ }; use ecstore::utils::{crypto::base64_encode, xml}; use http::StatusCode; -use iam::{auth::get_new_credentials_with_metadata, manager::get_token_signing_key, policy::Policy, sys::SESSION_POLICY_NAME}; +use iam::{manager::get_token_signing_key, sys::SESSION_POLICY_NAME}; use matchit::Params; +use policy::{auth::get_new_credentials_with_metadata, policy::Policy}; use s3s::{ dto::{AssumeRoleOutput, Credentials, Timestamp}, s3_error, Body, S3Error, S3ErrorCode, S3Request, S3Response, S3Result, diff --git a/rustfs/src/auth.rs b/rustfs/src/auth.rs index c2e215a6f..42d4a464d 100644 --- a/rustfs/src/auth.rs +++ b/rustfs/src/auth.rs @@ -1,11 +1,11 @@ use std::collections::HashMap; use http::HeaderMap; -use iam::auth; -use iam::auth::get_claims_from_token_with_secret; use iam::error::Error as IamError; use iam::get_global_action_cred; use iam::sys::SESSION_POLICY_NAME; +use policy::auth; +use policy::auth::get_claims_from_token_with_secret; use s3s::auth::S3Auth; use s3s::auth::SecretKey; use s3s::auth::SimpleAuth; diff --git a/rustfs/src/storage/access.rs b/rustfs/src/storage/access.rs index 81a744bdd..5d3300dd1 100644 --- a/rustfs/src/storage/access.rs +++ b/rustfs/src/storage/access.rs @@ -1,9 +1,9 @@ use super::ecfs::FS; use crate::auth::{check_key_valid, get_condition_values}; -use iam::auth; use iam::error::Error as IamError; -use iam::policy::action::{Action, S3Action}; -use iam::sys::Args; +use policy::auth; +use policy::policy::action::{Action, S3Action}; +use policy::policy::Args; use s3s::access::{S3Access, S3AccessContext}; use s3s::{dto::*, s3_error, S3Error, S3ErrorCode, S3Request, S3Result}; use std::collections::HashMap; diff --git a/rustfs/src/storage/ecfs.rs b/rustfs/src/storage/ecfs.rs index edb936dc3..2504fd477 100644 --- a/rustfs/src/storage/ecfs.rs +++ b/rustfs/src/storage/ecfs.rs @@ -39,10 +39,10 @@ use ecstore::xhttp; use futures::pin_mut; use futures::{Stream, StreamExt}; use http::HeaderMap; -use iam::policy::action::Action; -use iam::policy::action::S3Action; use lazy_static::lazy_static; use log::warn; +use policy::policy::action::Action; +use policy::policy::action::S3Action; use s3s::dto::*; use s3s::s3_error; use s3s::S3Error;