aws_config/default_provider/
token.rs

1/*
2 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 * SPDX-License-Identifier: Apache-2.0
4 */
5
6use crate::{
7    meta::{region::ProvideRegion, token::TokenProviderChain},
8    provider_config::ProviderConfig,
9};
10use aws_credential_types::provider::{future, token::ProvideToken};
11
12/// Default access token provider chain
13///
14/// The region from the default region provider will be used
15pub async fn default_provider() -> impl ProvideToken {
16    DefaultTokenChain::builder().build().await
17}
18
19/// Default access token provider chain
20///
21/// Currently, the default chain only examines the shared config
22/// (`~/.aws/config`) file and the SSO token cache to resolve an
23/// access token.
24///
25/// The AWS CLI can be used to retrieve the initial access token into
26/// the SSO token cache. Once it's there, the SDK can refresh automatically
27/// long as the it remains refreshable (it will eventually expire).
28///
29/// # Examples
30/// Create a default chain with a custom region:
31/// ```no_run
32/// use aws_types::region::Region;
33/// use aws_config::default_provider::token::DefaultTokenChain;
34/// let token_provider = DefaultTokenChain::builder()
35///     .region(Region::new("us-west-1"))
36///     .build();
37/// ```
38///
39/// Create a default chain with no overrides:
40/// ```no_run
41/// use aws_config::default_provider::token::DefaultTokenChain;
42/// let token_provider = DefaultTokenChain::builder().build();
43/// ```
44///
45/// Create a default chain that uses a different profile:
46/// ```no_run
47/// use aws_config::default_provider::token::DefaultTokenChain;
48/// let token_provider = DefaultTokenChain::builder()
49///     .profile_name("otherprofile")
50///     .build();
51/// ```
52#[derive(Debug)]
53pub struct DefaultTokenChain {
54    provider_chain: TokenProviderChain,
55}
56
57impl DefaultTokenChain {
58    /// Builder for `DefaultTokenChain`.
59    pub fn builder() -> Builder {
60        Builder::default()
61    }
62}
63
64impl ProvideToken for DefaultTokenChain {
65    fn provide_token<'a>(&'a self) -> future::ProvideToken<'a>
66    where
67        Self: 'a,
68    {
69        self.provider_chain.provide_token()
70    }
71}
72
73/// Builder for [`DefaultTokenChain`].
74#[derive(Debug, Default)]
75pub struct Builder {
76    profile_file_builder: crate::profile::token::Builder,
77    region_override: Option<Box<dyn ProvideRegion>>,
78    region_chain: crate::default_provider::region::Builder,
79    conf: Option<ProviderConfig>,
80}
81
82impl Builder {
83    /// Sets the region used when making requests to AWS services
84    ///
85    /// When unset, the default region resolver chain will be used.
86    pub fn region(mut self, region: impl ProvideRegion + 'static) -> Self {
87        self.set_region(Some(region));
88        self
89    }
90
91    /// Sets the region used when making requests to AWS services
92    ///
93    /// When unset, the default region resolver chain will be used.
94    pub fn set_region(&mut self, region: Option<impl ProvideRegion + 'static>) -> &mut Self {
95        self.region_override = region.map(|provider| Box::new(provider) as _);
96        self
97    }
98
99    /// Override the profile name used by this provider
100    ///
101    /// When unset, the value of the `AWS_PROFILE` environment variable will be used.
102    pub fn profile_name(mut self, name: &str) -> Self {
103        self.profile_file_builder = self.profile_file_builder.profile_name(name);
104        self.region_chain = self.region_chain.profile_name(name);
105        self
106    }
107
108    /// Override the configuration used for this provider
109    pub(crate) fn configure(mut self, config: ProviderConfig) -> Self {
110        self.region_chain = self.region_chain.configure(&config);
111        self.conf = Some(config);
112        self
113    }
114
115    /// Creates a [`DefaultTokenChain`].
116    pub async fn build(self) -> DefaultTokenChain {
117        let region = match self.region_override {
118            Some(provider) => provider.region().await,
119            None => self.region_chain.build().region().await,
120        };
121        let conf = self.conf.unwrap_or_default().with_region(region);
122
123        let provider_chain = TokenProviderChain::first_try(
124            "Profile",
125            self.profile_file_builder.configure(&conf).build(),
126        );
127        DefaultTokenChain { provider_chain }
128    }
129}