@@ -9,6 +9,7 @@ use std::path::PathBuf; |
| 9 | 9 | use std::sync::atomic::{AtomicBool, Ordering}; |
| 10 | 10 | use std::sync::{Arc, Condvar, Mutex}; |
| 11 | 11 | use std::thread; |
| 12 | +use std::time::{SystemTime, UNIX_EPOCH}; |
| 12 | 13 | use zbus::blocking::{Connection, Proxy}; |
| 13 | 14 | use zbus::fdo; |
| 14 | 15 | use zbus::zvariant::{OwnedObjectPath, OwnedValue, Str}; |
@@ -56,6 +57,15 @@ pub struct PolkitBackendConfig { |
| 56 | 57 | type Subject = (String, HashMap<String, OwnedValue>); |
| 57 | 58 | type Details = HashMap<String, String>; |
| 58 | 59 | type TemporaryAuthorization = (String, String, Subject, u64, u64); |
| 60 | + |
| 61 | +#[derive(Debug, Clone, serde::Serialize)] |
| 62 | +pub struct TemporaryAuthorizationRecord { |
| 63 | + pub authorization_id: String, |
| 64 | + pub action_id: String, |
| 65 | + pub obtained_at_unix: u64, |
| 66 | + pub expires_at_unix: u64, |
| 67 | + pub expires_in_secs: u64, |
| 68 | +} |
| 59 | 69 | const DEFAULT_AUTH_MAX_ATTEMPTS: usize = 3; |
| 60 | 70 | const DEFAULT_IDENTITY_SELECTION_ATTEMPTS: usize = 3; |
| 61 | 71 | const DEFAULT_RETENTION_SELECTION_ATTEMPTS: usize = 3; |
@@ -659,6 +669,33 @@ fn helper_outcome_label(outcome: HelperOutcome) -> &'static str { |
| 659 | 669 | } |
| 660 | 670 | } |
| 661 | 671 | |
| 672 | +pub fn enumerate_temporary_authorizations() -> Result<Vec<TemporaryAuthorizationRecord>> { |
| 673 | + let connection = Connection::system().context("failed to connect to system bus")?; |
| 674 | + let subject = build_subject(); |
| 675 | + let proxy = PolkitAgent::proxy(&connection)?; |
| 676 | + let authorizations: Vec<TemporaryAuthorization> = |
| 677 | + proxy.call("EnumerateTemporaryAuthorizations", &subject)?; |
| 678 | + let now_unix = SystemTime::now() |
| 679 | + .duration_since(UNIX_EPOCH) |
| 680 | + .map(|duration| duration.as_secs()) |
| 681 | + .unwrap_or(0); |
| 682 | + |
| 683 | + let mut entries = Vec::with_capacity(authorizations.len()); |
| 684 | + for (authorization_id, action_id, _subject, obtained_at_unix, expires_at_unix) in authorizations |
| 685 | + { |
| 686 | + let expires_in_secs = expires_at_unix.saturating_sub(now_unix); |
| 687 | + entries.push(TemporaryAuthorizationRecord { |
| 688 | + authorization_id, |
| 689 | + action_id, |
| 690 | + obtained_at_unix, |
| 691 | + expires_at_unix, |
| 692 | + expires_in_secs, |
| 693 | + }); |
| 694 | + } |
| 695 | + entries.sort_by(|left, right| left.action_id.cmp(&right.action_id)); |
| 696 | + Ok(entries) |
| 697 | +} |
| 698 | + |
| 662 | 699 | fn revoke_temporary_authorizations_for_action(action_id: &str) -> Result<usize> { |
| 663 | 700 | let connection = Connection::system().context("failed to connect to system bus")?; |
| 664 | 701 | let subject = build_subject(); |