Files
local-mini-kms/src/db.rs

81 lines
2.4 KiB
Rust

use rusqlite::{Connection, params};
use rust_util::{debugging, information, opt_result, simple_error, success, XResult};
pub const DEFAULT_MASTER_KEY_VERIFICATION_KEY: &str = "__master_verification_key";
pub struct Key {
pub name: String,
pub encrypted_key: String,
pub comment: Option<String>,
}
pub fn make_db_key_name(name: &str) -> String {
format!("value:{}", name)
}
pub fn open_db(db: &str) -> XResult<Connection> {
let con = opt_result!(Connection::open(db), "Open sqlite db: {}, failed: {}", db);
debugging!("Db auto commit: {}", con.is_autocommit());
Ok(con)
}
pub fn init_db(conn: &Connection) -> XResult<bool> {
let mut stmt = conn.prepare(
"SELECT name FROM sqlite_master WHERE type='table' AND name='keys'")?;
let mut rows = stmt.query(())?;
if rows.next()?.is_some() {
information!("Table keys exists, skip init");
return Ok(false);
}
let _ = conn.execute(r##"
CREATE TABLE keys (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
value TEXT,
comment TEXT
)
"##, ())?;
success!("Table keys created");
Ok(true)
}
pub fn insert_key(conn: &Connection, key: &Key) -> XResult<()> {
let default_comment = "".to_string();
let _ = conn.execute(
"INSERT INTO keys (name, value, comment) VALUES (?1, ?2, ?3)",
(&key.name, &key.encrypted_key, key.comment.as_ref().unwrap_or(&default_comment)),
)?;
Ok(())
}
pub fn update_key(conn: &Connection, key: &Key) -> XResult<()> {
if let Some(comment) = &key.comment {
let _ = conn.execute(
"UPDATE keys SET value = ?1, comment = ?2 WHERE name = ?3",
(&key.encrypted_key, comment, &key.name),
)?;
} else {
let _ = conn.execute(
"UPDATE keys SET value = ?1 WHERE name = ?2",
(&key.encrypted_key, &key.name),
)?;
}
Ok(())
}
pub fn find_key(conn: &Connection, name: &str) -> XResult<Option<Key>> {
let mut stmt = conn.prepare("SELECT id, name, value, comment FROM keys WHERE name = ?1")?;
let mut key_iter = stmt.query_map(params![name], |row| {
Ok(Key {
name: row.get(1)?,
encrypted_key: row.get(2)?,
comment: row.get(3)?,
})
})?;
match key_iter.next() {
None => Ok(None),
Some(Ok(r)) => Ok(Some(r)),
Some(Err(e)) => simple_error!("Find key failed: {}", e),
}
}