diff --git a/daemon/src/dbus.rs b/daemon/src/dbus.rs index 0bc8bb3..2368559 100644 --- a/daemon/src/dbus.rs +++ b/daemon/src/dbus.rs @@ -1,7 +1,9 @@ use crate::polkit::Polkit; use crate::state::AppState; use authforge_common::policy::Policy; -use authforge_common::types::{Credential, PendingFlag, PolicyApplyResult, RecoveryCodeSummary}; +use authforge_common::types::{ + Credential, PendingFlag, PendingStatus, PolicyApplyResult, RecoveryCodeSummary, +}; use std::sync::Arc; pub struct AuthForge { @@ -129,6 +131,14 @@ impl AuthForge { Ok(()) } + async fn get_pending_status(&self, user: String) -> zbus::fdo::Result { + // No polkit gate — pure read; daemon's pattern is gates on writes only. + self.state + .get_pending_status(&user) + .await + .map_err(|e| zbus::fdo::Error::Failed(e.to_string())) + } + async fn generate_recovery_code(&self, user: String) -> zbus::fdo::Result { self.authz("io.dangerousthings.AuthForge.generate-recovery") .await?; @@ -387,6 +397,34 @@ central_path = "{}" assert!(!state.has_pending("alice").await.unwrap()); } + #[tokio::test] + async fn pending_status_is_absent_for_fresh_user() { + let (_srv, client, _state, _tmp) = p2p_pair().await; + let p = proxy(&client).await; + let s: PendingStatus = p.call("GetPendingStatus", &("alice",)).await.unwrap(); + assert!(!s.present); + assert!(s.flag.required_methods.is_empty()); + } + + #[tokio::test] + async fn pending_status_round_trips_set_flag() { + let (_srv, client, _state, _tmp) = p2p_pair().await; + let p = proxy(&client).await; + let flag = PendingFlag { + required_methods: vec![Method::Fido2], + created_unix: 100, + deadline_unix: 200, + re_enroll: true, + }; + let _: () = p + .call("SetPendingFlag", &("alice", flag.clone())) + .await + .unwrap(); + let s: PendingStatus = p.call("GetPendingStatus", &("alice",)).await.unwrap(); + assert!(s.present); + assert_eq!(s.flag, flag); + } + #[tokio::test] async fn generate_recovery_code_returns_8_digits() { let (_srv, client, _state, _tmp) = p2p_pair().await; diff --git a/daemon/src/state.rs b/daemon/src/state.rs index ca317a8..3cb2e4c 100644 --- a/daemon/src/state.rs +++ b/daemon/src/state.rs @@ -259,7 +259,6 @@ impl AppState { Ok(self.pending.get(user)?.is_some()) } - #[allow(dead_code)] // wired through D-Bus in Task 5. pub async fn get_pending_status(&self, user: &str) -> Result { match self.pending.get(user)? { Some(flag) => Ok(PendingStatus { present: true, flag }),