refactor(daemon): AppState delegates to storage modules; dbus tests use tempdir

Lands plan tasks 2.15 (AppState refactor with StorageConfig + open()) and 2.16
(dbus.rs tests switched to tempdir-backed AppState; storage errors threaded
through D-Bus methods as Failed). Bundled because the AppState surface change
forces dbus.rs adjustments in the same commit.

- daemon/src/state.rs: AppState::open(StorageConfig) replaces with_fixtures().
  StorageConfig.from_env_or_defaults() reads AUTHFORGE_POLICY_DIR /
  _PENDING_DIR / _USERDB env vars (defaults: /etc/authforge/policy.d,
  /var/lib/authforge/pending, /var/lib/authforge/users.db). State delegates
  list/add/remove credentials to CredsPathResolver + CredentialsStore picked
  per-call from current Policy; pending and userdb operate independently.
- daemon/src/main.rs: opens state via env-driven config; reuses cfg.policy_dir
  for the watcher to keep one source of truth.
- daemon/src/dbus.rs: every write method maps StateError to fdo::Error::Failed.
  p2p_pair seeds 00-test.conf with [storage] backend = central pointing into
  the tempdir so credential writes don't try to touch /home/<user>/...
  (alice/bob/carol aren't real accounts in tests).
- Renamed: list_credentials_returns_fixture_for_alice ->
  list_credentials_after_enroll. Removed: with_fixtures().
- .gitignore: add .claude/ so leftover Phase 1 worktree state isn't committed.

Test count: 26/26 daemon tests green (was 17). Common: 13/13. Clippy + fmt clean.
This commit is contained in:
michael
2026-04-27 06:44:07 -07:00
parent 90f7a0f4fc
commit 24237cbf8b
5 changed files with 244 additions and 145 deletions

View File

@@ -1,5 +1,4 @@
use anyhow::{Context, Result};
use std::path::PathBuf;
use std::sync::Arc;
use tracing::{info, warn};
@@ -31,7 +30,9 @@ async fn main() -> Result<()> {
polkit::Polkit::system(conn.clone()).await
};
let state = Arc::new(state::AppState::with_fixtures());
let cfg = state::StorageConfig::from_env_or_defaults();
let policy_dir = cfg.policy_dir.clone();
let state = Arc::new(state::AppState::open(cfg)?);
let auth = dbus::AuthForge {
state: state.clone(),
polkit: Arc::new(polkit),
@@ -45,9 +46,6 @@ async fn main() -> Result<()> {
info!("listening on D-Bus as {BUS_NAME} at {OBJECT_PATH}");
// Inotify watcher → PolicyChanged signal.
let policy_dir = std::env::var_os("AUTHFORGE_POLICY_DIR")
.map(PathBuf::from)
.unwrap_or_else(|| PathBuf::from("/etc/authforge/policy.d"));
let policy_store = storage::policy::PolicyStore::new(policy_dir.clone());
match policy_store.watch() {
Ok((watcher, mut rx)) => {