use reqwest::Client;
use crate::dpop_provider::DpopProvider;
use crate::metadata::AuthorizationServerMetadata;
use crate::oauth::{
IntrospectionResponse, TokenExchangeOptions, TokenResponse, client_credentials_grant,
exchange_token, introspect_token, revoke_token,
};
use crate::transport::build_basic_auth_header;
use crate::{AuthplaneError, FetchSettings};
#[derive(Debug, Clone)]
pub struct AuthplaneAuth {
metadata: AuthorizationServerMetadata,
fetch_settings: FetchSettings,
http: Client,
}
impl AuthplaneAuth {
pub fn new(
metadata: AuthorizationServerMetadata,
fetch_settings: FetchSettings,
http: Client,
) -> Self {
Self {
metadata,
fetch_settings,
http,
}
}
pub fn metadata(&self) -> &AuthorizationServerMetadata {
&self.metadata
}
pub async fn client_credentials(
&self,
client_id: &str,
client_secret: &str,
scopes: &[String],
resources: &[String],
dpop: Option<&DpopProvider>,
) -> Result<TokenResponse, AuthplaneError> {
let token_endpoint = self.metadata.token_endpoint()?;
client_credentials_grant(
&self.http,
token_endpoint,
&build_basic_auth_header(client_id, client_secret),
&self.fetch_settings,
scopes,
resources,
dpop,
)
.await
}
pub async fn client_credentials_with_header(
&self,
auth_header: &str,
scopes: &[String],
resources: &[String],
dpop: Option<&DpopProvider>,
) -> Result<TokenResponse, AuthplaneError> {
let token_endpoint = self.metadata.token_endpoint()?;
client_credentials_grant(
&self.http,
token_endpoint,
auth_header,
&self.fetch_settings,
scopes,
resources,
dpop,
)
.await
}
pub async fn exchange_token(
&self,
client_id: &str,
client_secret: &str,
options: &TokenExchangeOptions,
dpop: Option<&DpopProvider>,
) -> Result<TokenResponse, AuthplaneError> {
let token_endpoint = self.metadata.token_endpoint()?;
exchange_token(
&self.http,
token_endpoint,
options,
&build_basic_auth_header(client_id, client_secret),
&self.fetch_settings,
dpop,
)
.await
}
pub async fn introspect(
&self,
client_id: &str,
client_secret: &str,
token: &str,
dpop: Option<&DpopProvider>,
) -> Result<IntrospectionResponse, AuthplaneError> {
let introspection_endpoint = self.metadata.introspection_endpoint()?;
introspect_token(
&self.http,
introspection_endpoint,
token,
&build_basic_auth_header(client_id, client_secret),
&self.fetch_settings,
dpop,
)
.await
}
pub async fn revoke(
&self,
client_id: &str,
client_secret: &str,
token: &str,
dpop: Option<&DpopProvider>,
) -> Result<(), AuthplaneError> {
let revocation_endpoint = self.metadata.revocation_endpoint()?;
revoke_token(
&self.http,
revocation_endpoint,
token,
&build_basic_auth_header(client_id, client_secret),
&self.fetch_settings,
dpop,
)
.await
}
}