use crate::box_error::BoxError;
use crate::client::identity::{Identity, SharedIdentityResolver};
use crate::client::orchestrator::HttpRequest;
use crate::client::runtime_components::sealed::ValidateConfig;
use crate::client::runtime_components::{GetIdentityResolver, RuntimeComponents};
use crate::impl_shared_conversions;
use aws_smithy_types::config_bag::{ConfigBag, Storable, StoreReplace};
use aws_smithy_types::type_erasure::TypeErasedBox;
use aws_smithy_types::Document;
use std::borrow::Cow;
use std::fmt;
use std::sync::Arc;
#[cfg(feature = "http-auth")]
pub mod http;
pub mod static_resolver;
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)]
pub struct AuthSchemeId {
scheme_id: &'static str,
}
impl AuthSchemeId {
pub const fn new(scheme_id: &'static str) -> Self {
Self { scheme_id }
}
pub const fn as_str(&self) -> &'static str {
self.scheme_id
}
}
impl From<&'static str> for AuthSchemeId {
fn from(scheme_id: &'static str) -> Self {
Self::new(scheme_id)
}
}
#[derive(Debug)]
pub struct AuthSchemeOptionResolverParams(TypeErasedBox);
impl AuthSchemeOptionResolverParams {
pub fn new<T: fmt::Debug + Send + Sync + 'static>(params: T) -> Self {
Self(TypeErasedBox::new(params))
}
pub fn get<T: fmt::Debug + Send + Sync + 'static>(&self) -> Option<&T> {
self.0.downcast_ref()
}
}
impl Storable for AuthSchemeOptionResolverParams {
type Storer = StoreReplace<Self>;
}
pub trait ResolveAuthSchemeOptions: Send + Sync + fmt::Debug {
fn resolve_auth_scheme_options(
&self,
params: &AuthSchemeOptionResolverParams,
) -> Result<Cow<'_, [AuthSchemeId]>, BoxError>;
}
#[derive(Clone, Debug)]
pub struct SharedAuthSchemeOptionResolver(Arc<dyn ResolveAuthSchemeOptions>);
impl SharedAuthSchemeOptionResolver {
pub fn new(auth_scheme_option_resolver: impl ResolveAuthSchemeOptions + 'static) -> Self {
Self(Arc::new(auth_scheme_option_resolver))
}
}
impl ResolveAuthSchemeOptions for SharedAuthSchemeOptionResolver {
fn resolve_auth_scheme_options(
&self,
params: &AuthSchemeOptionResolverParams,
) -> Result<Cow<'_, [AuthSchemeId]>, BoxError> {
(*self.0).resolve_auth_scheme_options(params)
}
}
impl_shared_conversions!(
convert SharedAuthSchemeOptionResolver
from ResolveAuthSchemeOptions
using SharedAuthSchemeOptionResolver::new
);
pub trait AuthScheme: Send + Sync + fmt::Debug {
fn scheme_id(&self) -> AuthSchemeId;
fn identity_resolver(
&self,
identity_resolvers: &dyn GetIdentityResolver,
) -> Option<SharedIdentityResolver>;
fn signer(&self) -> &dyn Sign;
}
#[derive(Clone, Debug)]
pub struct SharedAuthScheme(Arc<dyn AuthScheme>);
impl SharedAuthScheme {
pub fn new(auth_scheme: impl AuthScheme + 'static) -> Self {
Self(Arc::new(auth_scheme))
}
}
impl AuthScheme for SharedAuthScheme {
fn scheme_id(&self) -> AuthSchemeId {
self.0.scheme_id()
}
fn identity_resolver(
&self,
identity_resolvers: &dyn GetIdentityResolver,
) -> Option<SharedIdentityResolver> {
self.0.identity_resolver(identity_resolvers)
}
fn signer(&self) -> &dyn Sign {
self.0.signer()
}
}
impl ValidateConfig for SharedAuthScheme {}
impl_shared_conversions!(convert SharedAuthScheme from AuthScheme using SharedAuthScheme::new);
pub trait Sign: Send + Sync + fmt::Debug {
fn sign_http_request(
&self,
request: &mut HttpRequest,
identity: &Identity,
auth_scheme_endpoint_config: AuthSchemeEndpointConfig<'_>,
runtime_components: &RuntimeComponents,
config_bag: &ConfigBag,
) -> Result<(), BoxError>;
}
#[non_exhaustive]
#[derive(Clone, Debug)]
pub struct AuthSchemeEndpointConfig<'a>(Option<&'a Document>);
impl<'a> AuthSchemeEndpointConfig<'a> {
pub fn empty() -> Self {
Self(None)
}
pub fn as_document(&self) -> Option<&'a Document> {
self.0
}
}
impl<'a> From<Option<&'a Document>> for AuthSchemeEndpointConfig<'a> {
fn from(value: Option<&'a Document>) -> Self {
Self(value)
}
}
impl<'a> From<&'a Document> for AuthSchemeEndpointConfig<'a> {
fn from(value: &'a Document) -> Self {
Self(Some(value))
}
}