multistore_sts/
responses.rs1use multistore::error::ProxyError;
4use multistore::types::TemporaryCredentials;
5use quick_xml::se::to_string as xml_to_string;
6use serde::Serialize;
7
8#[derive(Debug, Serialize)]
10#[serde(rename = "AssumeRoleWithWebIdentityResponse")]
11pub struct AssumeRoleWithWebIdentityResponse {
12 #[serde(rename = "AssumeRoleWithWebIdentityResult")]
13 pub result: AssumeRoleWithWebIdentityResult,
14}
15
16#[derive(Debug, Serialize)]
18pub struct AssumeRoleWithWebIdentityResult {
19 #[serde(rename = "Credentials")]
20 pub credentials: StsCredentials,
21 #[serde(rename = "AssumedRoleUser")]
22 pub assumed_role_user: AssumedRoleUser,
23}
24
25#[derive(Debug, Serialize)]
27pub struct StsCredentials {
28 #[serde(rename = "AccessKeyId")]
29 pub access_key_id: String,
30 #[serde(rename = "SecretAccessKey")]
31 pub secret_access_key: String,
32 #[serde(rename = "SessionToken")]
33 pub session_token: String,
34 #[serde(rename = "Expiration")]
35 pub expiration: String,
36}
37
38#[derive(Debug, Serialize)]
40pub struct AssumedRoleUser {
41 #[serde(rename = "AssumedRoleId")]
42 pub assumed_role_id: String,
43 #[serde(rename = "Arn")]
44 pub arn: String,
45}
46
47impl AssumeRoleWithWebIdentityResponse {
48 pub fn to_xml(&self) -> String {
50 format!(
51 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n{}",
52 xml_to_string(self).unwrap_or_default()
53 )
54 }
55}
56
57pub fn build_sts_response(creds: &TemporaryCredentials) -> (u16, String) {
59 let response = AssumeRoleWithWebIdentityResponse {
60 result: AssumeRoleWithWebIdentityResult {
61 credentials: StsCredentials {
62 access_key_id: creds.access_key_id.clone(),
63 secret_access_key: creds.secret_access_key.clone(),
64 session_token: creds.session_token.clone(),
65 expiration: creds.expiration.to_rfc3339(),
66 },
67 assumed_role_user: AssumedRoleUser {
68 assumed_role_id: creds.assumed_role_id.clone(),
69 arn: creds.assumed_role_id.clone(),
70 },
71 },
72 };
73 (200, response.to_xml())
74}
75
76pub fn build_sts_error_response(err: &ProxyError) -> (u16, String) {
78 let (status, code, message) = match err {
79 ProxyError::RoleNotFound(r) => (
80 400,
81 "MalformedPolicyDocument",
82 format!("role not found: {}", r),
83 ),
84 ProxyError::InvalidOidcToken(msg) => (400, "InvalidIdentityToken", msg.clone()),
85 ProxyError::InvalidRequest(msg) => (400, "InvalidParameterValue", msg.clone()),
86 ProxyError::AccessDenied => (403, "AccessDenied", "access denied".to_string()),
87 _ => (500, "InternalError", "internal error".to_string()),
88 };
89
90 let xml = format!(
91 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
92 <ErrorResponse>\
93 <Error>\
94 <Code>{}</Code>\
95 <Message>{}</Message>\
96 </Error>\
97 </ErrorResponse>",
98 code, message
99 );
100 (status, xml)
101}