use crate::context::EmptyProvider;
use crate::error::SessionError;
use crate::mechanism::Authentication;
use crate::property::AuthzId;
use crate::session::{MechanismData, MessageSent, State};
use crate::io::Write;
#[derive(Copy, Clone, Debug)]
pub struct External;
impl Authentication for External {
fn step(
&mut self,
session: &mut MechanismData,
_input: Option<&[u8]>,
writer: &mut dyn Write,
) -> Result<State, SessionError> {
session.maybe_need_with::<AuthzId, _, _>(&EmptyProvider, |authzid| {
writer.write_all(authzid.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::property::AuthzId;
use crate::test;
use std::io::Cursor;
struct C<'a> {
authzid: Option<&'a str>,
}
impl SessionCallback for C<'_> {
fn callback(
&self,
_session_data: &SessionData,
_context: &Context,
request: &mut Request,
) -> Result<(), SessionError> {
if let Some(authzid) = self.authzid {
request.satisfy::<AuthzId>(authzid)?;
}
Ok(())
}
}
fn test_authzid(authzid: Option<&'static str>, output: &[u8]) {
let config = test::server_config(C { authzid });
let mut session = test::client_session(config, &super::super::mechinfo::EXTERNAL);
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_external() {
let authzids = [
"", "heylookanauthzid",
"cn=this,ou=authzid,ou=has,o=weirdformatting",
"«küßî»",
"“ЌύБЇ”",
];
for authzid in authzids {
test_authzid(Some(authzid), authzid.as_bytes());
}
}
#[test]
fn test_no_authzid() {
test_authzid(None, b"");
}
}