use std::{env, path::Path};
#[allow(deprecated)]
use std::{env::home_dir, path::PathBuf};
use serde_derive::{Deserialize, Serialize};
use crate::presence_verification::PresenceVerificationMethod;
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct Config {
pub tpm: String,
pub system_data_path: PathBuf,
pub user_data_path: PathBuf,
pub pv_timeout: u8,
pub pv_method: PresenceVerificationMethod,
}
impl Config {
pub fn default(
local: bool,
tpm: String,
system_data_path: Option<PathBuf>,
user_data_path: Option<PathBuf>,
presence_verification: Option<PresenceVerificationMethod>,
) -> Self {
Config {
tpm,
system_data_path: system_data_path.as_deref().map(absolute_path).unwrap_or(
if local {
local_path(&PathBuf::from(".local/state/totpm/system"))
} else {
PathBuf::from("/var/lib/totpm")
}
),
user_data_path: user_data_path.unwrap_or(PathBuf::from(".local/state/totpm")),
pv_timeout: 10,
pv_method: presence_verification.unwrap_or(
if local {
PresenceVerificationMethod::None
} else {
PresenceVerificationMethod::Fprintd
}
)
}
}
pub fn auth_value_path(&self) -> PathBuf {
self.system_data_path.join("auth_value")
}
pub fn primary_key_handle_path(&self) -> PathBuf {
self.system_data_path.join("primary_key_handle")
}
pub fn secrets_db_path(&self) -> PathBuf {
let secrets_db_file = "secrets.sqlite";
if self.user_data_path.is_absolute() {
self.user_data_path.join(secrets_db_file)
} else {
#[allow(deprecated)]
home_dir().unwrap().join(&self.user_data_path).join(secrets_db_file)
}
}
}
pub fn local_path(file: &Path) -> PathBuf {
assert!(file.is_relative());
#[allow(deprecated)]
env::home_dir().unwrap().join(file)
}
pub fn absolute_path(path: &Path) -> PathBuf {
if path.is_absolute() {
path.to_owned()
} else {
std::env::current_dir().unwrap().join(path)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn local_default_config_uses_local_defaults() {
#[allow(deprecated)]
let home_dir = env::home_dir().unwrap();
let cfg = Config::default(true, "device".to_string(), None, None, None);
assert!(cfg.system_data_path.starts_with(&home_dir));
assert!(cfg.user_data_path.is_relative());
assert!(cfg.auth_value_path().starts_with(&home_dir));
assert!(cfg.primary_key_handle_path().starts_with(&home_dir));
assert!(cfg.secrets_db_path().starts_with(&home_dir));
assert_eq!(cfg.pv_method, PresenceVerificationMethod::None);
}
#[test]
fn global_default_config_uses_global_defaults() {
#[allow(deprecated)]
let home_dir = env::home_dir().unwrap();
let cfg = Config::default(false, "device".to_string(), None, None, None);
assert!(cfg.system_data_path.starts_with("/var/lib"));
assert!(cfg.user_data_path.is_relative());
assert!(cfg.auth_value_path().starts_with("/var/lib"));
assert!(cfg.primary_key_handle_path().starts_with("/var/lib"));
assert!(cfg.secrets_db_path().starts_with(&home_dir));
assert_eq!(cfg.pv_method, PresenceVerificationMethod::Fprintd);
}
}