use std::fmt::Debug;
use std::marker::PhantomData;
use time::OffsetDateTime;
use super::{Assigned, NotAssigned, ToAssign};
use crate::{CredentialUse, Luid, SspiPackage};
pub type EmptyAcquireCredentialsHandle<'a, C, A> = AcquireCredentialsHandle<'a, C, A, WithoutCredentialUse>;
pub type FilledAcquireCredentialsHandle<'a, C, A> = AcquireCredentialsHandle<'a, C, A, WithCredentialUse>;
#[derive(Debug, Clone)]
pub struct AcquireCredentialsHandleResult<C> {
pub credentials_handle: C,
pub expiry: Option<OffsetDateTime>,
}
impl<T> AcquireCredentialsHandleResult<T> {
pub fn transform_credentials_handle<T2>(self, transformer: &dyn Fn(T) -> T2) -> AcquireCredentialsHandleResult<T2> {
let Self {
credentials_handle,
expiry,
} = self;
AcquireCredentialsHandleResult {
credentials_handle: transformer(credentials_handle),
expiry,
}
}
}
pub struct AcquireCredentialsHandle<'a, CredsHandle, AuthData, CredentialUseSet>
where
CredentialUseSet: ToAssign,
{
pub(crate) phantom_cred_handle: PhantomData<CredsHandle>,
pub(crate) phantom_cred_use_set: PhantomData<CredentialUseSet>,
pub credential_use: CredentialUse,
pub principal_name: Option<&'a str>,
pub logon_id: Option<Luid>,
pub auth_data: Option<&'a AuthData>,
}
impl<CredsHandle, AuthData, CredentialUseSet> Debug
for AcquireCredentialsHandle<'_, CredsHandle, AuthData, CredentialUseSet>
where
CredentialUseSet: ToAssign,
AuthData: Debug,
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("AcquireCredentialsHandle")
.field("phantom_cred_handle", &self.phantom_cred_handle)
.field("phantom_cred_use_set", &self.phantom_cred_use_set)
.field("credential_use", &self.credential_use)
.field("principal_name", &self.principal_name)
.field("logon_id", &self.logon_id)
.field("auth_data", &self.auth_data)
.finish()
}
}
impl<'a, CredsHandle, AuthData, CredentialUseSet> AcquireCredentialsHandle<'a, CredsHandle, AuthData, CredentialUseSet>
where
CredentialUseSet: ToAssign,
{
pub fn new() -> Self {
Self {
phantom_cred_handle: PhantomData,
phantom_cred_use_set: PhantomData,
principal_name: None,
credential_use: CredentialUse::Inbound,
logon_id: None,
auth_data: None,
}
}
pub fn with_credential_use(
self,
credential_use: CredentialUse,
) -> AcquireCredentialsHandle<'a, CredsHandle, AuthData, WithCredentialUse> {
AcquireCredentialsHandle {
phantom_cred_handle: PhantomData,
phantom_cred_use_set: PhantomData,
principal_name: self.principal_name,
credential_use,
logon_id: self.logon_id,
auth_data: self.auth_data,
}
}
pub fn with_principal_name(self, principal_name: &'a str) -> Self {
Self {
principal_name: Some(principal_name),
..self
}
}
pub fn with_logon_id(self, logon_id: Luid) -> Self {
Self {
logon_id: Some(logon_id),
..self
}
}
pub fn with_auth_data(self, auth_data: &'a AuthData) -> Self {
Self {
auth_data: Some(auth_data),
..self
}
}
}
impl<CredsHandle, AuthData, CredentialUseSet> Default
for AcquireCredentialsHandle<'_, CredsHandle, AuthData, CredentialUseSet>
where
CredentialUseSet: ToAssign,
{
fn default() -> Self {
Self::new()
}
}
impl<'b, CredsHandle, AuthData> FilledAcquireCredentialsHandle<'b, CredsHandle, AuthData> {
pub(crate) fn full_transform<NewCredsHandle, NewAuthData>(
self,
auth_data: Option<&'b NewAuthData>,
) -> FilledAcquireCredentialsHandle<'b, NewCredsHandle, NewAuthData> {
AcquireCredentialsHandle {
phantom_cred_handle: PhantomData,
phantom_cred_use_set: PhantomData,
principal_name: self.principal_name,
credential_use: self.credential_use,
logon_id: self.logon_id,
auth_data,
}
}
}
impl<CredsHandle, AuthData> FilledAcquireCredentialsHandle<'_, CredsHandle, AuthData> {
pub fn execute(
self,
inner: SspiPackage<'_, CredsHandle, AuthData>,
) -> crate::Result<AcquireCredentialsHandleResult<CredsHandle>> {
inner.acquire_credentials_handle_impl(self)
}
}
#[derive(Debug)]
pub struct WithCredentialUse;
impl ToAssign for WithCredentialUse {}
impl Assigned for WithCredentialUse {}
#[derive(Debug)]
pub struct WithoutCredentialUse;
impl ToAssign for WithoutCredentialUse {}
impl NotAssigned for WithoutCredentialUse {}