multistore_sts/
request.rs1use multistore::error::ProxyError;
9
10#[derive(Debug, Clone)]
12pub struct StsRequest {
13 pub role_arn: String,
15 pub web_identity_token: String,
17 pub duration_seconds: Option<u64>,
19}
20
21pub fn try_parse_sts_request(query: Option<&str>) -> Option<Result<StsRequest, ProxyError>> {
29 let q = query?;
30 let params: Vec<(String, String)> = url::form_urlencoded::parse(q.as_bytes())
31 .map(|(k, v)| (k.to_string(), v.to_string()))
32 .collect();
33
34 let action = params.iter().find(|(k, _)| k == "Action");
35 match action {
36 Some((_, value)) if value == "AssumeRoleWithWebIdentity" => {}
37 _ => return None,
38 }
39
40 Some(parse_sts_params(¶ms))
41}
42
43fn parse_sts_params(params: &[(String, String)]) -> Result<StsRequest, ProxyError> {
44 let role_arn = params
45 .iter()
46 .find(|(k, _)| k == "RoleArn")
47 .map(|(_, v)| v.clone())
48 .ok_or_else(|| ProxyError::InvalidRequest("missing RoleArn".into()))?;
49
50 let web_identity_token = params
51 .iter()
52 .find(|(k, _)| k == "WebIdentityToken")
53 .map(|(_, v)| v.clone())
54 .ok_or_else(|| ProxyError::InvalidRequest("missing WebIdentityToken".into()))?;
55
56 let duration_seconds = params
57 .iter()
58 .find(|(k, _)| k == "DurationSeconds")
59 .and_then(|(_, v)| v.parse().ok());
60
61 Ok(StsRequest {
62 role_arn,
63 web_identity_token,
64 duration_seconds,
65 })
66}
67
68#[cfg(test)]
69mod tests {
70 use super::*;
71
72 #[test]
73 fn test_not_sts_request() {
74 assert!(try_parse_sts_request(None).is_none());
75 assert!(try_parse_sts_request(Some("prefix=foo/")).is_none());
76 assert!(try_parse_sts_request(Some("Action=ListBuckets")).is_none());
77 }
78
79 #[test]
80 fn test_valid_sts_request() {
81 let query = "Action=AssumeRoleWithWebIdentity&RoleArn=my-role&WebIdentityToken=tok123";
82 let result = try_parse_sts_request(Some(query)).unwrap().unwrap();
83 assert_eq!(result.role_arn, "my-role");
84 assert_eq!(result.web_identity_token, "tok123");
85 assert_eq!(result.duration_seconds, None);
86 }
87
88 #[test]
89 fn test_sts_request_with_duration() {
90 let query =
91 "Action=AssumeRoleWithWebIdentity&RoleArn=r&WebIdentityToken=t&DurationSeconds=7200";
92 let result = try_parse_sts_request(Some(query)).unwrap().unwrap();
93 assert_eq!(result.duration_seconds, Some(7200));
94 }
95
96 #[test]
97 fn test_missing_role_arn() {
98 let query = "Action=AssumeRoleWithWebIdentity&WebIdentityToken=tok";
99 let result = try_parse_sts_request(Some(query)).unwrap();
100 assert!(result.is_err());
101 }
102
103 #[test]
104 fn test_missing_web_identity_token() {
105 let query = "Action=AssumeRoleWithWebIdentity&RoleArn=role";
106 let result = try_parse_sts_request(Some(query)).unwrap();
107 assert!(result.is_err());
108 }
109}