use libsecret::{prelude::*, SchemaAttributeType, SchemaFlags, SearchFlags}; use std::collections::HashMap; const SCHEMA_NAME: &str = "net.jeena.FeedTheMonkey"; const ATTR_SERVER: &str = "server-url"; const ATTR_USERNAME: &str = "username"; const LABEL: &str = "FeedTheMonkey credentials"; fn schema() -> libsecret::Schema { libsecret::Schema::new( SCHEMA_NAME, SchemaFlags::NONE, HashMap::from([ (ATTR_SERVER, SchemaAttributeType::String), (ATTR_USERNAME, SchemaAttributeType::String), ]), ) } pub fn store_credentials(server_url: &str, username: &str, password: &str) { let schema = schema(); let attrs = HashMap::from([ (ATTR_SERVER, server_url), (ATTR_USERNAME, username), ]); if let Err(e) = libsecret::password_store_sync( Some(&schema), attrs, Some(libsecret::COLLECTION_DEFAULT.as_str()), LABEL, password, gio::Cancellable::NONE, ) { eprintln!("Failed to store credentials: {e}"); } } pub fn load_credentials() -> Option<(String, String, String)> { let schema = schema(); let items = libsecret::password_search_sync( Some(&schema), HashMap::new(), SearchFlags::LOAD_SECRETS | SearchFlags::UNLOCK, gio::Cancellable::NONE, ).ok()?; let item = items.into_iter().next()?; let attrs = item.attributes(); let server_url = attrs.get(ATTR_SERVER)?.to_string(); let username = attrs.get(ATTR_USERNAME)?.to_string(); let secret = item.retrieve_secret_sync(gio::Cancellable::NONE).ok()??; let password = secret.text()?.to_string(); Some((server_url, username, password)) } pub fn clear_credentials() { let schema = schema(); if let Err(e) = libsecret::password_clear_sync( Some(&schema), HashMap::new(), gio::Cancellable::NONE, ) { eprintln!("Failed to clear credentials: {e}"); } }