#![allow(dead_code, unused_imports, unused_qualifications, unreachable_patterns)]
use crate::internal::core::{Error, Result};
#[cfg(all(feature = "keyring-storage", target_env = "gnu"))]
const MARKER_ACCOUNT: &str = "__meta_migration_marker__";
#[cfg(all(feature = "keyring-storage", target_env = "gnu"))]
const MARKER_PAYLOAD: &[u8] = b"v1";
#[cfg(all(feature = "keyring-storage", target_env = "gnu"))]
pub fn is_set(app_name: &str) -> Result<bool> {
let entry = keyring::Entry::new(app_name, MARKER_ACCOUNT).map_err(|e| Error::KeyOperation {
operation: "migrate_marker_load".into(),
detail: format!("keyring::Entry::new: {e}"),
})?;
match entry.get_secret() {
Ok(_) => Ok(true),
Err(keyring::Error::NoEntry) => Ok(false),
Err(e) => Err(Error::KeyOperation {
operation: "migrate_marker_load".into(),
detail: format!("get_secret: {e}"),
}),
}
}
#[cfg(not(all(feature = "keyring-storage", target_env = "gnu")))]
pub fn is_set(_app_name: &str) -> Result<bool> {
Ok(false)
}
#[cfg(all(feature = "keyring-storage", target_env = "gnu"))]
pub fn set(app_name: &str) -> Result<()> {
let entry = keyring::Entry::new(app_name, MARKER_ACCOUNT).map_err(|e| Error::KeyOperation {
operation: "migrate_marker_set".into(),
detail: format!("keyring::Entry::new: {e}"),
})?;
entry
.set_secret(MARKER_PAYLOAD)
.map_err(|e| Error::KeyOperation {
operation: "migrate_marker_set".into(),
detail: format!("set_secret: {e}"),
})
}
#[cfg(not(all(feature = "keyring-storage", target_env = "gnu")))]
pub fn set(_app_name: &str) -> Result<()> {
Err(Error::KeyOperation {
operation: "migrate_marker_set".into(),
detail: "keyring-storage feature not compiled in for this target".into(),
})
}
#[cfg(all(feature = "keyring-storage", target_env = "gnu"))]
pub fn clear(app_name: &str) -> Result<()> {
let entry = keyring::Entry::new(app_name, MARKER_ACCOUNT).map_err(|e| Error::KeyOperation {
operation: "migrate_marker_clear".into(),
detail: format!("keyring::Entry::new: {e}"),
})?;
match entry.delete_credential() {
Ok(()) | Err(keyring::Error::NoEntry) => Ok(()),
Err(e) => Err(Error::KeyOperation {
operation: "migrate_marker_clear".into(),
detail: format!("delete_credential: {e}"),
}),
}
}
#[cfg(not(all(feature = "keyring-storage", target_env = "gnu")))]
pub fn clear(_app_name: &str) -> Result<()> {
Ok(())
}
#[cfg(test)]
#[allow(clippy::unwrap_used, clippy::panic, let_underscore_drop)]
mod tests {
use super::*;
#[cfg(all(feature = "keyring-storage", target_env = "gnu"))]
use std::sync::atomic::{AtomicU64, Ordering};
#[cfg(all(feature = "keyring-storage", target_env = "gnu"))]
static COUNTER: AtomicU64 = AtomicU64::new(0);
#[cfg(all(feature = "keyring-storage", target_env = "gnu"))]
fn unique_app() -> String {
format!(
"enclaveapp-keyring-migrate-marker-test-{}-{}",
std::process::id(),
COUNTER.fetch_add(1, Ordering::SeqCst),
)
}
#[cfg(all(feature = "keyring-storage", target_env = "gnu"))]
#[test]
fn account_constant_format() {
assert_eq!(MARKER_ACCOUNT, "__meta_migration_marker__");
}
#[cfg(not(all(feature = "keyring-storage", target_env = "gnu")))]
#[test]
fn is_set_returns_false_when_keyring_not_compiled_in() {
let result = is_set("test-app");
assert!(matches!(result, Ok(false)));
}
#[cfg(not(all(feature = "keyring-storage", target_env = "gnu")))]
#[test]
fn clear_returns_ok_when_keyring_not_compiled_in() {
let result = clear("test-app");
assert!(result.is_ok());
}
#[cfg(not(all(feature = "keyring-storage", target_env = "gnu")))]
#[test]
fn set_returns_err_when_keyring_not_compiled_in() {
let result = set("test-app");
assert!(result.is_err());
}
#[cfg(all(feature = "keyring-storage", target_env = "gnu"))]
#[test]
#[ignore = "hits real Secret Service; run on a desktop Linux session"]
fn set_clear_roundtrip() {
let app = unique_app();
clear(&app).expect("clear is idempotent");
assert!(matches!(is_set(&app), Ok(false)));
set(&app).expect("set succeeds");
assert!(matches!(is_set(&app), Ok(true)));
set(&app).expect("repeat set");
assert!(matches!(is_set(&app), Ok(true)));
clear(&app).expect("clear succeeds");
assert!(matches!(is_set(&app), Ok(false)));
}
}