use crate::SaslMechanism;
use serde::{Deserialize, Serialize};
use thiserror::Error;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum AuthMethod {
Anonymous,
SaslPlain,
SaslScramSha256,
SaslScramSha512,
SaslOAuthBearer,
SaslGssapi,
MTls,
}
impl AuthMethod {
#[must_use]
pub fn from_sasl(m: SaslMechanism) -> Self {
match m {
SaslMechanism::Plain => Self::SaslPlain,
SaslMechanism::ScramSha256 => Self::SaslScramSha256,
SaslMechanism::ScramSha512 => Self::SaslScramSha512,
SaslMechanism::OAuthBearer => Self::SaslOAuthBearer,
SaslMechanism::Gssapi => Self::SaslGssapi,
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Principal {
pub name: String,
pub auth_method: AuthMethod,
pub groups: Vec<String>,
}
impl Principal {
#[must_use]
pub fn to_kafka(&self) -> KafkaPrincipal {
KafkaPrincipal {
principal_type: "User".to_string(),
name: self.name.clone(),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct KafkaPrincipal {
pub principal_type: String,
pub name: String,
}
impl std::fmt::Display for KafkaPrincipal {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}:{}", self.principal_type, self.name)
}
}
impl std::str::FromStr for KafkaPrincipal {
type Err = String;
fn from_str(s: &str) -> Result<Self, String> {
let (pt, n) = s
.split_once(':')
.ok_or_else(|| format!("invalid principal {s:?}"))?;
Ok(Self {
principal_type: pt.into(),
name: n.into(),
})
}
}
#[derive(Debug, Error, Clone, PartialEq, Eq)]
pub enum AuthError {
#[error("unknown user")]
UnknownUser,
#[error("bad password")]
BadPassword,
#[error("bad proof")]
BadProof,
#[error("malformed message")]
MalformedMessage,
#[error("unsupported mechanism")]
UnsupportedMechanism,
#[error("invalid token")]
InvalidToken,
#[error("oauthbearer introspection transport: {0}")]
IntrospectionTransport(String),
}
#[cfg(test)]
mod tests {
use super::*;
use assert2::assert;
#[test]
fn from_sasl_mapping() {
assert!(AuthMethod::from_sasl(SaslMechanism::Plain) == AuthMethod::SaslPlain);
assert!(AuthMethod::from_sasl(SaslMechanism::ScramSha256) == AuthMethod::SaslScramSha256);
assert!(AuthMethod::from_sasl(SaslMechanism::ScramSha512) == AuthMethod::SaslScramSha512);
assert!(AuthMethod::from_sasl(SaslMechanism::OAuthBearer) == AuthMethod::SaslOAuthBearer);
assert!(AuthMethod::from_sasl(SaslMechanism::Gssapi) == AuthMethod::SaslGssapi);
}
}