pub mod asymmetric;
use crate::re_export::std_anyhow::*;
use serde::{Serialize, Deserialize};
use std::fmt;
pub trait HasUserIdentifier {
fn username(&self) -> String;
fn platform_id(&self) -> String;
fn secret_type(&self) -> SecretType;
fn identifier(&self) -> String {
format!("{} -> {}", self.platform_id(), self.username())
}
fn public_key_created_at(&self) -> String;
fn generate_hint(&self) -> Option<String> {
let user_identifier = match self.secret_type() {
SecretType::IdentityGroup => "Group Name",
_ => "User name",
};
let (date, time) = Self::parse_key_create_time(&self.public_key_created_at());
Some(
format!(
"You are signing this HINT for{}encryption in Onion Vault:\n\n
Platform ID: \"{}\"\n\n{}: \"{}\"\n\nCreated at\n{}\n{}",
self.secret_type().in_box(),
self.platform_id(),
user_identifier,
self.username(),
date,
time
)
)
}
fn parse_identifier(identifier: &str) -> (String, String) {
let separator_position = identifier.find(" -> ");
if let Some(pos) = separator_position {
let platform_id = &identifier[..pos];
let username = &identifier[pos + 4..];
(platform_id.to_string(), username.to_string())
} else {
("".to_string(), "".to_string())
}
}
fn parse_key_create_time(datetime_str: &str) -> (String, String) {
let separator_index = datetime_str.find('T').expect("Expected 'T' in the datetime string");
let date = &datetime_str[0..separator_index];
let time = &datetime_str[separator_index + 1..separator_index + 9];
(date.to_string(), time.to_string())
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub enum SecretType {
UniVault,
Account,
JSON,
RawBytes,
PasswordManager,
IdentityGroup,
Password,
TOTPKey,
BackupKey,
Text,
}
impl fmt::Display for SecretType {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
SecretType::UniVault =>write!(f, "UniVault"),
SecretType::Account =>write!(f, "Account"),
SecretType::JSON =>write!(f, "JSON"),
SecretType::RawBytes =>write!(f, "Raw Bytes"),
SecretType::PasswordManager =>write!(f, "Passwd Manager"),
SecretType::IdentityGroup =>write!(f, "Identity Group"),
SecretType::Password =>write!(f, "Password"),
SecretType::TOTPKey =>write!(f, "TOTP Key"),
SecretType::BackupKey =>write!(f, "Backup Key"),
SecretType::Text =>write!(f, "Text"),
}
}
}
impl SecretType {
pub fn to_string_name(&self) -> &'static str {
match self {
SecretType::UniVault => "UniVault",
SecretType::Account => "Account",
SecretType::JSON => "JSON",
SecretType::RawBytes => "Raw Bytes",
SecretType::PasswordManager => "Passwd Manager",
SecretType::IdentityGroup => "Identity Group",
SecretType::Password => "Password",
SecretType::TOTPKey => "TOTP Key",
SecretType::BackupKey => "Backup Key",
SecretType::Text => "Text",
}
}
pub fn in_box(&self) -> String {
let string_name = self.to_string_name();
let width = string_name.chars().count() + 2;
let horizontal_line = format!("+{}+", "-".repeat(width));
format!("\n{}\n| {} |\n{}\n", horizontal_line, string_name, horizontal_line)
}
}
pub trait Encryptor {
fn encrypt(&mut self, secret: &[u8]) -> anyhow::Result<Vec<u8>>;
fn decrypt(&self, encrypted_bytes: &[u8]) -> anyhow::Result<Vec<u8>>;
fn name(&self) -> String;
}