git.delta.rocks / remowt / refs/commits / 075f10342c88

difftreelog

source

crates/polkit-shared/src/lib.rs2.7 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				"command: {}",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, "process: {}", 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						"user: {} {} {}",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}