use super::AnonymousToken;
use crate::context::EmptyProvider;
use crate::error::SessionError;
use crate::mechanism::Authentication;
use crate::session::{MechanismData, MessageSent, State};
use crate::io::Write;
#[derive(Copy, Clone, Debug)]
pub struct Anonymous;
impl Authentication for Anonymous {
fn step(
&mut self,
session: &mut MechanismData,
_input: Option<&[u8]>,
writer: &mut dyn Write,
) -> Result<State, SessionError> {
session.maybe_need_with::<AnonymousToken, _, _>(&EmptyProvider, |token| {
writer.write_all(token.as_bytes())?;
Ok(())
})?;
Ok(State::Finished(MessageSent::Yes))
}
}
#[cfg(test)]
mod tests {
use crate::callback::{Context, Request, SessionCallback, SessionData};
use crate::error::SessionError;
use crate::mechanisms::anonymous::AnonymousToken;
use crate::test;
use std::io::Cursor;
struct C<'a> {
token: Option<&'a str>,
}
impl SessionCallback for C<'_> {
fn callback(
&self,
_session_data: &SessionData,
_context: &Context,
request: &mut Request,
) -> Result<(), SessionError> {
if let Some(token) = self.token {
request.satisfy::<AnonymousToken>(token)?;
}
Ok(())
}
}
fn test_token(token: Option<&'static str>, output: &[u8]) {
let config = test::server_config(C { token });
let mut session = test::client_session(config, &super::super::mechinfo::ANONYMOUS);
let mut out = Cursor::new(Vec::new());
let state = session.step(None, &mut out).unwrap();
let data = out.into_inner();
assert_eq!(output, &data[..]);
assert!(state.is_finished());
}
#[test]
fn test_with_token() {
let tokens = [
"thisisatoken",
"", ];
for token in tokens {
test_token(Some(token), token.as_bytes());
}
}
#[test]
fn test_no_token() {
test_token(None, b"");
}
}