distant_auth/handler/methods/
prompt.rs1use std::io;
2
3use async_trait::async_trait;
4use log::*;
5
6use crate::handler::AuthMethodHandler;
7use crate::msg::{
8 Challenge, ChallengeResponse, Error, Info, Verification, VerificationKind, VerificationResponse,
9};
10
11pub struct PromptAuthMethodHandler<T, U> {
14 text_prompt: T,
15 password_prompt: U,
16}
17
18impl<T, U> PromptAuthMethodHandler<T, U> {
19 pub fn new(text_prompt: T, password_prompt: U) -> Self {
20 Self {
21 text_prompt,
22 password_prompt,
23 }
24 }
25}
26
27#[async_trait]
28impl<T, U> AuthMethodHandler for PromptAuthMethodHandler<T, U>
29where
30 T: Fn(&str) -> io::Result<String> + Send + Sync + 'static,
31 U: Fn(&str) -> io::Result<String> + Send + Sync + 'static,
32{
33 async fn on_challenge(&mut self, challenge: Challenge) -> io::Result<ChallengeResponse> {
34 trace!("on_challenge({challenge:?})");
35 let mut answers = Vec::new();
36 for question in challenge.questions.iter() {
37 let mut lines = question.text.split('\n').collect::<Vec<_>>();
39
40 let line = lines.pop().unwrap();
42
43 for line in lines.into_iter() {
45 eprintln!("{line}");
46 }
47
48 let answer = (self.password_prompt)(line).unwrap_or_default();
51
52 answers.push(answer);
53 }
54 Ok(ChallengeResponse { answers })
55 }
56
57 async fn on_verification(
58 &mut self,
59 verification: Verification,
60 ) -> io::Result<VerificationResponse> {
61 trace!("on_verify({verification:?})");
62 match verification.kind {
63 VerificationKind::Host => {
64 eprintln!("{}", verification.text);
65
66 let answer = (self.text_prompt)("Enter [y/N]> ")?;
67 trace!("Verify? Answer = '{answer}'");
68 Ok(VerificationResponse {
69 valid: matches!(answer.trim(), "y" | "Y" | "yes" | "YES"),
70 })
71 }
72 x => {
73 error!("Unsupported verify kind: {x}");
74 Ok(VerificationResponse { valid: false })
75 }
76 }
77 }
78
79 async fn on_info(&mut self, info: Info) -> io::Result<()> {
80 trace!("on_info({info:?})");
81 println!("{}", info.text);
82 Ok(())
83 }
84
85 async fn on_error(&mut self, error: Error) -> io::Result<()> {
86 trace!("on_error({error:?})");
87 eprintln!("{}: {}", error.kind, error.text);
88 Ok(())
89 }
90}