use async_trait::async_trait;
use reqwest::{Client, RequestBuilder, Url};
use static_assertions::assert_impl_all;
use super::internal::Internal;
use super::protocol;
use super::IdOrName;
use crate::{AuthType, EndpointFilters, Error};
#[derive(Debug, Clone)]
pub struct ApplicationCredential {
inner: Internal,
}
assert_impl_all!(ApplicationCredential: Send, Sync);
impl ApplicationCredential {
pub fn new<U, S1, S2>(auth_url: U, id: S1, secret: S2) -> Result<Self, Error>
where
U: AsRef<str>,
S1: Into<String>,
S2: Into<String>,
{
let app_cred = protocol::ApplicationCredential {
id: IdOrName::Id(id.into()),
secret: secret.into(),
user: None,
};
let body = protocol::AuthRoot {
auth: protocol::Auth {
identity: protocol::Identity::ApplicationCredential(app_cred),
scope: None,
},
};
Ok(Self {
inner: Internal::new(auth_url.as_ref(), body)?,
})
}
pub fn with_user_id<U, S1, S2, S3>(
auth_url: U,
name: S1,
secret: S2,
user_id: S3,
) -> Result<Self, Error>
where
U: AsRef<str>,
S1: Into<String>,
S2: Into<String>,
S3: Into<String>,
{
let app_cred = protocol::ApplicationCredential {
id: IdOrName::Name(name.into()),
secret: secret.into(),
user: Some(IdOrName::Id(user_id.into())),
};
let body = protocol::AuthRoot {
auth: protocol::Auth {
identity: protocol::Identity::ApplicationCredential(app_cred),
scope: None,
},
};
Ok(Self {
inner: Internal::new(auth_url.as_ref(), body)?,
})
}
#[inline]
pub fn project(&self) -> Option<&IdOrName> {
self.inner.project()
}
}
#[async_trait]
impl AuthType for ApplicationCredential {
async fn authenticate(
&self,
client: &Client,
request: RequestBuilder,
) -> Result<RequestBuilder, Error> {
self.inner.authenticate(client, request).await
}
async fn get_endpoint(
&self,
client: &Client,
service_type: &str,
filters: &EndpointFilters,
) -> Result<Url, Error> {
self.inner.get_endpoint(client, service_type, filters).await
}
async fn refresh(&self, client: &Client) -> Result<(), Error> {
self.inner.refresh(client, true).await
}
}
#[cfg(test)]
pub mod test {
#![allow(unused_results)]
use reqwest::Url;
use super::ApplicationCredential;
#[test]
fn test_identity_new() {
let id = ApplicationCredential::new("http://127.0.0.1:8080/", "abcdef", "shhhh").unwrap();
let e = Url::parse(id.inner.token_endpoint()).unwrap();
assert_eq!(e.scheme(), "http");
assert_eq!(e.host_str().unwrap(), "127.0.0.1");
assert_eq!(e.port().unwrap(), 8080u16);
assert_eq!(e.path(), "/v3/auth/tokens");
}
}