From 982cc66c7490f0eff5a6ded94943e22d4129daff Mon Sep 17 00:00:00 2001 From: weisd Date: Wed, 16 Jul 2025 16:40:51 +0800 Subject: [PATCH] fix: Refactor session policy handling and fix owner permission check (#226) --- crates/iam/src/manager.rs | 3 ++- crates/iam/src/sys.rs | 18 +++++++++++++++++- crates/policy/src/auth/credentials.rs | 8 -------- rustfs/src/auth.rs | 2 +- 4 files changed, 20 insertions(+), 11 deletions(-) diff --git a/crates/iam/src/manager.rs b/crates/iam/src/manager.rs index c0831ce1..d8b073af 100644 --- a/crates/iam/src/manager.rs +++ b/crates/iam/src/manager.rs @@ -13,6 +13,7 @@ // limitations under the License. use crate::error::{Error, Result, is_err_config_not_found}; +use crate::sys::get_claims_from_token_with_secret; use crate::{ cache::{Cache, CacheEntity}, error::{Error as IamError, is_err_no_such_group, is_err_no_such_policy, is_err_no_such_user}, @@ -26,7 +27,7 @@ use rustfs_ecstore::global::get_global_action_cred; use rustfs_madmin::{AccountStatus, AddOrUpdateUserReq, GroupDesc}; use rustfs_policy::{ arn::ARN, - auth::{self, Credentials, UserIdentity, get_claims_from_token_with_secret, is_secret_key_valid, jwt_sign}, + auth::{self, Credentials, UserIdentity, is_secret_key_valid, jwt_sign}, format::Format, policy::{ EMBEDDED_POLICY_TYPE, INHERITED_POLICY_TYPE, Policy, PolicyDoc, default::DEFAULT_POLICIES, iam_policy_claim_name_sa, diff --git a/crates/iam/src/sys.rs b/crates/iam/src/sys.rs index 0b6947c5..cc55a7ee 100644 --- a/crates/iam/src/sys.rs +++ b/crates/iam/src/sys.rs @@ -23,6 +23,7 @@ use crate::store::GroupInfo; use crate::store::MappedPolicy; use crate::store::Store; use crate::store::UserType; +use crate::utils::extract_claims; use rustfs_ecstore::global::get_global_action_cred; use rustfs_madmin::AddOrUpdateUserReq; use rustfs_madmin::GroupDesc; @@ -542,7 +543,7 @@ impl IamSys { } }; - if policies.is_empty() { + if !is_owner && policies.is_empty() { return false; } @@ -732,3 +733,18 @@ pub struct UpdateServiceAccountOpts { pub expiration: Option, pub status: Option, } + +pub fn get_claims_from_token_with_secret(token: &str, secret: &str) -> Result> { + let mut ms = + extract_claims::>(token, secret).map_err(|e| Error::other(format!("extract claims err {e}")))?; + + if let Some(session_policy) = ms.claims.get(SESSION_POLICY_NAME) { + let policy_str = session_policy.as_str().unwrap_or_default(); + let policy = base64_decode(policy_str.as_bytes()).map_err(|e| Error::other(format!("base64 decode err {e}")))?; + ms.claims.insert( + SESSION_POLICY_NAME_EXTRACTED.to_string(), + Value::String(String::from_utf8(policy).map_err(|e| Error::other(format!("utf8 decode err {e}")))?), + ); + } + Ok(ms.claims) +} diff --git a/crates/policy/src/auth/credentials.rs b/crates/policy/src/auth/credentials.rs index 6a1d3d8b..0bc2618e 100644 --- a/crates/policy/src/auth/credentials.rs +++ b/crates/policy/src/auth/credentials.rs @@ -16,8 +16,6 @@ use crate::error::Error as IamError; use crate::error::{Error, Result}; use crate::policy::{INHERITED_POLICY_TYPE, Policy, Validator, iam_policy_claim_name_sa}; use crate::utils; -use crate::utils::extract_claims; -use serde::de::DeserializeOwned; use serde::{Deserialize, Serialize}; use serde_json::{Value, json}; use std::collections::HashMap; @@ -253,12 +251,6 @@ pub fn create_new_credentials_with_metadata( }) } -pub fn get_claims_from_token_with_secret(token: &str, secret: &str) -> Result { - let ms = extract_claims::(token, secret)?; - // TODO SessionPolicyName - Ok(ms.claims) -} - pub fn jwt_sign(claims: &T, token_secret: &str) -> Result { let token = utils::generate_jwt(claims, token_secret)?; Ok(token) diff --git a/rustfs/src/auth.rs b/rustfs/src/auth.rs index 53367e0a..f33bc761 100644 --- a/rustfs/src/auth.rs +++ b/rustfs/src/auth.rs @@ -17,8 +17,8 @@ use http::Uri; use rustfs_ecstore::global::get_global_action_cred; use rustfs_iam::error::Error as IamError; use rustfs_iam::sys::SESSION_POLICY_NAME; +use rustfs_iam::sys::get_claims_from_token_with_secret; use rustfs_policy::auth; -use rustfs_policy::auth::get_claims_from_token_with_secret; use s3s::S3Error; use s3s::S3ErrorCode; use s3s::S3Result;