Skip to content

Commit 6f27543

Browse files
committed
Revert removal of the Authenticate trait.
1 parent c8fc0cb commit 6f27543

File tree

7 files changed

+31
-5
lines changed

7 files changed

+31
-5
lines changed

Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ bufstream = "0.1.3"
2727
imap-proto = "0.16.1"
2828
nom = { version = "7.1.0", default-features = false }
2929
rsasl = { version = "2.0.0-rc.2", default-features = false, features = ["provider_base64"] }
30+
base64 = "0.13.0"
3031
chrono = { version = "0.4", default-features = false, features = ["std"]}
3132
lazy_static = "1.4"
3233
ouroboros = "0.15.0"

examples/rustls_sasl.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ fn fetch_inbox_top(
3232

3333
// the client we have here is unauthenticated.
3434
// to do anything useful with the e-mails, we need to log in
35-
let mut imap_session = client.authenticate(saslconfig, mechanism).map_err(|e| e.0)?;
35+
let mut imap_session = client.sasl_auth(saslconfig, mechanism).map_err(|e| e.0)?;
3636

3737
// we want to fetch the first email in the INBOX mailbox
3838
imap_session.select("INBOX")?;

src/authenticator.rs

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
/// This trait allows for pluggable authentication schemes. It is used by `Client::authenticate` to
2+
/// [authenticate using SASL](https://tools.ietf.org/html/rfc3501#section-6.2.2).
3+
pub trait Authenticator {
4+
/// The type of the response to the challenge. This will usually be a `Vec<u8>` or `String`.
5+
type Response: AsRef<[u8]>;
6+
7+
/// Each base64-decoded server challenge is passed to `process`.
8+
/// The returned byte-string is base64-encoded and then sent back to the server.
9+
fn process(&self, challenge: &[u8]) -> Self::Response;
10+
}

src/client.rs

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use std::sync::mpsc;
99
use std::sync::Arc;
1010
use rsasl::prelude::{Mechname, SASLClient, SASLConfig, Session as SASLSession, State as SASLState};
1111

12+
use super::authenticator::Authenticator;
1213
use super::error::{Bad, Bye, Error, No, ParseError, Result, ValidateError};
1314
use super::extensions;
1415
use super::parse::*;

src/error.rs

+11-3
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use std::net::TcpStream;
77
use std::result;
88
use std::str::Utf8Error;
99

10+
use base64::DecodeError;
1011
use bufstream::IntoInnerError as BufError;
1112
use imap_proto::{types::ResponseCode, Response};
1213
#[cfg(feature = "native-tls")]
@@ -239,7 +240,7 @@ pub enum ParseError {
239240
/// Indicates an error parsing the status response. Such as OK, NO, and BAD.
240241
Invalid(Vec<u8>),
241242
/// The client could not find or decode the server's authentication challenge.
242-
Authentication(String),
243+
Authentication(String, Option<DecodeError>),
243244
/// The client received data that was not UTF-8 encoded.
244245
DataNotUtf8(Vec<u8>, Utf8Error),
245246
}
@@ -248,7 +249,7 @@ impl fmt::Display for ParseError {
248249
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
249250
match *self {
250251
ParseError::Invalid(_) => f.write_str("Unable to parse status response"),
251-
ParseError::Authentication(_) => {
252+
ParseError::Authentication(_, _) => {
252253
f.write_str("Unable to parse authentication response")
253254
}
254255
ParseError::DataNotUtf8(_, _) => f.write_str("Unable to parse data as UTF-8 text"),
@@ -260,10 +261,17 @@ impl StdError for ParseError {
260261
fn description(&self) -> &str {
261262
match *self {
262263
ParseError::Invalid(_) => "Unable to parse status response",
263-
ParseError::Authentication(_) => "Unable to parse authentication response",
264+
ParseError::Authentication(_, _) => "Unable to parse authentication response",
264265
ParseError::DataNotUtf8(_, _) => "Unable to parse data as UTF-8 text",
265266
}
266267
}
268+
269+
fn cause(&self) -> Option<&dyn StdError> {
270+
match *self {
271+
ParseError::Authentication(_, Some(ref e)) => Some(e),
272+
_ => None,
273+
}
274+
}
267275
}
268276

269277
/// An [invalid character](https://tools.ietf.org/html/rfc3501#section-4.3) was found in a command

src/lib.rs

+3
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,9 @@ mod parse;
8181

8282
pub mod types;
8383

84+
mod authenticator;
85+
pub use crate::authenticator::Authenticator;
86+
8487
mod client;
8588
pub use crate::client::*;
8689
mod client_builder;

src/parse.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,10 @@ pub fn parse_authenticate_response(line: &str) -> Result<&str> {
1818
let data = cap.get(1).map(|x| x.as_str()).unwrap_or("");
1919
return Ok(data);
2020
}
21-
Err(Error::Parse(ParseError::Authentication(line.to_string())))
21+
Err(Error::Parse(ParseError::Authentication(
22+
line.to_string(),
23+
None,
24+
)))
2225
}
2326

2427
pub(crate) enum MapOrNot<'a, T> {

0 commit comments

Comments
 (0)