Skip to main content

aws_lite_rs/api/
sts.rs

1//! AWS Security Token Service API client.
2//!
3//! Thin wrapper over generated ops. All URL construction and HTTP methods
4//! are in `ops::sts::StsOps`. This layer adds:
5//! - Ergonomic method signatures
6
7use crate::{
8    AwsHttpClient, Result,
9    ops::sts::StsOps,
10    types::sts::{
11        AssumeRoleRequest, AssumeRoleResponse, GetCallerIdentityRequest, GetCallerIdentityResponse,
12    },
13};
14
15/// Client for the AWS Security Token Service API.
16pub struct StsClient<'a> {
17    ops: StsOps<'a>,
18}
19
20impl<'a> StsClient<'a> {
21    /// Create a new AWS Security Token Service API client.
22    pub(crate) fn new(client: &'a AwsHttpClient) -> Self {
23        Self {
24            ops: StsOps::new(client),
25        }
26    }
27
28    /// Returns details about the IAM user or role whose credentials are used
29    /// to call the operation.
30    pub async fn get_caller_identity(&self) -> Result<GetCallerIdentityResponse> {
31        let body = GetCallerIdentityRequest::default();
32        self.ops.get_caller_identity(&body).await
33    }
34
35    /// Returns a set of temporary security credentials for cross-account access.
36    pub async fn assume_role(&self, body: &AssumeRoleRequest) -> Result<AssumeRoleResponse> {
37        self.ops.assume_role(body).await
38    }
39}
40
41#[cfg(test)]
42mod tests {
43    use crate::AwsHttpClient;
44    use crate::mock_client::MockClient;
45    use crate::test_support::sts_mock_helpers::StsMockHelpers;
46
47    fn xml_envelope(action: &str, inner: &str) -> Vec<u8> {
48        format!("<{action}Response><{action}Result>{inner}</{action}Result></{action}Response>")
49            .into_bytes()
50    }
51
52    #[tokio::test]
53    async fn get_caller_identity_returns_parsed_response() {
54        let mut mock = MockClient::new();
55        mock.expect_get_caller_identity()
56            .returning_bytes(xml_envelope(
57                "GetCallerIdentity",
58                "<Account>265411104181</Account>\
59             <Arn>arn:aws:iam::265411104181:root</Arn>\
60             <UserId>265411104181</UserId>",
61            ));
62
63        let client = AwsHttpClient::from_mock(mock);
64        let response = client.sts().get_caller_identity().await.unwrap();
65
66        assert_eq!(response.account.as_deref(), Some("265411104181"));
67        assert_eq!(
68            response.arn.as_deref(),
69            Some("arn:aws:iam::265411104181:root")
70        );
71        assert_eq!(response.user_id.as_deref(), Some("265411104181"));
72    }
73
74    #[tokio::test]
75    async fn assume_role_returns_credentials() {
76        let mut mock = MockClient::new();
77        mock.expect_assume_role().returning_bytes(xml_envelope(
78            "AssumeRole",
79            "<Credentials>\
80               <AccessKeyId>ASIATESTACCESSKEY</AccessKeyId>\
81               <SecretAccessKey>testsecretkey123</SecretAccessKey>\
82               <SessionToken>testsessiontoken456</SessionToken>\
83               <Expiration>2024-01-15T12:00:00Z</Expiration>\
84             </Credentials>\
85             <AssumedRoleUser>\
86               <AssumedRoleId>AROATESTROLE:test-session</AssumedRoleId>\
87               <Arn>arn:aws:sts::123456789012:assumed-role/TestRole/test-session</Arn>\
88             </AssumedRoleUser>",
89        ));
90
91        let client = AwsHttpClient::from_mock(mock);
92        let body = crate::types::sts::AssumeRoleRequest {
93            role_arn: "arn:aws:iam::123456789012:role/TestRole".to_string(),
94            role_session_name: "test-session".to_string(),
95            ..Default::default()
96        };
97        let response = client.sts().assume_role(&body).await.unwrap();
98
99        let creds = response
100            .credentials
101            .as_ref()
102            .expect("credentials should be set");
103        assert_eq!(creds.access_key_id, "ASIATESTACCESSKEY");
104        assert_eq!(creds.secret_access_key, "testsecretkey123");
105        assert_eq!(creds.session_token, "testsessiontoken456");
106        assert_eq!(creds.expiration, "2024-01-15T12:00:00Z");
107
108        let assumed = response
109            .assumed_role_user
110            .as_ref()
111            .expect("assumed role user should be set");
112        assert_eq!(assumed.assumed_role_id, "AROATESTROLE:test-session");
113        assert_eq!(
114            assumed.arn,
115            "arn:aws:sts::123456789012:assumed-role/TestRole/test-session"
116        );
117    }
118}