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