distant_auth/handler/methods/
static_key.rs1use std::fmt::Display;
2use std::io;
3
4use async_trait::async_trait;
5use log::*;
6
7use crate::handler::AuthMethodHandler;
8use crate::msg::{Challenge, ChallengeResponse, Error, Info, Verification, VerificationResponse};
9
10pub struct StaticKeyAuthMethodHandler<K> {
14 key: K,
15 handler: Box<dyn AuthMethodHandler>,
16}
17
18impl<K> StaticKeyAuthMethodHandler<K> {
19 pub fn new<T: AuthMethodHandler + 'static>(key: K, handler: T) -> Self {
22 Self {
23 key,
24 handler: Box::new(handler),
25 }
26 }
27
28 pub fn simple(key: K) -> Self {
32 Self::new(key, {
33 struct __AuthMethodHandler;
34
35 #[async_trait]
36 impl AuthMethodHandler for __AuthMethodHandler {
37 async fn on_challenge(&mut self, _: Challenge) -> io::Result<ChallengeResponse> {
38 unreachable!("on_challenge should be handled by StaticKeyAuthMethodHandler");
39 }
40
41 async fn on_verification(
42 &mut self,
43 _: Verification,
44 ) -> io::Result<VerificationResponse> {
45 Ok(VerificationResponse { valid: true })
46 }
47
48 async fn on_info(&mut self, _: Info) -> io::Result<()> {
49 Ok(())
50 }
51
52 async fn on_error(&mut self, _: Error) -> io::Result<()> {
53 Ok(())
54 }
55 }
56
57 __AuthMethodHandler
58 })
59 }
60}
61
62#[async_trait]
63impl<K> AuthMethodHandler for StaticKeyAuthMethodHandler<K>
64where
65 K: Display + Send,
66{
67 async fn on_challenge(&mut self, challenge: Challenge) -> io::Result<ChallengeResponse> {
68 trace!("on_challenge({challenge:?})");
69 let mut answers = Vec::new();
70 for question in challenge.questions.iter() {
71 if question.label != "key" {
73 return Err(io::Error::new(
74 io::ErrorKind::InvalidInput,
75 "Only 'key' challenges are supported",
76 ));
77 }
78 answers.push(self.key.to_string());
79 }
80 Ok(ChallengeResponse { answers })
81 }
82
83 async fn on_verification(
84 &mut self,
85 verification: Verification,
86 ) -> io::Result<VerificationResponse> {
87 trace!("on_verify({verification:?})");
88 self.handler.on_verification(verification).await
89 }
90
91 async fn on_info(&mut self, info: Info) -> io::Result<()> {
92 trace!("on_info({info:?})");
93 self.handler.on_info(info).await
94 }
95
96 async fn on_error(&mut self, error: Error) -> io::Result<()> {
97 trace!("on_error({error:?})");
98 self.handler.on_error(error).await
99 }
100}
101
102#[cfg(test)]
103mod tests {
104 use test_log::test;
105
106 use super::*;
107 use crate::msg::{ErrorKind, Question, VerificationKind};
108
109 #[test(tokio::test)]
110 async fn on_challenge_should_fail_if_non_key_question_received() {
111 let mut handler = StaticKeyAuthMethodHandler::simple(String::from("secret-key"));
112
113 handler
114 .on_challenge(Challenge {
115 questions: vec![Question::new("test")],
116 options: Default::default(),
117 })
118 .await
119 .unwrap_err();
120 }
121
122 #[test(tokio::test)]
123 async fn on_challenge_should_answer_with_stringified_key_for_key_questions() {
124 let mut handler = StaticKeyAuthMethodHandler::simple(String::from("secret-key"));
125
126 let response = handler
127 .on_challenge(Challenge {
128 questions: vec![Question::new("key")],
129 options: Default::default(),
130 })
131 .await
132 .unwrap();
133 assert_eq!(response.answers.len(), 1, "Wrong answer set received");
134 assert!(!response.answers[0].is_empty(), "Empty answer being sent");
135 }
136
137 #[test(tokio::test)]
138 async fn on_verification_should_leverage_fallback_handler() {
139 let mut handler = StaticKeyAuthMethodHandler::simple(String::from("secret-key"));
140
141 let response = handler
142 .on_verification(Verification {
143 kind: VerificationKind::Host,
144 text: "host".to_string(),
145 })
146 .await
147 .unwrap();
148 assert!(response.valid, "Unexpected result from fallback handler");
149 }
150
151 #[test(tokio::test)]
152 async fn on_info_should_leverage_fallback_handler() {
153 let mut handler = StaticKeyAuthMethodHandler::simple(String::from("secret-key"));
154
155 handler
156 .on_info(Info {
157 text: "info".to_string(),
158 })
159 .await
160 .unwrap();
161 }
162
163 #[test(tokio::test)]
164 async fn on_error_should_leverage_fallback_handler() {
165 let mut handler = StaticKeyAuthMethodHandler::simple(String::from("secret-key"));
166
167 handler
168 .on_error(Error {
169 kind: ErrorKind::Error,
170 text: "text".to_string(),
171 })
172 .await
173 .unwrap();
174 }
175}