fix(iam): propagate cache miss load failures (#2692)

Co-authored-by: GatewayJ <8352692332qq.com>
Co-authored-by: loverustfs <hello@rustfs.com>
Co-authored-by: houseme <housemecn@gmail.com>
This commit is contained in:
GatewayJ
2026-04-27 17:21:22 +08:00
committed by GitHub
parent 468dc3aebd
commit cfbd094bc4
3 changed files with 49 additions and 5 deletions
+20 -4
View File
@@ -255,18 +255,30 @@ where
let mut sts_policy_map = HashMap::new();
let mut policy_docs_map = HashMap::new();
let _ = self.api.load_user(access_key, UserType::Svc, &mut users_map).await;
match self.api.load_user(access_key, UserType::Svc, &mut users_map).await {
Ok(()) => {}
Err(err) if is_err_no_such_user(&err) => {}
Err(err) => return Err(err),
}
let parent_user = users_map.get(access_key).map(|svc| svc.credentials.parent_user.clone());
if let Some(parent_user) = parent_user {
let _ = self.api.load_user(&parent_user, UserType::Reg, &mut users_map).await;
match self.api.load_user(&parent_user, UserType::Reg, &mut users_map).await {
Ok(()) => {}
Err(err) if is_err_no_such_user(&err) => {}
Err(err) => return Err(err),
}
let _ = self
.api
.load_mapped_policy(&parent_user, UserType::Reg, false, &mut user_policy_map)
.await;
} else {
let _ = self.api.load_user(access_key, UserType::Reg, &mut users_map).await;
match self.api.load_user(access_key, UserType::Reg, &mut users_map).await {
Ok(()) => {}
Err(err) if is_err_no_such_user(&err) => {}
Err(err) => return Err(err),
}
if users_map.contains_key(access_key) {
let _ = self
.api
@@ -274,7 +286,11 @@ where
.await;
}
let _ = self.api.load_user(access_key, UserType::Sts, &mut sts_users_map).await;
match self.api.load_user(access_key, UserType::Sts, &mut sts_users_map).await {
Ok(()) => {}
Err(err) if is_err_no_such_user(&err) => {}
Err(err) => return Err(err),
}
let has_sts_user = sts_users_map.get(access_key);
+16 -1
View File
@@ -755,7 +755,7 @@ impl<T: Store> IamSys<T> {
Ok((Some(res), ok))
}
None => {
let _ = self.store.load_user(access_key).await;
self.store.load_user(access_key).await?;
if let Some(res) = self.store.get_user(access_key).await {
let ok = res.credentials.is_valid();
@@ -1372,6 +1372,10 @@ mod tests {
}
async fn load_user(&self, name: &str, user_type: UserType, m: &mut HashMap<String, UserIdentity>) -> Result<()> {
if user_type == UserType::Reg && name == "load-failure-user" {
return Err(Error::Io(std::io::Error::other("load user failed")));
}
if user_type == UserType::Reg && name == "notify-user" {
let user = UserIdentity::from(Credentials {
access_key: name.to_string(),
@@ -1813,6 +1817,17 @@ mod tests {
);
}
#[tokio::test]
async fn test_check_key_propagates_cache_miss_load_failure() {
let store = StsTestMockStore { empty_policies: false };
let cache_manager = IamCache::new(store).await;
let iam_sys = IamSys::new(cache_manager);
let result = iam_sys.check_key("load-failure-user").await;
assert!(matches!(result, Err(Error::Io(_))));
}
#[tokio::test]
async fn test_prepare_auth_eval_matches_prepare_sts_auth_for_parent_policy_fallback() {
let store = StsTestMockStore { empty_policies: false };