use reqsign_core::SigningCredential;
use reqsign_core::time::Timestamp;
use reqsign_core::utils::Redact;
use std::fmt::{Debug, Formatter};
use std::time::Duration;
#[derive(Clone)]
pub enum Credential {
SharedKey {
account_name: String,
account_key: String,
},
SasToken {
token: String,
},
BearerToken {
token: String,
expires_in: Option<Timestamp>,
},
}
impl Debug for Credential {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
Credential::SharedKey {
account_name,
account_key,
} => f
.debug_struct("Credential::SharedKey")
.field("account_name", &Redact::from(account_name))
.field("account_key", &Redact::from(account_key))
.finish(),
Credential::SasToken { token } => f
.debug_struct("Credential::SasToken")
.field("token", &Redact::from(token))
.finish(),
Credential::BearerToken { token, expires_in } => f
.debug_struct("Credential::BearerToken")
.field("token", &Redact::from(token))
.field("expires_in", expires_in)
.finish(),
}
}
}
impl SigningCredential for Credential {
fn is_valid(&self) -> bool {
match self {
Credential::SharedKey {
account_name,
account_key,
} => !account_name.is_empty() && !account_key.is_empty(),
Credential::SasToken { token } => !token.is_empty(),
Credential::BearerToken { token, expires_in } => {
if token.is_empty() {
return false;
}
if let Some(expires) = expires_in {
*expires > Timestamp::now() + Duration::from_secs(20)
} else {
true
}
}
}
}
}
impl Credential {
pub fn with_shared_key(account_name: &str, account_key: &str) -> Self {
Self::SharedKey {
account_name: account_name.to_string(),
account_key: account_key.to_string(),
}
}
pub fn with_sas_token(sas_token: &str) -> Self {
Self::SasToken {
token: sas_token.to_string(),
}
}
pub fn with_bearer_token(bearer_token: &str, expires_in: Option<Timestamp>) -> Self {
Self::BearerToken {
token: bearer_token.to_string(),
expires_in,
}
}
}