use serde::{Deserialize, Serialize};
use std::fmt;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub enum ItemCategory {
Login,
SecureNote,
CreditCard,
Identity,
Password,
Document,
BankAccount,
Database,
DriverLicense,
EmailAccount,
Membership,
OutdoorLicense,
Passport,
RewardProgram,
Server,
SocialSecurityNumber,
SoftwareLicense,
SshKey,
WirelessRouter,
ApiCredential,
MedicalRecord,
#[serde(untagged)]
Other(String),
}
impl ItemCategory {
pub fn json_schema() -> serde_json::Map<String, serde_json::Value> {
let mut schema = serde_json::Map::new();
schema.insert(
"type".to_string(),
serde_json::Value::String("string".to_string()),
);
schema.insert(
"description".to_string(),
serde_json::Value::String(
"Item category. Use one of the known values, or any string for forward compatibility.".to_string(),
),
);
schema.insert(
"enum".to_string(),
serde_json::Value::Array(vec![
serde_json::Value::String("LOGIN".to_string()),
serde_json::Value::String("SECURE_NOTE".to_string()),
serde_json::Value::String("CREDIT_CARD".to_string()),
serde_json::Value::String("IDENTITY".to_string()),
serde_json::Value::String("PASSWORD".to_string()),
serde_json::Value::String("DOCUMENT".to_string()),
serde_json::Value::String("BANK_ACCOUNT".to_string()),
serde_json::Value::String("DATABASE".to_string()),
serde_json::Value::String("DRIVER_LICENSE".to_string()),
serde_json::Value::String("EMAIL_ACCOUNT".to_string()),
serde_json::Value::String("MEMBERSHIP".to_string()),
serde_json::Value::String("OUTDOOR_LICENSE".to_string()),
serde_json::Value::String("PASSPORT".to_string()),
serde_json::Value::String("REWARD_PROGRAM".to_string()),
serde_json::Value::String("SERVER".to_string()),
serde_json::Value::String("SOCIAL_SECURITY_NUMBER".to_string()),
serde_json::Value::String("SOFTWARE_LICENSE".to_string()),
serde_json::Value::String("SSH_KEY".to_string()),
serde_json::Value::String("WIRELESS_ROUTER".to_string()),
serde_json::Value::String("API_CREDENTIAL".to_string()),
serde_json::Value::String("MEDICAL_RECORD".to_string()),
]),
);
schema
}
}
impl fmt::Display for ItemCategory {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
ItemCategory::Login => write!(f, "LOGIN"),
ItemCategory::SecureNote => write!(f, "SECURE_NOTE"),
ItemCategory::CreditCard => write!(f, "CREDIT_CARD"),
ItemCategory::Identity => write!(f, "IDENTITY"),
ItemCategory::Password => write!(f, "PASSWORD"),
ItemCategory::Document => write!(f, "DOCUMENT"),
ItemCategory::BankAccount => write!(f, "BANK_ACCOUNT"),
ItemCategory::Database => write!(f, "DATABASE"),
ItemCategory::DriverLicense => write!(f, "DRIVER_LICENSE"),
ItemCategory::EmailAccount => write!(f, "EMAIL_ACCOUNT"),
ItemCategory::Membership => write!(f, "MEMBERSHIP"),
ItemCategory::OutdoorLicense => write!(f, "OUTDOOR_LICENSE"),
ItemCategory::Passport => write!(f, "PASSPORT"),
ItemCategory::RewardProgram => write!(f, "REWARD_PROGRAM"),
ItemCategory::Server => write!(f, "SERVER"),
ItemCategory::SocialSecurityNumber => write!(f, "SOCIAL_SECURITY_NUMBER"),
ItemCategory::SoftwareLicense => write!(f, "SOFTWARE_LICENSE"),
ItemCategory::SshKey => write!(f, "SSH_KEY"),
ItemCategory::WirelessRouter => write!(f, "WIRELESS_ROUTER"),
ItemCategory::ApiCredential => write!(f, "API_CREDENTIAL"),
ItemCategory::MedicalRecord => write!(f, "MEDICAL_RECORD"),
ItemCategory::Other(s) => write!(f, "{}", s),
}
}
}
impl AsRef<str> for ItemCategory {
fn as_ref(&self) -> &str {
match self {
ItemCategory::Login => "LOGIN",
ItemCategory::SecureNote => "SECURE_NOTE",
ItemCategory::CreditCard => "CREDIT_CARD",
ItemCategory::Identity => "IDENTITY",
ItemCategory::Password => "PASSWORD",
ItemCategory::Document => "DOCUMENT",
ItemCategory::BankAccount => "BANK_ACCOUNT",
ItemCategory::Database => "DATABASE",
ItemCategory::DriverLicense => "DRIVER_LICENSE",
ItemCategory::EmailAccount => "EMAIL_ACCOUNT",
ItemCategory::Membership => "MEMBERSHIP",
ItemCategory::OutdoorLicense => "OUTDOOR_LICENSE",
ItemCategory::Passport => "PASSPORT",
ItemCategory::RewardProgram => "REWARD_PROGRAM",
ItemCategory::Server => "SERVER",
ItemCategory::SocialSecurityNumber => "SOCIAL_SECURITY_NUMBER",
ItemCategory::SoftwareLicense => "SOFTWARE_LICENSE",
ItemCategory::SshKey => "SSH_KEY",
ItemCategory::WirelessRouter => "WIRELESS_ROUTER",
ItemCategory::ApiCredential => "API_CREDENTIAL",
ItemCategory::MedicalRecord => "MEDICAL_RECORD",
ItemCategory::Other(s) => s.as_str(),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum VaultPermission {
AllowViewing,
AllowEditing,
AllowManaging,
}
impl VaultPermission {
pub fn json_schema() -> serde_json::Map<String, serde_json::Value> {
let mut schema = serde_json::Map::new();
schema.insert(
"type".to_string(),
serde_json::Value::String("string".to_string()),
);
schema.insert(
"description".to_string(),
serde_json::Value::String("Vault access permission level.".to_string()),
);
schema.insert(
"enum".to_string(),
serde_json::Value::Array(vec![
serde_json::Value::String("allow_viewing".to_string()),
serde_json::Value::String("allow_editing".to_string()),
serde_json::Value::String("allow_managing".to_string()),
]),
);
schema
}
}
impl fmt::Display for VaultPermission {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
VaultPermission::AllowViewing => write!(f, "allow_viewing"),
VaultPermission::AllowEditing => write!(f, "allow_editing"),
VaultPermission::AllowManaging => write!(f, "allow_managing"),
}
}
}
impl AsRef<str> for VaultPermission {
fn as_ref(&self) -> &str {
match self {
VaultPermission::AllowViewing => "allow_viewing",
VaultPermission::AllowEditing => "allow_editing",
VaultPermission::AllowManaging => "allow_managing",
}
}
}
pub fn permissions_to_string(permissions: &[VaultPermission]) -> String {
permissions
.iter()
.map(|p| p.as_ref())
.collect::<Vec<_>>()
.join(",")
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum ShareExpiry {
#[serde(rename = "1h")]
OneHour,
#[serde(rename = "1d")]
OneDay,
#[serde(rename = "7d")]
SevenDays,
#[serde(rename = "14d")]
FourteenDays,
#[serde(rename = "30d")]
ThirtyDays,
}
impl ShareExpiry {
pub fn json_schema() -> serde_json::Map<String, serde_json::Value> {
let mut schema = serde_json::Map::new();
schema.insert(
"type".to_string(),
serde_json::Value::String("string".to_string()),
);
schema.insert(
"description".to_string(),
serde_json::Value::String(
"Share link expiration duration. Default is 7 days.".to_string(),
),
);
schema.insert(
"enum".to_string(),
serde_json::Value::Array(vec![
serde_json::Value::String("1h".to_string()),
serde_json::Value::String("1d".to_string()),
serde_json::Value::String("7d".to_string()),
serde_json::Value::String("14d".to_string()),
serde_json::Value::String("30d".to_string()),
]),
);
schema
}
}
impl fmt::Display for ShareExpiry {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
ShareExpiry::OneHour => write!(f, "1h"),
ShareExpiry::OneDay => write!(f, "1d"),
ShareExpiry::SevenDays => write!(f, "7d"),
ShareExpiry::FourteenDays => write!(f, "14d"),
ShareExpiry::ThirtyDays => write!(f, "30d"),
}
}
}
impl AsRef<str> for ShareExpiry {
fn as_ref(&self) -> &str {
match self {
ShareExpiry::OneHour => "1h",
ShareExpiry::OneDay => "1d",
ShareExpiry::SevenDays => "7d",
ShareExpiry::FourteenDays => "14d",
ShareExpiry::ThirtyDays => "30d",
}
}
}
impl Default for ShareExpiry {
fn default() -> Self {
ShareExpiry::SevenDays
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum TokenExpiry {
#[serde(rename = "30d")]
ThirtyDays,
#[serde(rename = "1y")]
OneYear,
#[serde(rename = "never")]
Never,
}
impl TokenExpiry {
pub fn json_schema() -> serde_json::Map<String, serde_json::Value> {
let mut schema = serde_json::Map::new();
schema.insert(
"type".to_string(),
serde_json::Value::String("string".to_string()),
);
schema.insert(
"description".to_string(),
serde_json::Value::String("Token expiration duration.".to_string()),
);
schema.insert(
"enum".to_string(),
serde_json::Value::Array(vec![
serde_json::Value::String("30d".to_string()),
serde_json::Value::String("1y".to_string()),
serde_json::Value::String("never".to_string()),
]),
);
schema
}
}
impl fmt::Display for TokenExpiry {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
TokenExpiry::ThirtyDays => write!(f, "30d"),
TokenExpiry::OneYear => write!(f, "1y"),
TokenExpiry::Never => write!(f, "never"),
}
}
}
impl AsRef<str> for TokenExpiry {
fn as_ref(&self) -> &str {
match self {
TokenExpiry::ThirtyDays => "30d",
TokenExpiry::OneYear => "1y",
TokenExpiry::Never => "never",
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum EventFeature {
Signinattempts,
Itemusages,
Auditevents,
}
impl EventFeature {
pub fn json_schema() -> serde_json::Map<String, serde_json::Value> {
let mut schema = serde_json::Map::new();
schema.insert(
"type".to_string(),
serde_json::Value::String("string".to_string()),
);
schema.insert(
"description".to_string(),
serde_json::Value::String("Event type for Events API subscription.".to_string()),
);
schema.insert(
"enum".to_string(),
serde_json::Value::Array(vec![
serde_json::Value::String("signinattempts".to_string()),
serde_json::Value::String("itemusages".to_string()),
serde_json::Value::String("auditevents".to_string()),
]),
);
schema
}
}
impl fmt::Display for EventFeature {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
EventFeature::Signinattempts => write!(f, "signinattempts"),
EventFeature::Itemusages => write!(f, "itemusages"),
EventFeature::Auditevents => write!(f, "auditevents"),
}
}
}
impl AsRef<str> for EventFeature {
fn as_ref(&self) -> &str {
match self {
EventFeature::Signinattempts => "signinattempts",
EventFeature::Itemusages => "itemusages",
EventFeature::Auditevents => "auditevents",
}
}
}
pub fn features_to_vec(features: &[EventFeature]) -> Vec<&str> {
features.iter().map(|f| f.as_ref()).collect()
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum GroupUserRole {
Member,
Manager,
}
impl GroupUserRole {
pub fn json_schema() -> serde_json::Map<String, serde_json::Value> {
let mut schema = serde_json::Map::new();
schema.insert(
"type".to_string(),
serde_json::Value::String("string".to_string()),
);
schema.insert(
"description".to_string(),
serde_json::Value::String("Role for a user within a group.".to_string()),
);
schema.insert(
"enum".to_string(),
serde_json::Value::Array(vec![
serde_json::Value::String("member".to_string()),
serde_json::Value::String("manager".to_string()),
]),
);
schema
}
}
impl fmt::Display for GroupUserRole {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
GroupUserRole::Member => write!(f, "member"),
GroupUserRole::Manager => write!(f, "manager"),
}
}
}
impl AsRef<str> for GroupUserRole {
fn as_ref(&self) -> &str {
match self {
GroupUserRole::Member => "member",
GroupUserRole::Manager => "manager",
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_item_category_serialization() {
assert_eq!(
serde_json::to_string(&ItemCategory::Login).unwrap(),
"\"LOGIN\""
);
assert_eq!(
serde_json::to_string(&ItemCategory::SecureNote).unwrap(),
"\"SECURE_NOTE\""
);
assert_eq!(
serde_json::to_string(&ItemCategory::SshKey).unwrap(),
"\"SSH_KEY\""
);
}
#[test]
fn test_item_category_deserialization() {
assert_eq!(
serde_json::from_str::<ItemCategory>("\"LOGIN\"").unwrap(),
ItemCategory::Login
);
assert_eq!(
serde_json::from_str::<ItemCategory>("\"SECURE_NOTE\"").unwrap(),
ItemCategory::SecureNote
);
assert_eq!(
serde_json::from_str::<ItemCategory>("\"UNKNOWN_FUTURE_TYPE\"").unwrap(),
ItemCategory::Other("UNKNOWN_FUTURE_TYPE".to_string())
);
}
#[test]
fn test_share_expiry_serialization() {
assert_eq!(
serde_json::to_string(&ShareExpiry::OneHour).unwrap(),
"\"1h\""
);
assert_eq!(
serde_json::to_string(&ShareExpiry::SevenDays).unwrap(),
"\"7d\""
);
}
#[test]
fn test_token_expiry_serialization() {
assert_eq!(
serde_json::to_string(&TokenExpiry::ThirtyDays).unwrap(),
"\"30d\""
);
assert_eq!(
serde_json::to_string(&TokenExpiry::Never).unwrap(),
"\"never\""
);
}
#[test]
fn test_vault_permission_serialization() {
assert_eq!(
serde_json::to_string(&VaultPermission::AllowViewing).unwrap(),
"\"allow_viewing\""
);
}
#[test]
fn test_permissions_to_string() {
let perms = vec![VaultPermission::AllowViewing, VaultPermission::AllowEditing];
assert_eq!(permissions_to_string(&perms), "allow_viewing,allow_editing");
}
#[test]
fn test_event_feature_serialization() {
assert_eq!(
serde_json::to_string(&EventFeature::Signinattempts).unwrap(),
"\"signinattempts\""
);
}
#[test]
fn test_group_user_role_serialization() {
assert_eq!(
serde_json::to_string(&GroupUserRole::Member).unwrap(),
"\"member\""
);
assert_eq!(
serde_json::to_string(&GroupUserRole::Manager).unwrap(),
"\"manager\""
);
}
#[test]
fn test_item_category_json_schema() {
let schema = ItemCategory::json_schema();
assert_eq!(
schema.get("type").unwrap(),
&serde_json::Value::String("string".to_string())
);
let enum_values = schema.get("enum").unwrap().as_array().unwrap();
assert!(enum_values.contains(&serde_json::Value::String("LOGIN".to_string())));
assert!(enum_values.contains(&serde_json::Value::String("SECURE_NOTE".to_string())));
}
#[test]
fn test_share_expiry_json_schema() {
let schema = ShareExpiry::json_schema();
let enum_values = schema.get("enum").unwrap().as_array().unwrap();
assert!(enum_values.contains(&serde_json::Value::String("1h".to_string())));
assert!(enum_values.contains(&serde_json::Value::String("7d".to_string())));
}
}