mirror of
https://github.com/rustfs/rustfs.git
synced 2026-09-04 19:25:40 +00:00
rewrite AssumeRoleHandle
This commit is contained in:
+17
-10
@@ -177,22 +177,17 @@ pub fn generate_credentials() -> Result<(String, String)> {
|
|||||||
Ok((ak, sk))
|
Ok((ak, sk))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_new_credentials_with_metadata<T: Serialize>(
|
pub fn get_new_credentials_with_metadata(claims: &HashMap<String, Value>, token_secret: &str) -> Result<Credentials> {
|
||||||
claims: &T,
|
|
||||||
token_secret: &str,
|
|
||||||
exp: Option<usize>,
|
|
||||||
) -> Result<Credentials> {
|
|
||||||
let (ak, sk) = generate_credentials()?;
|
let (ak, sk) = generate_credentials()?;
|
||||||
|
|
||||||
create_new_credentials_with_metadata(&ak, &sk, claims, token_secret, exp)
|
create_new_credentials_with_metadata(&ak, &sk, claims, token_secret)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_new_credentials_with_metadata<T: Serialize>(
|
pub fn create_new_credentials_with_metadata(
|
||||||
ak: &str,
|
ak: &str,
|
||||||
sk: &str,
|
sk: &str,
|
||||||
claims: &T,
|
claims: &HashMap<String, Value>,
|
||||||
token_secret: &str,
|
token_secret: &str,
|
||||||
exp: Option<usize>,
|
|
||||||
) -> Result<Credentials> {
|
) -> Result<Credentials> {
|
||||||
if ak.len() < ACCESS_KEY_MIN_LEN || ak.len() > ACCESS_KEY_MAX_LEN {
|
if ak.len() < ACCESS_KEY_MIN_LEN || ak.len() > ACCESS_KEY_MAX_LEN {
|
||||||
return Err(Error::new(IamError::InvalidAccessKeyLength));
|
return Err(Error::new(IamError::InvalidAccessKeyLength));
|
||||||
@@ -202,6 +197,18 @@ pub fn create_new_credentials_with_metadata<T: Serialize>(
|
|||||||
return Err(Error::new(IamError::InvalidAccessKeyLength));
|
return Err(Error::new(IamError::InvalidAccessKeyLength));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let expiration = {
|
||||||
|
if let Some(v) = claims.get("exp") {
|
||||||
|
if let Some(expiry) = v.as_i64() {
|
||||||
|
Some(OffsetDateTime::from_unix_timestamp(expiry)?.to_offset(OffsetDateTime::now_local()?.offset()))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let token = utils::generate_jwt(claims, token_secret)?;
|
let token = utils::generate_jwt(claims, token_secret)?;
|
||||||
|
|
||||||
Ok(Credentials {
|
Ok(Credentials {
|
||||||
@@ -209,7 +216,7 @@ pub fn create_new_credentials_with_metadata<T: Serialize>(
|
|||||||
secret_key: sk.to_owned(),
|
secret_key: sk.to_owned(),
|
||||||
session_token: token,
|
session_token: token,
|
||||||
status: ACCOUNT_ON.to_owned(),
|
status: ACCOUNT_ON.to_owned(),
|
||||||
expiration: exp.map(|v| OffsetDateTime::now_utc().saturating_add(Duration::seconds(v as i64))),
|
expiration,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-1
@@ -773,7 +773,14 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn set_temp_user(&self, access_key: &str, cred: &Credentials, policy_name: Option<&str>) -> Result<OffsetDateTime> {
|
pub async fn set_temp_user(&self, access_key: &str, cred: &Credentials, policy_name: Option<&str>) -> Result<OffsetDateTime> {
|
||||||
if access_key.is_empty() || cred.is_temp() || cred.is_expired() || cred.parent_user.is_empty() {
|
if access_key.is_empty() || !cred.is_temp() || cred.is_expired() || cred.parent_user.is_empty() {
|
||||||
|
error!(
|
||||||
|
"set temp user invalid argument, access_key: {}, is_temp: {}, is_expired: {}, parent_user_empty: {}",
|
||||||
|
access_key,
|
||||||
|
cred.is_temp(),
|
||||||
|
cred.is_expired(),
|
||||||
|
cred.parent_user.is_empty()
|
||||||
|
);
|
||||||
return Err(Error::new(IamError::InvalidArgument));
|
return Err(Error::new(IamError::InvalidArgument));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+7
-7
@@ -210,14 +210,14 @@ impl<T: Store> IamSys<T> {
|
|||||||
Vec::new()
|
Vec::new()
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut m = HashMap::new();
|
let mut m: HashMap<String, Value> = HashMap::new();
|
||||||
m.insert("parent".to_owned(), parent_user.to_owned());
|
m.insert("parent".to_owned(), serde_json::Value::String(parent_user.to_owned()));
|
||||||
|
|
||||||
if !policy_buf.is_empty() {
|
if !policy_buf.is_empty() {
|
||||||
m.insert(SESSION_POLICY_NAME.to_owned(), base64_encode(&policy_buf));
|
m.insert(SESSION_POLICY_NAME.to_owned(), serde_json::Value::String(base64_encode(&policy_buf)));
|
||||||
m.insert(iam_policy_claim_name_sa(), EMBEDDED_POLICY_TYPE.to_owned());
|
m.insert(iam_policy_claim_name_sa(), serde_json::Value::String(EMBEDDED_POLICY_TYPE.to_owned()));
|
||||||
} else {
|
} else {
|
||||||
m.insert(iam_policy_claim_name_sa(), INHERITED_POLICY_TYPE.to_owned());
|
m.insert(iam_policy_claim_name_sa(), serde_json::Value::String(INHERITED_POLICY_TYPE.to_owned()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(claims) = opts.claims {
|
if let Some(claims) = opts.claims {
|
||||||
@@ -234,7 +234,7 @@ impl<T: Store> IamSys<T> {
|
|||||||
generate_credentials()?
|
generate_credentials()?
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut cred = create_new_credentials_with_metadata(&access_key, &secret_key, &m, &secret_key, None)?;
|
let mut cred = create_new_credentials_with_metadata(&access_key, &secret_key, &m, &secret_key)?;
|
||||||
cred.parent_user = parent_user.to_owned();
|
cred.parent_user = parent_user.to_owned();
|
||||||
cred.groups = Some(groups);
|
cred.groups = Some(groups);
|
||||||
cred.status = ACCOUNT_ON.to_owned();
|
cred.status = ACCOUNT_ON.to_owned();
|
||||||
@@ -671,7 +671,7 @@ pub struct NewServiceAccountOpts {
|
|||||||
pub description: Option<String>,
|
pub description: Option<String>,
|
||||||
pub expiration: Option<OffsetDateTime>,
|
pub expiration: Option<OffsetDateTime>,
|
||||||
pub allow_site_replicator_account: bool,
|
pub allow_site_replicator_account: bool,
|
||||||
pub claims: Option<HashMap<String, String>>,
|
pub claims: Option<HashMap<String, Value>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct UpdateServiceAccountOpts {
|
pub struct UpdateServiceAccountOpts {
|
||||||
|
|||||||
+161
-172
@@ -16,14 +16,17 @@ use ecstore::new_object_layer_fn;
|
|||||||
use ecstore::peer::is_reserved_or_invalid_bucket;
|
use ecstore::peer::is_reserved_or_invalid_bucket;
|
||||||
use ecstore::store::is_valid_object_prefix;
|
use ecstore::store::is_valid_object_prefix;
|
||||||
use ecstore::store_api::StorageAPI;
|
use ecstore::store_api::StorageAPI;
|
||||||
|
use ecstore::utils::crypto::base64_encode;
|
||||||
use ecstore::utils::path::path_join;
|
use ecstore::utils::path::path_join;
|
||||||
use ecstore::utils::xml;
|
use ecstore::utils::xml;
|
||||||
use ecstore::GLOBAL_Endpoints;
|
use ecstore::GLOBAL_Endpoints;
|
||||||
use futures::{Stream, StreamExt};
|
use futures::{Stream, StreamExt};
|
||||||
use http::{HeaderMap, Uri};
|
use http::{HeaderMap, Uri};
|
||||||
use hyper::StatusCode;
|
use hyper::StatusCode;
|
||||||
use iam::auth::{create_new_credentials_with_metadata, get_claims_from_token_with_secret};
|
use iam::auth::{get_claims_from_token_with_secret, get_new_credentials_with_metadata};
|
||||||
use iam::error::Error as IamError;
|
use iam::error::Error as IamError;
|
||||||
|
use iam::policy::Policy;
|
||||||
|
use iam::sys::SESSION_POLICY_NAME;
|
||||||
use iam::{auth, get_global_action_cred};
|
use iam::{auth, get_global_action_cred};
|
||||||
use madmin::metrics::RealtimeMetrics;
|
use madmin::metrics::RealtimeMetrics;
|
||||||
use madmin::utils::parse_duration;
|
use madmin::utils::parse_duration;
|
||||||
@@ -36,6 +39,7 @@ use s3s::{
|
|||||||
};
|
};
|
||||||
use s3s::{S3ErrorCode, StdError};
|
use s3s::{S3ErrorCode, StdError};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use serde_json::Value;
|
||||||
use serde_urlencoded::from_bytes;
|
use serde_urlencoded::from_bytes;
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::{HashMap, HashSet};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
@@ -70,49 +74,6 @@ pub struct AssumeRoleRequest {
|
|||||||
pub external_id: String,
|
pub external_id: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
// #[derive(Debug, Serialize, Default)]
|
|
||||||
// #[serde(rename_all = "PascalCase", default)]
|
|
||||||
// pub struct AssumeRoleResponse {
|
|
||||||
// #[serde(rename = "AssumeRoleResult")]
|
|
||||||
// pub result: AssumeRoleResult,
|
|
||||||
// }
|
|
||||||
|
|
||||||
// #[derive(Debug, Serialize, Default)]
|
|
||||||
// #[serde(rename_all = "PascalCase", default)]
|
|
||||||
// pub struct AssumeRoleResult {
|
|
||||||
// pub credentials: Credentials,
|
|
||||||
// }
|
|
||||||
|
|
||||||
// #[derive(Debug, Serialize, Default)]
|
|
||||||
// #[serde(rename_all = "PascalCase", default)]
|
|
||||||
// pub struct Credentials {
|
|
||||||
// #[serde(rename = "AccessKeyId")]
|
|
||||||
// pub access_key: String,
|
|
||||||
// #[serde(rename = "SecretAccessKey")]
|
|
||||||
// pub secret_key: String,
|
|
||||||
// pub status: String,
|
|
||||||
// pub expiration: usize,
|
|
||||||
// pub session_token: String,
|
|
||||||
// pub parent_user: String,
|
|
||||||
// }
|
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize, Default)]
|
|
||||||
pub struct STSClaims {
|
|
||||||
pub parent: String,
|
|
||||||
pub exp: usize,
|
|
||||||
pub access_key: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl STSClaims {
|
|
||||||
pub fn to_map(&self) -> HashMap<String, String> {
|
|
||||||
let mut m = HashMap::new();
|
|
||||||
m.insert("parent".to_string(), self.parent.clone());
|
|
||||||
m.insert("exp".to_string(), self.exp.to_string());
|
|
||||||
m.insert("access_key".to_string(), self.access_key.clone());
|
|
||||||
m
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_token_signing_key() -> Option<String> {
|
fn get_token_signing_key() -> Option<String> {
|
||||||
if let Some(s) = get_global_action_cred() {
|
if let Some(s) = get_global_action_cred() {
|
||||||
Some(s.secret_key.clone())
|
Some(s.secret_key.clone())
|
||||||
@@ -122,7 +83,7 @@ fn get_token_signing_key() -> Option<String> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// check_key_valid get auth.cred
|
// check_key_valid get auth.cred
|
||||||
pub async fn check_key_valid(token: Option<String>, ak: &str) -> S3Result<(auth::Credentials, bool)> {
|
pub async fn check_key_valid(security_token: Option<String>, ak: &str) -> S3Result<(auth::Credentials, bool)> {
|
||||||
let Some(mut cred) = get_global_action_cred() else {
|
let Some(mut cred) = get_global_action_cred() else {
|
||||||
return Err(S3Error::with_message(
|
return Err(S3Error::with_message(
|
||||||
S3ErrorCode::InternalError,
|
S3ErrorCode::InternalError,
|
||||||
@@ -145,92 +106,83 @@ pub async fn check_key_valid(token: Option<String>, ak: &str) -> S3Result<(auth:
|
|||||||
.await
|
.await
|
||||||
.map_err(|e| S3Error::with_message(S3ErrorCode::InternalError, format!("check claims failed {}", e)))?;
|
.map_err(|e| S3Error::with_message(S3ErrorCode::InternalError, format!("check claims failed {}", e)))?;
|
||||||
|
|
||||||
// if !ok {
|
if !ok {
|
||||||
// if u.credentials.status == "off" {
|
if let Some(u) = u {
|
||||||
// return Err(s3_error!(InvalidRequest, "ErrAccessKeyDisabled"));
|
if u.credentials.status == "off" {
|
||||||
// }
|
return Err(s3_error!(InvalidRequest, "ErrAccessKeyDisabled"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// return Err(s3_error!(InvalidRequest, "check key failed"));
|
return Err(s3_error!(InvalidRequest, "check key failed"));
|
||||||
// }
|
}
|
||||||
|
|
||||||
// match iam_store
|
let Some(u) = u else {
|
||||||
// .check_key(ak)
|
return Err(s3_error!(InvalidRequest, "check key failed"));
|
||||||
// .await
|
};
|
||||||
// .map_err(|e| S3Error::with_message(S3ErrorCode::InternalError, format!("check claims failed {}", e)))?
|
|
||||||
// {
|
|
||||||
// (Some(u), true) => {
|
|
||||||
// cred = u.credentials;
|
|
||||||
// }
|
|
||||||
// (Some(u), false) => {
|
|
||||||
// if u.credentials.status == "off" {
|
|
||||||
// return Err(s3_error!(InvalidRequest, "ErrAccessKeyDisabled"));
|
|
||||||
// }
|
|
||||||
|
|
||||||
// return Err(s3_error!(InvalidRequest, "check key failed"));
|
cred = u.credentials;
|
||||||
// }
|
|
||||||
// _ => {
|
|
||||||
// return Err(s3_error!(InvalidRequest, "check key failed"));
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unimplemented!()
|
let claims = check_claims_from_token(&security_token.unwrap_or_default(), &cred)
|
||||||
|
.map_err(|e| S3Error::with_message(S3ErrorCode::InternalError, format!("check claims failed {}", e)))?;
|
||||||
|
|
||||||
// if let Some(st) = token {
|
cred.claims = if !claims.is_empty() { Some(claims) } else { None };
|
||||||
// let claims = check_claims_from_token(&st, &cred)
|
|
||||||
// .map_err(|e| S3Error::with_message(S3ErrorCode::InternalError, format!("check claims failed {}", e)))?;
|
|
||||||
// cred.claims = Some(claims.to_map());
|
|
||||||
// }
|
|
||||||
|
|
||||||
// let owner = sys_cred.access_key == cred.access_key || cred.parent_user == sys_cred.access_key;
|
let mut owner = sys_cred.access_key == cred.access_key || cred.parent_user == sys_cred.access_key;
|
||||||
|
|
||||||
// // permitRootAccess
|
// permitRootAccess
|
||||||
// // SessionPolicyName
|
if let Some(claims) = &cred.claims {
|
||||||
// Ok((cred, owner))
|
if claims.contains_key(SESSION_POLICY_NAME) {
|
||||||
|
owner = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok((cred, owner))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn check_claims_from_token(token: &str, cred: &auth::Credentials) -> S3Result<STSClaims> {
|
pub fn check_claims_from_token(token: &str, cred: &auth::Credentials) -> S3Result<HashMap<String, Value>> {
|
||||||
unimplemented!()
|
if !token.is_empty() && cred.access_key.is_empty() {
|
||||||
// if !token.is_empty() && cred.access_key.is_empty() {
|
return Err(s3_error!(InvalidRequest, "no access key"));
|
||||||
// return Err(s3_error!(InvalidRequest, "no access key"));
|
}
|
||||||
// }
|
|
||||||
|
|
||||||
// if token.is_empty() && cred.is_temp() && !cred.is_service_account() {
|
if token.is_empty() && cred.is_temp() && !cred.is_service_account() {
|
||||||
// return Err(s3_error!(InvalidRequest, "invalid token"));
|
return Err(s3_error!(InvalidRequest, "invalid token"));
|
||||||
// }
|
}
|
||||||
|
|
||||||
// if !token.is_empty() && !cred.is_temp() {
|
if !token.is_empty() && !cred.is_temp() {
|
||||||
// return Err(s3_error!(InvalidRequest, "invalid token"));
|
return Err(s3_error!(InvalidRequest, "invalid token"));
|
||||||
// }
|
}
|
||||||
|
|
||||||
// if !cred.is_service_account() && cred.is_temp() && token != cred.session_token {
|
if !cred.is_service_account() && cred.is_temp() && token != cred.session_token {
|
||||||
// return Err(s3_error!(InvalidRequest, "invalid token"));
|
return Err(s3_error!(InvalidRequest, "invalid token"));
|
||||||
// }
|
}
|
||||||
|
|
||||||
// if cred.is_temp() || cred.is_expired() {
|
if cred.is_temp() || cred.is_expired() {
|
||||||
// return Err(s3_error!(InvalidRequest, "invalid access key"));
|
return Err(s3_error!(InvalidRequest, "invalid access key"));
|
||||||
// }
|
}
|
||||||
|
|
||||||
// let Some(sys_cred) = get_global_action_cred() else {
|
let Some(sys_cred) = get_global_action_cred() else {
|
||||||
// return Err(s3_error!(InternalError, "action cred not init"));
|
return Err(s3_error!(InternalError, "action cred not init"));
|
||||||
// };
|
};
|
||||||
|
|
||||||
// let mut secret = sys_cred.secret_key;
|
let mut secret = sys_cred.secret_key;
|
||||||
|
|
||||||
// let mut token = token;
|
// TODO: REPLICATION
|
||||||
|
|
||||||
// if cred.is_service_account() {
|
let mut token = token;
|
||||||
// token = cred.session_token.as_str();
|
|
||||||
// secret = cred.secret_key.clone();
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if !token.is_empty() {
|
if cred.is_service_account() {
|
||||||
// let claims: HashMap<String, String> =
|
token = cred.session_token.as_str();
|
||||||
// get_claims_from_token_with_secret(token, &secret).map_err(|_e| s3_error!(InvalidRequest, "invalid token"))?;
|
secret = cred.secret_key.clone();
|
||||||
// return Ok(claims);
|
}
|
||||||
// }
|
|
||||||
|
|
||||||
// Ok(STSClaims::default())
|
if !token.is_empty() {
|
||||||
|
let claims: HashMap<String, Value> =
|
||||||
|
get_claims_from_token_with_secret(token, &secret).map_err(|_e| s3_error!(InvalidRequest, "invalid token"))?;
|
||||||
|
return Ok(claims);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(HashMap::new())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_session_token(hds: &HeaderMap) -> Option<String> {
|
pub fn get_session_token(hds: &HeaderMap) -> Option<String> {
|
||||||
@@ -238,93 +190,130 @@ pub fn get_session_token(hds: &HeaderMap) -> Option<String> {
|
|||||||
.map(|v| v.to_str().unwrap_or_default().to_string())
|
.map(|v| v.to_str().unwrap_or_default().to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn populate_session_policy(claims: &mut HashMap<String, Value>, policy: &str) -> S3Result<()> {
|
||||||
|
if !policy.is_empty() {
|
||||||
|
let session_policy = Policy::parse_config(policy.as_bytes())
|
||||||
|
.map_err(|e| S3Error::with_message(S3ErrorCode::InternalError, format!("parse policy err {}", e)))?;
|
||||||
|
if session_policy.version.is_empty() {
|
||||||
|
return Err(s3_error!(InvalidRequest, "invalid policy"));
|
||||||
|
}
|
||||||
|
|
||||||
|
let policy_buf = serde_json::to_vec(&session_policy)
|
||||||
|
.map_err(|e| S3Error::with_message(S3ErrorCode::InternalError, format!("marshal policy err {}", e)))?;
|
||||||
|
|
||||||
|
if policy_buf.len() > 2048 {
|
||||||
|
return Err(s3_error!(InvalidRequest, "policy too large"));
|
||||||
|
}
|
||||||
|
|
||||||
|
claims.insert(SESSION_POLICY_NAME.to_string(), serde_json::Value::String(base64_encode(&policy_buf)));
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
pub struct AssumeRoleHandle {}
|
pub struct AssumeRoleHandle {}
|
||||||
#[async_trait::async_trait]
|
#[async_trait::async_trait]
|
||||||
impl Operation for AssumeRoleHandle {
|
impl Operation for AssumeRoleHandle {
|
||||||
async fn call(&self, req: S3Request<Body>, _params: Params<'_, '_>) -> S3Result<S3Response<(StatusCode, Body)>> {
|
async fn call(&self, req: S3Request<Body>, _params: Params<'_, '_>) -> S3Result<S3Response<(StatusCode, Body)>> {
|
||||||
unimplemented!()
|
warn!("handle AssumeRoleHandle");
|
||||||
// warn!("handle AssumeRoleHandle");
|
|
||||||
|
|
||||||
// let Some(user) = req.credentials else { return Err(s3_error!(InvalidRequest, "get cred failed")) };
|
let Some(user) = req.credentials else { return Err(s3_error!(InvalidRequest, "get cred failed")) };
|
||||||
|
|
||||||
|
let session_token = get_session_token(&req.headers);
|
||||||
|
if session_token.is_some() {
|
||||||
|
return Err(s3_error!(InvalidRequest, "AccessDenied1"));
|
||||||
|
}
|
||||||
|
|
||||||
|
let (cred, _owner) = check_key_valid(session_token, &user.access_key).await?;
|
||||||
|
|
||||||
// // TODO: 判断权限, 不允许sts访问
|
// // TODO: 判断权限, 不允许sts访问
|
||||||
|
if cred.is_temp() || cred.is_service_account() {
|
||||||
|
return Err(s3_error!(InvalidRequest, "AccessDenied"));
|
||||||
|
}
|
||||||
|
|
||||||
// let mut input = req.input;
|
let mut input = req.input;
|
||||||
|
|
||||||
// let Some(bytes) = input.take_bytes() else {
|
let Some(bytes) = input.take_bytes() else {
|
||||||
// return Err(s3_error!(InvalidRequest, "get body failed"));
|
return Err(s3_error!(InvalidRequest, "get body failed"));
|
||||||
// };
|
};
|
||||||
// let body: AssumeRoleRequest = from_bytes(&bytes).map_err(|_e| s3_error!(InvalidRequest, "get body failed"))?;
|
let body: AssumeRoleRequest = from_bytes(&bytes).map_err(|_e| s3_error!(InvalidRequest, "get body failed"))?;
|
||||||
|
|
||||||
// if body.action.as_str() != ASSUME_ROLE_ACTION {
|
if body.action.as_str() != ASSUME_ROLE_ACTION {
|
||||||
// return Err(s3_error!(InvalidArgument, "not suport action"));
|
return Err(s3_error!(InvalidArgument, "not suport action"));
|
||||||
// }
|
}
|
||||||
|
|
||||||
// if body.version.as_str() != ASSUME_ROLE_VERSION {
|
if body.version.as_str() != ASSUME_ROLE_VERSION {
|
||||||
// return Err(s3_error!(InvalidArgument, "not suport version"));
|
return Err(s3_error!(InvalidArgument, "not suport version"));
|
||||||
// }
|
}
|
||||||
|
|
||||||
|
let mut claims = cred.claims.unwrap_or_default();
|
||||||
|
|
||||||
|
populate_session_policy(&mut claims, &body.policy)?;
|
||||||
|
|
||||||
|
let exp = {
|
||||||
|
if body.duration_seconds > 0 {
|
||||||
|
body.duration_seconds
|
||||||
|
} else {
|
||||||
|
3600
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
claims.insert(
|
||||||
|
"exp".to_string(),
|
||||||
|
serde_json::Value::Number(serde_json::Number::from(OffsetDateTime::now_utc().unix_timestamp() + exp as i64)),
|
||||||
|
);
|
||||||
|
|
||||||
|
claims.insert("parent".to_string(), serde_json::Value::String(cred.access_key.clone()));
|
||||||
|
|
||||||
// warn!("AssumeRole get cred {:?}", &user);
|
// warn!("AssumeRole get cred {:?}", &user);
|
||||||
// warn!("AssumeRole get body {:?}", &body);
|
// warn!("AssumeRole get body {:?}", &body);
|
||||||
|
|
||||||
// let Ok(iam_store) = iam::get() else { return Err(s3_error!(InvalidRequest, "iam not init")) };
|
let Ok(iam_store) = iam::get() else { return Err(s3_error!(InvalidRequest, "iam not init")) };
|
||||||
|
|
||||||
// if let Err(_err) = iam_store.policy_db_get(&user.access_key, None).await {
|
if let Err(_err) = iam_store
|
||||||
// return Err(s3_error!(InvalidArgument, "invalid policy arg"));
|
.policy_db_get(&cred.access_key, &cred.groups.unwrap_or_default())
|
||||||
// }
|
.await
|
||||||
|
{
|
||||||
|
return Err(s3_error!(InvalidArgument, "invalid policy arg"));
|
||||||
|
}
|
||||||
|
|
||||||
// let Some(secret) = get_token_signing_key() else {
|
let Some(secret) = get_token_signing_key() else {
|
||||||
// return Err(s3_error!(InvalidArgument, "sk not init"));
|
return Err(s3_error!(InvalidArgument, "global active sk not init"));
|
||||||
// };
|
};
|
||||||
|
|
||||||
// let exp = {
|
info!("AssumeRole get claims {:?}", &claims);
|
||||||
// if body.duration_seconds > 0 {
|
|
||||||
// body.duration_seconds
|
|
||||||
// } else {
|
|
||||||
// 3600
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
|
|
||||||
// let mut claims = STSClaims {
|
let mut new_cred = get_new_credentials_with_metadata(&claims, &secret)
|
||||||
// parent: user.access_key.clone(),
|
.map_err(|e| S3Error::with_message(S3ErrorCode::InternalError, format!("get new cred failed {}", e)))?;
|
||||||
// exp,
|
|
||||||
// ..Default::default()
|
|
||||||
// };
|
|
||||||
|
|
||||||
// let ak = iam::utils::gen_access_key(20).unwrap_or_default();
|
new_cred.parent_user = cred.access_key.clone();
|
||||||
// let sk = iam::utils::gen_secret_key(32).unwrap_or_default();
|
|
||||||
|
|
||||||
// claims.access_key = ak.clone();
|
info!("AssumeRole get new_cred {:?}", &new_cred);
|
||||||
|
|
||||||
// let mut cred = match create_new_credentials_with_metadata(&ak, &sk, &claims, &secret, Some(exp)) {
|
if let Err(_err) = iam_store.set_temp_user(&new_cred.access_key, &new_cred, None).await {
|
||||||
// Ok(res) => res,
|
return Err(s3_error!(InternalError, "set_temp_user failed"));
|
||||||
// Err(_er) => return Err(s3_error!(InvalidRequest, "")),
|
}
|
||||||
// };
|
|
||||||
|
|
||||||
// cred.parent_user = user.access_key.clone();
|
// TODO: globalSiteReplicationSys
|
||||||
|
|
||||||
// if let Err(err) = iam_store.set_temp_user(&cred.access_key, &cred, None).await {
|
let resp = AssumeRoleOutput {
|
||||||
// error!("set_temp_user err {:?}", err);
|
credentials: Some(Credentials {
|
||||||
// return Err(s3_error!(InternalError, "set_temp_user failed"));
|
access_key_id: new_cred.access_key,
|
||||||
// }
|
expiration: Timestamp::from(
|
||||||
|
new_cred
|
||||||
|
.expiration
|
||||||
|
.unwrap_or(OffsetDateTime::now_utc().saturating_add(Duration::seconds(3600))),
|
||||||
|
),
|
||||||
|
secret_access_key: new_cred.secret_key,
|
||||||
|
session_token: new_cred.session_token,
|
||||||
|
}),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
|
||||||
// let resp = AssumeRoleOutput {
|
// getAssumeRoleCredentials
|
||||||
// credentials: Some(Credentials {
|
let output = xml::serialize::<AssumeRoleOutput>(&resp).unwrap();
|
||||||
// access_key_id: cred.access_key,
|
|
||||||
// expiration: Timestamp::from(
|
|
||||||
// cred.expiration
|
|
||||||
// .unwrap_or(OffsetDateTime::now_utc().saturating_add(Duration::seconds(3600))),
|
|
||||||
// ),
|
|
||||||
// secret_access_key: cred.secret_key,
|
|
||||||
// session_token: cred.session_token,
|
|
||||||
// }),
|
|
||||||
// ..Default::default()
|
|
||||||
// };
|
|
||||||
|
|
||||||
// // getAssumeRoleCredentials
|
Ok(S3Response::new((StatusCode::OK, Body::from(output))))
|
||||||
// let output = xml::serialize::<AssumeRoleOutput>(&resp).unwrap();
|
|
||||||
|
|
||||||
// Ok(S3Response::new((StatusCode::OK, Body::from(output))))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
use iam::cache::CacheInner;
|
|
||||||
use log::warn;
|
use log::warn;
|
||||||
use s3s::auth::S3Auth;
|
use s3s::auth::S3Auth;
|
||||||
use s3s::auth::SecretKey;
|
use s3s::auth::SecretKey;
|
||||||
|
|||||||
Reference in New Issue
Block a user