use cts_common::{CtsServiceDiscovery, Region, ServiceDiscovery};
use crate::access_key::AccessKey;
use crate::access_key_refresher::AccessKeyRefresher;
use crate::auto_refresh::AutoRefresh;
use crate::{ensure_trailing_slash, AuthError, AuthStrategy, SecretToken, ServiceToken};
pub struct AccessKeyStrategy {
inner: AutoRefresh<AccessKeyRefresher>,
}
impl AccessKeyStrategy {
pub fn new(region: Region, access_key: AccessKey) -> Result<Self, AuthError> {
Self::builder(region, access_key).build()
}
pub fn builder(region: Region, access_key: AccessKey) -> AccessKeyStrategyBuilder {
AccessKeyStrategyBuilder {
region,
access_key: access_key.into_secret_token(),
audience: None,
base_url_override: None,
}
}
}
impl AuthStrategy for &AccessKeyStrategy {
async fn get_token(self) -> Result<ServiceToken, AuthError> {
Ok(self.inner.get_token().await?)
}
}
pub struct AccessKeyStrategyBuilder {
region: Region,
access_key: SecretToken,
audience: Option<String>,
base_url_override: Option<url::Url>,
}
impl AccessKeyStrategyBuilder {
pub fn audience(mut self, audience: impl Into<String>) -> Self {
self.audience = Some(audience.into());
self
}
#[cfg(any(test, feature = "test-utils"))]
pub fn base_url(mut self, url: url::Url) -> Self {
self.base_url_override = Some(url);
self
}
pub fn build(self) -> Result<AccessKeyStrategy, AuthError> {
let base_url = match self.base_url_override {
Some(url) => url,
None => crate::cts_base_url_from_env()?
.unwrap_or(CtsServiceDiscovery::endpoint(self.region)?),
};
let refresher = AccessKeyRefresher::new(
self.access_key,
ensure_trailing_slash(base_url),
self.audience,
);
Ok(AccessKeyStrategy {
inner: AutoRefresh::new(refresher),
})
}
}