simplify the API regarding authentication

This commit is contained in:
lumi 2017-02-25 06:49:13 +01:00
commit 6579ce6563
6 changed files with 99 additions and 19 deletions

View file

@ -1,6 +1,6 @@
//! Provides the SASL "ANONYMOUS" mechanism.
use sasl::SaslMechanism;
use sasl::{SaslMechanism, SaslCredentials, SaslSecret};
pub struct Anonymous;
@ -12,4 +12,13 @@ impl Anonymous {
impl SaslMechanism for Anonymous {
fn name(&self) -> &str { "ANONYMOUS" }
fn from_credentials(credentials: SaslCredentials) -> Result<Anonymous, String> {
if let SaslSecret::None = credentials.secret {
Ok(Anonymous)
}
else {
Err("the anonymous sasl mechanism requires no credentials".to_owned())
}
}
}

View file

@ -1,6 +1,6 @@
//! Provides the SASL "PLAIN" mechanism.
use sasl::SaslMechanism;
use sasl::{SaslMechanism, SaslCredentials, SaslSecret};
pub struct Plain {
username: String,
@ -19,6 +19,15 @@ impl Plain {
impl SaslMechanism for Plain {
fn name(&self) -> &str { "PLAIN" }
fn from_credentials(credentials: SaslCredentials) -> Result<Plain, String> {
if let SaslSecret::Password(password) = credentials.secret {
Ok(Plain::new(credentials.username, password))
}
else {
Err("PLAIN requires a password".to_owned())
}
}
fn initial(&mut self) -> Result<Vec<u8>, String> {
let mut auth = Vec::new();
auth.push(0);

View file

@ -2,7 +2,7 @@
use base64;
use sasl::SaslMechanism;
use sasl::{SaslMechanism, SaslCredentials, SaslSecret};
use error::Error;
@ -172,6 +172,22 @@ impl<S: ScramProvider> SaslMechanism for Scram<S> {
&self.name
}
fn from_credentials(credentials: SaslCredentials) -> Result<Scram<S>, String> {
if let SaslSecret::Password(password) = credentials.secret {
if let Some(binding) = credentials.channel_binding {
Scram::new_with_channel_binding(credentials.username, password, binding)
.map_err(|_| "can't generate nonce".to_owned())
}
else {
Scram::new(credentials.username, password)
.map_err(|_| "can't generate nonce".to_owned())
}
}
else {
Err("SCRAM requires a password".to_owned())
}
}
fn initial(&mut self) -> Result<Vec<u8>, String> {
let mut gs2_header = Vec::new();
if let Some(_) = self.channel_binding {

View file

@ -1,9 +1,23 @@
//! Provides the `SaslMechanism` trait and some implementations.
pub struct SaslCredentials {
pub username: String,
pub secret: SaslSecret,
pub channel_binding: Option<Vec<u8>>,
}
pub enum SaslSecret {
None,
Password(String),
}
pub trait SaslMechanism {
/// The name of the mechanism.
fn name(&self) -> &str;
/// Creates this mechanism from `SaslCredentials`.
fn from_credentials(credentials: SaslCredentials) -> Result<Self, String> where Self: Sized;
/// Provides initial payload of the SASL mechanism.
fn initial(&mut self) -> Result<Vec<u8>, String> {
Ok(Vec::new())