diff --git a/Cargo.lock b/Cargo.lock index c138585ab..507f9d4f7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2110,7 +2110,11 @@ dependencies = [ "hyper", "matchit 0.8.5", "pin-project-lite", + "quick-xml", "s3s", + "serde", + "serde-xml-rs", + "serde_urlencoded", "tracing", ] @@ -2325,6 +2329,18 @@ dependencies = [ "serde_derive", ] +[[package]] +name = "serde-xml-rs" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb3aa78ecda1ebc9ec9847d5d3aba7d618823446a049ba2491940506da6e2782" +dependencies = [ + "log", + "serde", + "thiserror", + "xml-rs", +] + [[package]] name = "serde_derive" version = "1.0.214" @@ -3200,6 +3216,12 @@ version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" +[[package]] +name = "xml-rs" +version = "0.8.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af310deaae937e48a26602b730250b4949e125f468f11e6990be3e5304ddd96f" + [[package]] name = "xxhash-rust" version = "0.8.12" diff --git a/ecstore/src/options.rs b/ecstore/src/options.rs index 0751b3d9b..bf787c40a 100644 --- a/ecstore/src/options.rs +++ b/ecstore/src/options.rs @@ -64,7 +64,7 @@ pub fn put_opts_from_headers( } fn get_default_opts( - headers: &HeaderMap, + _headers: &HeaderMap, metadata: HashMap, _copy_source: bool, ) -> Result { diff --git a/router/Cargo.toml b/router/Cargo.toml index 31e05d448..422643924 100644 --- a/router/Cargo.toml +++ b/router/Cargo.toml @@ -15,3 +15,7 @@ hyper.workspace = true matchit = "0.8.4" pin-project-lite.workspace = true common.workspace = true +serde_urlencoded = "0.7.1" +serde.workspace = true +quick-xml = "0.37.0" +serde-xml-rs = "0.6.0" diff --git a/router/src/handlers.rs b/router/src/handlers.rs index 5e4a0213d..84345eb18 100644 --- a/router/src/handlers.rs +++ b/router/src/handlers.rs @@ -1,17 +1,88 @@ +use crate::router::Operation; use hyper::StatusCode; use matchit::Params; use s3s::{s3_error, Body, S3Request, S3Response, S3Result}; +use serde::{Deserialize, Serialize}; +use serde_urlencoded::from_bytes; use tracing::warn; -use crate::router::Operation; +#[derive(Deserialize, Debug, Default)] +#[serde(rename_all = "PascalCase", default)] +pub struct AssumeRoleRequest { + pub action: String, + pub duration_seconds: usize, + pub version: String, + pub role_arn: String, + pub role_session_name: String, + pub policy: 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, +} pub struct AssumeRoleHandle {} #[async_trait::async_trait] impl Operation for AssumeRoleHandle { - async fn call(&self, _req: S3Request, _params: Params<'_, '_>) -> S3Result> { + async fn call(&self, req: S3Request, _params: Params<'_, '_>) -> S3Result> { warn!("handle AssumeRoleHandle"); - return Err(s3_error!(NotImplemented)); + let Some(cred) = req.credentials else { return Err(s3_error!(InvalidRequest, "get body failed")) }; + + warn!("AssumeRole get cred {:?}", cred); + + let mut input = req.input; + + let Some(bytes) = input.take_bytes() else { + return Err(s3_error!(InvalidRequest, "get body failed")); + }; + let body: AssumeRoleRequest = from_bytes(&bytes).map_err(|_e| s3_error!(InvalidRequest, "get body failed"))?; + + warn!("AssumeRole get body {:?}", body); + + let resp = AssumeRoleResponse { + result: AssumeRoleResult { + credentials: Credentials { + access_key: "test".to_owned(), + secret_key: "test".to_owned(), + status: "on".to_owned(), + expiration: 0, + session_token: "sdf".to_owned(), + parent_user: cred.access_key, + }, + }, + }; + // getAssumeRoleCredentials + let output = serde_xml_rs::to_string(&resp).unwrap(); + + warn!("output {:?}", output); + + Ok(S3Response::new((StatusCode::OK, Body::from(output)))) + + // return Err(s3_error!(NotImplemented)); } }