1use chrono::{DateTime, Utc};
2use serde::{Deserialize, Serialize};
3use uuid::Uuid;
4
5#[derive(Debug, Clone, Serialize, Deserialize)]
6pub struct Server {
7 pub id: Uuid,
8 pub name: String,
9 pub host: String,
10 pub port: u16,
11 pub username: String,
12 pub password: String,
13 pub description: Option<String>,
14 #[serde(default)]
15 pub identity_file: Option<String>,
16 #[serde(default)]
17 pub forward_agent: bool,
18 pub created_at: DateTime<Utc>,
19 pub updated_at: DateTime<Utc>,
20 #[serde(default)]
21 pub tags: Vec<String>,
22}
23
24impl Server {
25 pub fn new(
26 name: String,
27 host: String,
28 port: u16,
29 username: String,
30 password: String,
31 description: Option<String>,
32 ) -> Self {
33 let now = Utc::now();
34 Self {
35 id: Uuid::new_v4(),
36 name,
37 host,
38 port,
39 username,
40 password,
41 description,
42 identity_file: None,
43 forward_agent: false,
44 created_at: now,
45 updated_at: now,
46 tags: Vec::new(),
47 }
48 }
49
50 pub fn ssh_command(&self) -> String {
51 format!("ssh {}@{} -p {}", self.username, self.host, self.port)
52 }
53
54 pub fn update_fields(
55 &mut self,
56 name: String,
57 host: String,
58 port: u16,
59 username: String,
60 password: String,
61 description: Option<String>,
62 ) {
63 self.name = name;
64 self.host = host;
65 self.port = port;
66 self.username = username;
67 self.password = password;
68 self.description = description;
69 self.updated_at = Utc::now();
70 }
71}
72
73#[derive(Debug, Clone, Serialize, Deserialize)]
74pub struct VaultData {
75 pub servers: Vec<Server>,
76 pub version: String,
77}
78
79impl Default for VaultData {
80 fn default() -> Self {
81 Self::new()
82 }
83}
84
85impl VaultData {
86 pub fn new() -> Self {
87 Self {
88 servers: Vec::new(),
89 version: "1.0.0".to_string(),
90 }
91 }
92
93 pub fn add_server(&mut self, server: Server) {
94 self.servers.push(server);
95 }
96
97 pub fn remove_server(&mut self, id: &Uuid) -> bool {
98 let len = self.servers.len();
99 self.servers.retain(|s| &s.id != id);
100 self.servers.len() != len
101 }
102
103 pub fn find_server(&self, id: &Uuid) -> Option<&Server> {
104 self.servers.iter().find(|s| &s.id == id)
105 }
106
107 pub fn replace_server(&mut self, server: Server) -> bool {
108 if let Some(pos) = self.servers.iter().position(|s| s.id == server.id) {
109 self.servers[pos] = server;
110 true
111 } else {
112 false
113 }
114 }
115}