#![deny(missing_docs)]
use std::fmt;
use std::sync::Arc;
use crate::NifiClient;
use crate::error::NifiError;
#[async_trait::async_trait]
pub trait AuthProvider: Send + Sync + fmt::Debug {
async fn authenticate(&self, client: &NifiClient) -> Result<(), NifiError>;
}
#[async_trait::async_trait]
impl AuthProvider for Arc<dyn AuthProvider> {
async fn authenticate(&self, client: &NifiClient) -> Result<(), NifiError> {
(**self).authenticate(client).await
}
}
#[derive(Clone)]
pub struct PasswordAuth {
username: String,
password: zeroize::Zeroizing<String>,
}
impl PasswordAuth {
pub fn new(username: impl Into<String>, password: impl Into<String>) -> Self {
Self {
username: username.into(),
password: zeroize::Zeroizing::new(password.into()),
}
}
}
impl fmt::Debug for PasswordAuth {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("PasswordAuth")
.field("username", &self.username)
.field("password", &"[REDACTED]")
.finish()
}
}
#[async_trait::async_trait]
impl AuthProvider for PasswordAuth {
async fn authenticate(&self, client: &NifiClient) -> Result<(), NifiError> {
client.login(&self.username, &self.password).await
}
}
#[derive(Debug, Clone)]
pub struct EnvPasswordAuth {
username_var: String,
password_var: String,
}
impl EnvPasswordAuth {
pub fn new() -> Self {
Self {
username_var: "NIFI_USERNAME".to_string(),
password_var: "NIFI_PASSWORD".to_string(),
}
}
pub fn with_vars(username_var: impl Into<String>, password_var: impl Into<String>) -> Self {
Self {
username_var: username_var.into(),
password_var: password_var.into(),
}
}
pub fn username_var(&self) -> &str {
&self.username_var
}
pub fn password_var(&self) -> &str {
&self.password_var
}
}
impl Default for EnvPasswordAuth {
fn default() -> Self {
Self::new()
}
}
#[async_trait::async_trait]
impl AuthProvider for EnvPasswordAuth {
async fn authenticate(&self, client: &NifiClient) -> Result<(), NifiError> {
let username = std::env::var(&self.username_var).map_err(|_| NifiError::Auth {
message: format!("environment variable {} is not set", self.username_var),
})?;
let password =
zeroize::Zeroizing::new(std::env::var(&self.password_var).map_err(|_| {
NifiError::Auth {
message: format!("environment variable {} is not set", self.password_var),
}
})?);
client.login(&username, &password).await
}
}
#[derive(Clone)]
pub struct StaticTokenAuth {
token: zeroize::Zeroizing<String>,
}
impl StaticTokenAuth {
pub fn new(token: impl Into<String>) -> Self {
Self {
token: zeroize::Zeroizing::new(token.into()),
}
}
}
impl fmt::Debug for StaticTokenAuth {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("StaticTokenAuth")
.field("token", &"[REDACTED]")
.finish()
}
}
#[async_trait::async_trait]
impl AuthProvider for StaticTokenAuth {
async fn authenticate(&self, client: &NifiClient) -> Result<(), NifiError> {
client.set_token((*self.token).clone()).await;
Ok(())
}
}