use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use uuid::Uuid;
use crate::hardware::HardwareAccelerator;
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
pub enum SecurityLevel {
Standard, #[default]
High, Quantum, }
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub enum ItemType {
Credential,
Folder,
Key,
Url,
Note,
SecureNote,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AttachmentMetadata {
pub id: Uuid,
pub file_name: String,
pub mime_type: Option<String>,
pub size: u64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BaseItem {
pub id: Uuid,
pub name: String,
pub item_type: ItemType,
pub folder_id: Option<Uuid>,
pub tags: Vec<String>,
pub attachments: Vec<AttachmentMetadata>,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
pub hmac: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Credential {
pub base: BaseItem,
pub username: String,
pub password: String,
pub url: Option<String>,
pub notes: Option<String>,
pub totp_secret: Option<String>,
pub last_used: Option<DateTime<Utc>>,
pub password_history: Vec<PasswordHistory>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PasswordHistory {
pub password: String,
pub changed_at: DateTime<Utc>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Folder {
pub base: BaseItem,
pub description: Option<String>,
pub color: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Key {
pub base: BaseItem,
pub key_type: KeyType,
pub key_data: String, pub algorithm: String,
pub key_size: u32,
pub usage: Vec<KeyUsage>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum KeyType {
Symmetric,
Asymmetric,
Hmac,
Derivation,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum KeyUsage {
Encryption,
Decryption,
Signing,
Verification,
KeyExchange,
KeyDerivation,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Url {
pub base: BaseItem,
pub url: String,
pub title: Option<String>,
pub favicon: Option<String>,
pub notes: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Note {
pub base: BaseItem,
pub content: String,
pub is_encrypted: bool,
pub format: NoteFormat,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum NoteFormat {
PlainText,
Markdown,
Json,
Xml,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SecureNote {
pub base: BaseItem,
pub encrypted_content: String,
pub content_type: String,
pub additional_metadata: HashMap<String, String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum Item {
Credential(Credential),
Folder(Folder),
Key(Key),
Url(Url),
Note(Note),
SecureNote(SecureNote),
}
impl Item {
pub fn get_base(&self) -> &BaseItem {
match self {
Item::Credential(c) => &c.base,
Item::Folder(f) => &f.base,
Item::Key(k) => &k.base,
Item::Url(u) => &u.base,
Item::Note(n) => &n.base,
Item::SecureNote(s) => &s.base,
}
}
pub fn get_base_mut(&mut self) -> &mut BaseItem {
match self {
Item::Credential(c) => &mut c.base,
Item::Folder(f) => &mut f.base,
Item::Key(k) => &mut k.base,
Item::Url(u) => &mut u.base,
Item::Note(n) => &mut n.base,
Item::SecureNote(s) => &mut s.base,
}
}
pub fn get_id(&self) -> Uuid {
self.get_base().id
}
pub fn get_name(&self) -> &str {
&self.get_base().name
}
pub fn get_type(&self) -> &ItemType {
&self.get_base().item_type
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PasswordDatabase {
pub version: String,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
pub security_level: SecurityLevel,
pub items: Vec<Item>,
pub metadata: DatabaseMetadata,
pub integrity_hash: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DatabaseMetadata {
pub name: String,
pub description: Option<String>,
pub settings: DatabaseSettings,
pub custom_fields: HashMap<String, String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DatabaseSettings {
pub auto_lock_timeout: u64,
pub password_generator_settings: PasswordGeneratorSettings,
pub security_settings: SecuritySettings,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PasswordGeneratorSettings {
pub length: u32,
pub use_uppercase: bool,
pub use_lowercase: bool,
pub use_numbers: bool,
pub use_symbols: bool,
pub exclude_similar: bool,
pub exclude_ambiguous: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SecuritySettings {
pub key_derivation_iterations: u32,
pub memory_cost: u32,
pub parallelism: u32,
pub salt_length: usize,
pub iv_length: usize,
pub tag_length: usize,
pub testing_mode: bool,
}
impl SecuritySettings {
pub fn recommended(level: SecurityLevel) -> Self {
let parallelism = HardwareAccelerator::optimal_thread_count() as u32;
match level {
SecurityLevel::Standard => Self {
key_derivation_iterations: 3,
memory_cost: 65_536, parallelism,
salt_length: 32,
iv_length: 12,
tag_length: 16,
testing_mode: false,
},
SecurityLevel::High => Self {
key_derivation_iterations: 4,
memory_cost: 131_072, parallelism,
salt_length: 32,
iv_length: 12,
tag_length: 16,
testing_mode: false,
},
SecurityLevel::Quantum => Self {
key_derivation_iterations: 5,
memory_cost: 262_144, parallelism,
salt_length: 32,
iv_length: 12,
tag_length: 16,
testing_mode: false,
},
}
}
}
impl Default for SecuritySettings {
fn default() -> Self {
Self::recommended(SecurityLevel::default())
}
}
impl Default for PasswordGeneratorSettings {
fn default() -> Self {
Self {
length: 20,
use_uppercase: true,
use_lowercase: true,
use_numbers: true,
use_symbols: true,
exclude_similar: true,
exclude_ambiguous: false,
}
}
}
impl Default for DatabaseSettings {
fn default() -> Self {
Self {
auto_lock_timeout: 300, password_generator_settings: PasswordGeneratorSettings::default(),
security_settings: SecuritySettings::default(),
}
}
}