git.delta.rocks / remowt / refs/commits / 960ee4bca68c

difftreelog

source

crates/polkit-shared/src/lib.rs3.4 KiBsourcehistory
1use std::collections::HashMap;2use std::{fmt, fs};34use nix::unistd::{Uid, User};5use serde::{Deserialize, Serialize};6use zbus::zvariant::{OwnedValue, Type, Value};78pub fn emphasize(s: impl AsRef<str>) -> String {9    format!("<span style=\"italic\">&lt;{}&gt;</span>", escape(s),)10}11fn command(s: impl AsRef<str>) -> String {12    format!("<u><tt>{}</tt></u>", s.as_ref())13}14fn escape(s: impl AsRef<str>) -> String {15    s.as_ref()16        .replace("&", "&quot;")17        .replace("<", "&lt;")18        .replace(">", "&gt;")19}2021pub struct PidDisplay(pub u32);22impl fmt::Display for PidDisplay {23    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {24        if self.0 == 1 {25            emphasize("init").fmt(f)26        } else if let Ok(proc) = fs::read_to_string(format!("/proc/{}/cmdline", self.0)) {27            write!(28                f,29                "<sub>command</sub>{}",30                command(31                    proc.replace("\0", " ")32                        .strip_suffix(" ")33                        .expect("cmdline should end with NUL")34                )35            )36        } else if let Ok(proc) = fs::read_to_string(format!("/proc/{}/comm", self.0)) {37            write!(f, "<sub>process</sub>{}", command(proc.replace("\0", " ")))38        } else {39            emphasize("unknown process").fmt(f)40        }41    }42}4344#[derive(Serialize, Deserialize, Type, PartialEq, Debug)]45pub struct Identity {46    pub kind: String,47    pub details: HashMap<String, OwnedValue>,48}4950impl Identity {51    pub fn uid(&self) -> Option<Uid> {52        if self.kind != "unix-user" {53            return None;54        }55        let uid = self.details.get("uid")?;56        let Value::U32(uid) = &**uid else {57            return None;58        };59        Some(Uid::from_raw(*uid))60    }61}6263impl fmt::Display for Identity {64    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {65        match self.kind.as_str() {66            "unix-user" => match self.details.get("uid").map(|v| &**v) {67                Some(Value::U32(uid)) => match User::from_uid(Uid::from_raw(*uid)) {68                    Ok(Some(u)) => write!(69                        f,70                        "<sub>user</sub>{}<sup>{}</sup>{}",71                        u.name,72                        u.uid,73                        if u.gecos.is_empty() {74                            "".to_owned()75                        } else {76                            format!(": {}", escape(u.gecos.to_string_lossy()))77                        }78                    ),79                    Ok(None) => emphasize("not found").fmt(f),80                    Err(e) => {81                        let user = format!("could not get user: {e}");82                        emphasize(&user).fmt(f)?;83                        Ok(())84                    }85                },8687                _ => emphasize("unknown uid").fmt(f),88            },89            _ => emphasize(format!("identity of unknown kind: {}", self.kind)).fmt(f),90        }91    }92}9394impl Clone for Identity {95    fn clone(&self) -> Self {96        Self {97            kind: self.kind.clone(),98            details: self99                .details100                .iter()101                .map(|(k, v)| (k.clone(), v.try_clone().expect("no fds are expected")))102                .collect(),103        }104    }105}106107#[derive(Serialize, Deserialize, Type, PartialEq, Debug)]108pub struct BackendRequest {109    pub cookie: String,110    pub environment: HashMap<String, String>,111    pub prompter_path: String,112    pub identity: Identity,113}