1pub(crate) mod ssh;
2
3#[macro_use]
4extern crate lazy_static;
5
6use std::{
7 error::Error,
8 sync::{mpsc::Sender, Arc},
9};
10
11use cursive::View;
12
13pub use cursive;
14pub use russh_keys;
15
16use russh_keys::key::{KeyPair, PublicKey};
17use ssh::{plugin::set_plugin, server::Server, session_manager::SessionManager};
18use tokio::sync::{mpsc, watch};
19
20#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
21pub struct SessionHandle(u64);
22
23pub trait AppSession {
24 fn on_start(
26 &mut self,
27 siv: &mut cursive::Cursive,
28 session_handle: SessionHandle,
29 pub_key: Option<PublicKey>,
30 force_refresh_sender: Sender<()>,
31 ) -> Result<Box<dyn View>, Box<dyn Error>>;
32
33 fn on_tick(&mut self, _siv: &mut cursive::Cursive) -> Result<(), Box<dyn Error>> {
35 Ok(())
36 }
37}
38
39pub trait App: Send + Sync {
41 fn on_load(&mut self) -> Result<(), Box<dyn Error>>;
43 fn new_session(&self) -> Box<dyn AppSession>;
45}
46
47pub struct AppServer {
49 port: u16,
50}
51
52impl AppServer {
53 pub fn new_with_port(port: u16) -> Self {
55 Self { port }
56 }
57
58 pub async fn run(
60 &mut self,
61 key_pairs: &[KeyPair],
62 plugin: Arc<dyn App>,
63 ) -> Result<(), Box<dyn Error>> {
64 set_plugin(plugin);
65 let (sender, receiver) = mpsc::channel(100);
66 let (_tx, rx) = watch::channel(false);
67 let repo = SessionManager::new(sender.clone(), receiver);
68 let sh = Server::new(key_pairs, rx, sender, self.port).await;
69 sh.listen(repo).await.unwrap();
70
71 Ok(())
72 }
73}