use crate::error::SaslError;
use async_trait::async_trait;
use bytes::Bytes;
pub mod plain;
pub mod scram;
pub use plain::PlainMechanism;
pub use scram::AsyncScramMechanism;
#[derive(Debug, Clone)]
pub struct SaslCredentials {
pub mechanism: SaslMechanismType,
pub username: String,
pub password: String,
pub authzid: Option<String>, }
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SaslMechanismType {
Plain,
ScramSha256,
ScramSha512,
}
impl SaslMechanismType {
pub fn as_str(&self) -> &'static str {
match self {
Self::Plain => "PLAIN",
Self::ScramSha256 => "SCRAM-SHA-256",
Self::ScramSha512 => "SCRAM-SHA-512",
}
}
}
#[async_trait]
#[allow(dead_code)]
pub trait SaslMechanism: Send + Sync {
fn name(&self) -> &'static str;
fn is_client_first(&self) -> bool;
async fn initial_response(
&mut self,
credentials: &SaslCredentials,
) -> Result<Option<Bytes>, SaslError>;
async fn challenge(&mut self, challenge: &[u8]) -> Result<Option<Bytes>, SaslError>;
fn is_complete(&self) -> bool;
fn is_success(&self) -> bool;
fn reset(&mut self);
}
#[allow(dead_code)]
pub fn create_mechanism(mechanism_type: SaslMechanismType) -> Box<dyn SaslMechanism> {
match mechanism_type {
SaslMechanismType::Plain => Box::new(PlainMechanism::new()),
SaslMechanismType::ScramSha256 => Box::new(AsyncScramMechanism::new_sha256()),
SaslMechanismType::ScramSha512 => Box::new(AsyncScramMechanism::new_sha512()),
}
}