distant_net/manager/server/
authentication.rs

1use std::collections::HashMap;
2use std::io;
3use std::sync::Arc;
4
5use async_trait::async_trait;
6use distant_auth::msg::*;
7use distant_auth::Authenticator;
8use tokio::sync::{oneshot, RwLock};
9
10use crate::manager::data::{ManagerAuthenticationId, ManagerResponse};
11use crate::server::ServerReply;
12
13/// Implementation of [`Authenticator`] used by a manger to perform authentication with
14/// remote servers it is managing.
15#[derive(Clone)]
16pub struct ManagerAuthenticator {
17    /// Used to communicate authentication requests
18    pub(super) reply: ServerReply<ManagerResponse>,
19
20    /// Used to store one-way response senders that are used to return callbacks
21    pub(super) registry:
22        Arc<RwLock<HashMap<ManagerAuthenticationId, oneshot::Sender<AuthenticationResponse>>>>,
23}
24
25impl ManagerAuthenticator {
26    /// Sends an [`Authentication`] `msg` that expects a reply, storing a callback.
27    async fn send(&self, msg: Authentication) -> io::Result<AuthenticationResponse> {
28        let (tx, rx) = oneshot::channel();
29        let id = rand::random();
30
31        self.registry.write().await.insert(id, tx);
32        self.reply.send(ManagerResponse::Authenticate { id, msg })?;
33        rx.await
34            .map_err(|x| io::Error::new(io::ErrorKind::Other, x))
35    }
36
37    /// Sends an [`Authentication`] `msg` without expecting a reply. No callback is stored.
38    fn fire(&self, msg: Authentication) -> io::Result<()> {
39        let id = rand::random();
40        self.reply.send(ManagerResponse::Authenticate { id, msg })?;
41        Ok(())
42    }
43}
44
45/// Represents an interface for submitting challenges for authentication.
46#[async_trait]
47impl Authenticator for ManagerAuthenticator {
48    async fn initialize(
49        &mut self,
50        initialization: Initialization,
51    ) -> io::Result<InitializationResponse> {
52        match self
53            .send(Authentication::Initialization(initialization))
54            .await
55        {
56            Ok(AuthenticationResponse::Initialization(x)) => Ok(x),
57            Ok(x) => Err(io::Error::new(
58                io::ErrorKind::Other,
59                format!("Unexpected response: {x:?}"),
60            )),
61            Err(x) => Err(x),
62        }
63    }
64
65    async fn challenge(&mut self, challenge: Challenge) -> io::Result<ChallengeResponse> {
66        match self.send(Authentication::Challenge(challenge)).await {
67            Ok(AuthenticationResponse::Challenge(x)) => Ok(x),
68            Ok(x) => Err(io::Error::new(
69                io::ErrorKind::Other,
70                format!("Unexpected response: {x:?}"),
71            )),
72            Err(x) => Err(x),
73        }
74    }
75
76    async fn verify(&mut self, verification: Verification) -> io::Result<VerificationResponse> {
77        match self.send(Authentication::Verification(verification)).await {
78            Ok(AuthenticationResponse::Verification(x)) => Ok(x),
79            Ok(x) => Err(io::Error::new(
80                io::ErrorKind::Other,
81                format!("Unexpected response: {x:?}"),
82            )),
83            Err(x) => Err(x),
84        }
85    }
86
87    async fn info(&mut self, info: Info) -> io::Result<()> {
88        self.fire(Authentication::Info(info))
89    }
90
91    async fn error(&mut self, error: Error) -> io::Result<()> {
92        self.fire(Authentication::Error(error))
93    }
94
95    async fn start_method(&mut self, start_method: StartMethod) -> io::Result<()> {
96        self.fire(Authentication::StartMethod(start_method))
97    }
98
99    async fn finished(&mut self) -> io::Result<()> {
100        self.fire(Authentication::Finished)
101    }
102}