1use aws_credential_types::attributes::AccountId;
7use aws_credential_types::provider::{self, error::CredentialsError};
8use aws_credential_types::Credentials as AwsCredentials;
9use aws_sdk_sts::types::{AssumedRoleUser, Credentials as StsCredentials};
10
11use std::time::{SystemTime, UNIX_EPOCH};
12
13pub(crate) fn into_credentials(
15 sts_credentials: Option<StsCredentials>,
16 assumed_role_user: Option<AssumedRoleUser>,
17 provider_name: &'static str,
18) -> provider::Result {
19 let sts_credentials = sts_credentials
20 .ok_or_else(|| CredentialsError::unhandled("STS credentials must be defined"))?;
21 let expiration = SystemTime::try_from(sts_credentials.expiration).map_err(|_| {
22 CredentialsError::unhandled(
23 "credential expiration time cannot be represented by a SystemTime",
24 )
25 })?;
26 let mut builder = AwsCredentials::builder()
27 .access_key_id(sts_credentials.access_key_id)
28 .secret_access_key(sts_credentials.secret_access_key)
29 .session_token(sts_credentials.session_token)
30 .expiry(expiration)
31 .provider_name(provider_name);
32 if let Some(AssumedRoleUser { arn, .. }) = assumed_role_user {
33 builder.set_account_id(Some(parse_account_id(&arn)?));
34 }
35 Ok(builder.build())
36}
37
38pub(crate) fn default_session_name(base: &str, ts: SystemTime) -> String {
44 let now = ts.duration_since(UNIX_EPOCH).expect("post epoch");
45 format!("{}-{}", base, now.as_millis())
46}
47
48fn parse_account_id(arn: &str) -> Result<AccountId, CredentialsError> {
55 let mut split = arn.splitn(6, ':');
56 let invalid_format =
57 || CredentialsError::unhandled("ARN must have 6 components delimited by `:`");
58 let _arn = split.next().ok_or_else(invalid_format)?;
59 let _partition = split.next().ok_or_else(invalid_format)?;
60 let _service = split.next().ok_or_else(invalid_format)?;
61 let _region = split.next().ok_or_else(invalid_format)?;
62 let account_id = split.next().ok_or_else(invalid_format)?;
63
64 Ok(account_id.into())
65}