This commit is contained in:
weisd
2025-06-06 11:35:27 +08:00
parent 9384b831ec
commit db355bb26b
37 changed files with 2169 additions and 668 deletions
+47 -52
View File
@@ -1,3 +1,4 @@
use crate::error::{is_err_config_not_found, Error, Result};
use crate::{
cache::{Cache, CacheEntity},
error::{is_err_no_such_group, is_err_no_such_policy, is_err_no_such_user, Error as IamError},
@@ -8,7 +9,6 @@ use crate::{
STATUS_DISABLED, STATUS_ENABLED,
},
};
use common::error::{Error, Result};
use ecstore::utils::{crypto::base64_encode, path::path_join_buf};
use madmin::{AccountStatus, AddOrUpdateUserReq, GroupDesc};
use policy::{
@@ -182,7 +182,7 @@ where
pub async fn get_policy(&self, name: &str) -> Result<Policy> {
if name.is_empty() {
return Err(Error::new(IamError::InvalidArgument));
return Err(Error::InvalidArgument);
}
let policies = MappedPolicy::new(name).to_slice();
@@ -199,13 +199,13 @@ where
.load()
.get(&policy)
.cloned()
.ok_or(Error::new(IamError::NoSuchPolicy))?;
.ok_or(Error::NoSuchPolicy)?;
to_merge.push(v.policy);
}
if to_merge.is_empty() {
return Err(Error::new(IamError::NoSuchPolicy));
return Err(Error::NoSuchPolicy);
}
Ok(Policy::merge_policies(to_merge))
@@ -213,20 +213,15 @@ where
pub async fn get_policy_doc(&self, name: &str) -> Result<PolicyDoc> {
if name.is_empty() {
return Err(Error::new(IamError::InvalidArgument));
return Err(Error::InvalidArgument);
}
self.cache
.policy_docs
.load()
.get(name)
.cloned()
.ok_or(Error::new(IamError::NoSuchPolicy))
self.cache.policy_docs.load().get(name).cloned().ok_or(Error::NoSuchPolicy)
}
pub async fn delete_policy(&self, name: &str, is_from_notify: bool) -> Result<()> {
if name.is_empty() {
return Err(Error::new(IamError::InvalidArgument));
return Err(Error::InvalidArgument);
}
if is_from_notify {
@@ -254,7 +249,7 @@ where
});
if !users.is_empty() || !groups.is_empty() {
return Err(IamError::PolicyInUse.into());
return Err(Error::PolicyInUse);
}
if let Err(err) = self.api.delete_policy_doc(name).await {
@@ -274,7 +269,7 @@ where
pub async fn set_policy(&self, name: &str, policy: Policy) -> Result<OffsetDateTime> {
if name.is_empty() || policy.is_empty() {
return Err(Error::new(IamError::InvalidArgument));
return Err(Error::InvalidArgument);
}
let policy_doc = self
@@ -406,7 +401,7 @@ where
}
if !user_exists {
return Err(Error::new(IamError::NoSuchUser(access_key.to_string())));
return Err(Error::NoSuchUser(access_key.to_string()));
}
Ok(ret)
@@ -452,13 +447,13 @@ where
/// create a service account and update cache
pub async fn add_service_account(&self, cred: Credentials) -> Result<OffsetDateTime> {
if cred.access_key.is_empty() || cred.parent_user.is_empty() {
return Err(Error::new(IamError::InvalidArgument));
return Err(Error::InvalidArgument);
}
let users = self.cache.users.load();
if let Some(x) = users.get(&cred.access_key) {
if x.credentials.is_service_account() {
return Err(Error::new(IamError::IAMActionNotAllowed));
return Err(Error::IAMActionNotAllowed);
}
}
@@ -475,11 +470,11 @@ where
pub async fn update_service_account(&self, name: &str, opts: UpdateServiceAccountOpts) -> Result<OffsetDateTime> {
let Some(ui) = self.cache.users.load().get(name).cloned() else {
return Err(IamError::NoSuchServiceAccount(name.to_string()).into());
return Err(Error::NoSuchServiceAccount(name.to_string()));
};
if !ui.credentials.is_service_account() {
return Err(IamError::NoSuchServiceAccount(name.to_string()).into());
return Err(Error::NoSuchServiceAccount(name.to_string()));
}
let mut cr = ui.credentials.clone();
@@ -487,7 +482,7 @@ where
if let Some(secret) = opts.secret_key {
if !is_secret_key_valid(&secret) {
return Err(IamError::InvalidSecretKeyLength.into());
return Err(Error::InvalidSecretKeyLength);
}
cr.secret_key = secret;
}
@@ -534,7 +529,7 @@ where
if !session_policy.version.is_empty() && !session_policy.statements.is_empty() {
let policy_buf = serde_json::to_vec(&session_policy)?;
if policy_buf.len() > MAX_SVCSESSION_POLICY_SIZE {
return Err(IamError::PolicyTooLarge.into());
return Err(Error::PolicyTooLarge);
}
m.insert(SESSION_POLICY_NAME.to_owned(), serde_json::Value::String(base64_encode(&policy_buf)));
@@ -557,7 +552,7 @@ where
pub async fn policy_db_get(&self, name: &str, groups: &Option<Vec<String>>) -> Result<Vec<String>> {
if name.is_empty() {
return Err(Error::new(IamError::InvalidArgument));
return Err(Error::InvalidArgument);
}
let (mut policies, _) = self.policy_db_get_internal(name, false, false).await?;
@@ -593,7 +588,7 @@ where
Cache::add_or_update(&self.cache.groups, name, p, OffsetDateTime::now_utc());
}
m.get(name).cloned().ok_or(IamError::NoSuchGroup(name.to_string()))?
m.get(name).cloned().ok_or(Error::NoSuchGroup(name.to_string()))?
}
};
@@ -736,7 +731,7 @@ where
}
pub async fn policy_db_set(&self, name: &str, user_type: UserType, is_group: bool, policy: &str) -> Result<OffsetDateTime> {
if name.is_empty() {
return Err(Error::new(IamError::InvalidArgument));
return Err(Error::InvalidArgument);
}
if policy.is_empty() {
@@ -762,7 +757,7 @@ where
let policy_docs_cache = self.cache.policy_docs.load();
for p in mp.to_slice() {
if !policy_docs_cache.contains_key(&p) {
return Err(Error::new(IamError::NoSuchPolicy));
return Err(Error::NoSuchPolicy);
}
}
@@ -790,14 +785,14 @@ where
cred.is_expired(),
cred.parent_user.is_empty()
);
return Err(Error::new(IamError::InvalidArgument));
return Err(Error::InvalidArgument);
}
if let Some(policy) = policy_name {
let mp = MappedPolicy::new(policy);
let (_, combined_policy_stmt) = filter_policies(&self.cache, &mp.policies, "temp");
if combined_policy_stmt.is_empty() {
return Err(Error::msg(format!("need poliy not found {}", IamError::NoSuchPolicy)));
return Err(Error::other(format!("need poliy not found {}", IamError::NoSuchPolicy)));
}
self.api
@@ -824,11 +819,11 @@ where
let u = match users.get(name) {
Some(u) => u,
None => return Err(Error::new(IamError::NoSuchUser(name.to_string()))),
None => return Err(Error::NoSuchUser(name.to_string())),
};
if u.credentials.is_temp() || u.credentials.is_service_account() {
return Err(Error::new(IamError::IAMActionNotAllowed));
return Err(Error::IAMActionNotAllowed);
}
let mut uinfo = madmin::UserInfo {
@@ -960,7 +955,7 @@ where
if let Some(x) = users.get(access_key) {
warn!("user already exists: {:?}", x);
if x.credentials.is_temp() {
return Err(IamError::IAMActionNotAllowed.into());
return Err(Error::IAMActionNotAllowed);
}
}
@@ -988,7 +983,7 @@ where
pub async fn delete_user(&self, access_key: &str, utype: UserType) -> Result<()> {
if access_key.is_empty() {
return Err(Error::new(IamError::InvalidArgument));
return Err(Error::InvalidArgument);
}
if utype == UserType::Reg {
@@ -1040,13 +1035,13 @@ where
pub async fn update_user_secret_key(&self, access_key: &str, secret_key: &str) -> Result<()> {
if access_key.is_empty() || secret_key.is_empty() {
return Err(Error::new(IamError::InvalidArgument));
return Err(Error::InvalidArgument);
}
let users = self.cache.users.load();
let u = match users.get(access_key) {
Some(u) => u,
None => return Err(Error::new(IamError::NoSuchUser(access_key.to_string()))),
None => return Err(Error::NoSuchUser(access_key.to_string())),
};
let mut cred = u.credentials.clone();
@@ -1063,21 +1058,21 @@ where
pub async fn set_user_status(&self, access_key: &str, status: AccountStatus) -> Result<OffsetDateTime> {
if access_key.is_empty() {
return Err(Error::new(IamError::InvalidArgument));
return Err(Error::InvalidArgument);
}
if !access_key.is_empty() && status != AccountStatus::Enabled && status != AccountStatus::Disabled {
return Err(Error::new(IamError::InvalidArgument));
return Err(Error::InvalidArgument);
}
let users = self.cache.users.load();
let u = match users.get(access_key) {
Some(u) => u,
None => return Err(Error::new(IamError::NoSuchUser(access_key.to_string()))),
None => return Err(Error::NoSuchUser(access_key.to_string())),
};
if u.credentials.is_temp() || u.credentials.is_service_account() {
return Err(Error::new(IamError::IAMActionNotAllowed));
return Err(Error::IAMActionNotAllowed);
}
let status = {
@@ -1122,7 +1117,7 @@ where
let users = self.cache.users.load();
let u = match users.get(access_key) {
Some(u) => u,
None => return Err(Error::new(IamError::NoSuchUser(access_key.to_string()))),
None => return Err(Error::NoSuchUser(access_key.to_string())),
};
if u.credentials.is_temp() {
@@ -1134,7 +1129,7 @@ where
pub async fn add_users_to_group(&self, group: &str, members: Vec<String>) -> Result<OffsetDateTime> {
if group.is_empty() {
return Err(Error::new(IamError::InvalidArgument));
return Err(Error::InvalidArgument);
}
let users_cache = self.cache.users.load();
@@ -1142,10 +1137,10 @@ where
for member in members.iter() {
if let Some(u) = users_cache.get(member) {
if u.credentials.is_temp() || u.credentials.is_service_account() {
return Err(Error::new(IamError::IAMActionNotAllowed));
return Err(Error::IAMActionNotAllowed);
}
} else {
return Err(Error::new(IamError::NoSuchUser(member.to_string())));
return Err(Error::NoSuchUser(member.to_string()));
}
}
@@ -1180,13 +1175,13 @@ where
pub async fn set_group_status(&self, name: &str, enable: bool) -> Result<OffsetDateTime> {
if name.is_empty() {
return Err(Error::new(IamError::InvalidArgument));
return Err(Error::InvalidArgument);
}
let groups = self.cache.groups.load();
let mut gi = match groups.get(name) {
Some(gi) => gi.clone(),
None => return Err(Error::new(IamError::NoSuchGroup(name.to_string()))),
None => return Err(Error::NoSuchGroup(name.to_string())),
};
if enable {
@@ -1212,7 +1207,7 @@ where
.load()
.get(name)
.cloned()
.ok_or(Error::new(IamError::NoSuchGroup(name.to_string())))?;
.ok_or(Error::NoSuchGroup(name.to_string()))?;
Ok(GroupDesc {
name: name.to_string(),
@@ -1239,7 +1234,7 @@ where
.load()
.get(name)
.cloned()
.ok_or(Error::new(IamError::NoSuchGroup(name.to_string())))?;
.ok_or(Error::NoSuchGroup(name.to_string()))?;
let s: HashSet<&String> = HashSet::from_iter(gi.members.iter());
let d: HashSet<&String> = HashSet::from_iter(members.iter());
@@ -1265,7 +1260,7 @@ where
pub async fn remove_users_from_group(&self, group: &str, members: Vec<String>) -> Result<OffsetDateTime> {
if group.is_empty() {
return Err(Error::new(IamError::InvalidArgument));
return Err(Error::InvalidArgument);
}
let users_cache = self.cache.users.load();
@@ -1273,10 +1268,10 @@ where
for member in members.iter() {
if let Some(u) = users_cache.get(member) {
if u.credentials.is_temp() || u.credentials.is_service_account() {
return Err(Error::new(IamError::IAMActionNotAllowed));
return Err(Error::IAMActionNotAllowed);
}
} else {
return Err(Error::new(IamError::NoSuchUser(member.to_string())));
return Err(Error::NoSuchUser(member.to_string()));
}
}
@@ -1286,10 +1281,10 @@ where
.load()
.get(group)
.cloned()
.ok_or(Error::new(IamError::NoSuchGroup(group.to_string())))?;
.ok_or(Error::NoSuchGroup(group.to_string()))?;
if members.is_empty() && !gi.members.is_empty() {
return Err(IamError::GroupNotEmpty.into());
return Err(Error::GroupNotEmpty);
}
if members.is_empty() {
@@ -1588,7 +1583,7 @@ pub fn get_token_signing_key() -> Option<String> {
pub fn extract_jwt_claims(u: &UserIdentity) -> Result<HashMap<String, Value>> {
let Some(sys_key) = get_token_signing_key() else {
return Err(Error::msg("global active sk not init"));
return Err(Error::other("global active sk not init"));
};
let keys = vec![&sys_key, &u.credentials.secret_key];
@@ -1598,7 +1593,7 @@ pub fn extract_jwt_claims(u: &UserIdentity) -> Result<HashMap<String, Value>> {
return Ok(claims);
}
}
Err(Error::msg("unable to extract claims"))
Err(Error::other("unable to extract claims"))
}
fn filter_policies(cache: &Cache, policy_name: &str, bucket_name: &str) -> (String, Policy) {