Skip to main content

sysd_manager_proxy_lib/
lib.rs

1mod file;
2mod interface;
3mod sysdcom;
4use base::RunMode;
5pub mod install;
6use std::{collections::HashMap, error::Error, future::pending, sync::OnceLock};
7use tracing::{debug, info, warn};
8use tracing_subscriber::fmt;
9use zbus::{Connection, message::Header};
10use zbus_polkit::policykit1::{AuthorityProxy, CheckAuthorizationFlags, Subject};
11
12use crate::interface::{SysDManagerProxySignals, init_serve_connection};
13static AUTHORITY: OnceLock<AuthorityProxy> = OnceLock::new();
14static CONNECTION: OnceLock<Connection> = OnceLock::new();
15
16pub async fn init_authority() -> Result<(), zbus::Error> {
17    info!("Init Proxy Authority");
18    let connection = Connection::system().await?;
19    let proxy = AuthorityProxy::new(&connection).await?;
20
21    info!("backend name {}", proxy.backend_name().await?);
22    info!("backend version {}", proxy.backend_version().await?);
23    info!("backend feature {:?}", proxy.backend_features().await?);
24
25    AUTHORITY.get_or_init(|| proxy);
26    Ok(())
27}
28
29pub fn auth() -> &'static AuthorityProxy<'static> {
30    AUTHORITY.get().expect("REASON")
31}
32
33pub fn conn() -> &'static Connection {
34    CONNECTION.get().expect("REASON")
35}
36
37pub fn map() -> &'static HashMap<&'static str, &'static str> {
38    static MAP: OnceLock<HashMap<&str, &str>> = OnceLock::new();
39    MAP.get_or_init(HashMap::new)
40}
41
42pub struct SysDManagerProxy {}
43
44impl SysDManagerProxy {
45    pub fn new() -> Result<Self, zbus_polkit::Error> {
46        Ok(SysDManagerProxy {})
47    }
48
49    async fn check_autorisation(&self, header: Header<'_>) -> Result<(), zbus::fdo::Error> {
50        let autority = AUTHORITY.get().expect("REASON");
51
52        let subject = Subject::new_for_message_header(&header).map_err(|err| {
53            warn!("Subject new_for_message_header{:?}", err);
54            zbus::fdo::Error::AccessDenied("PolKit Subject".to_owned())
55        })?;
56        let authorization_result = autority
57            .check_authorization(
58                &subject,
59                "io.github.plrigaux.SysDManager",
60                map(),
61                CheckAuthorizationFlags::AllowUserInteraction.into(),
62                "",
63            )
64            .await;
65
66        match authorization_result {
67            Ok(a) => {
68                debug!("is_authorized {}", a.is_authorized);
69                if a.is_authorized {
70                    Ok(())
71                } else if a.is_challenge {
72                    let msg = format!("{:?}", a.details);
73                    Err(zbus::fdo::Error::InteractiveAuthorizationRequired(msg))
74                } else {
75                    let msg = format!("{:?}", a.details);
76                    Err(zbus::fdo::Error::AuthFailed(msg))
77                }
78            }
79            Err(e) => {
80                warn!("check_authorization {:?}", e);
81                let err: zbus::fdo::Error = e.into();
82                Err(err)
83            }
84        }
85    }
86}
87
88pub fn init_tracing() {
89    let timer = fmt::time::ChronoLocal::new("%Y-%m-%d %H:%M:%S%.3f".to_owned());
90    //let timer = fmt::time::ChronoLocal::rfc_3339();
91
92    tracing_subscriber::fmt()
93        .with_timer(timer)
94        .with_max_level(tracing::Level::DEBUG)
95        .with_line_number(true)
96        .init();
97}
98
99pub async fn serve_proxy(run_mode: RunMode) -> Result<(), Box<dyn Error>> {
100    init_authority().await?;
101    let (connection, path) = init_serve_connection(run_mode).await?;
102
103    connection
104        .object_server()
105        .interface(path)
106        .await?
107        .hello("bob")
108        .await?;
109    // Do other things or go to wait forever
110    pending::<()>().await;
111
112    Ok(())
113}