1use std::fmt::{Display, Formatter};
2use std::path::{Path, PathBuf};
3use std::time::Duration;
4
5use kellnr_settings::Settings;
6
7use crate::password::generate_salt;
8
9#[derive(Debug, Clone, PartialEq, Eq, Hash)]
10pub enum ConString {
11 Postgres(PgConString),
12 Sqlite(SqliteConString),
13}
14
15impl Display for ConString {
16 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
17 let con_string = match self {
18 ConString::Postgres(p) => p.to_string(),
19 ConString::Sqlite(s) => s.to_string(),
20 };
21 write!(f, "{con_string}")
22 }
23}
24
25impl ConString {
26 pub fn admin_pwd(&self) -> String {
27 match self {
28 ConString::Postgres(p) => p.admin.pwd.clone(),
29 ConString::Sqlite(s) => s.admin_pwd.clone(),
30 }
31 }
32
33 pub fn salt(&self) -> String {
34 match self {
35 ConString::Postgres(p) => p.admin.salt.clone(),
36 ConString::Sqlite(s) => s.salt.clone(),
37 }
38 }
39
40 pub fn admin_token(&self) -> Option<String> {
41 match self {
42 ConString::Postgres(p) => p.admin.token.clone(),
43 ConString::Sqlite(s) => s.admin_token.clone(),
44 }
45 }
46}
47
48#[derive(Debug, Clone, PartialEq, Eq, Hash)]
49pub struct AdminUser {
50 pub pwd: String,
51 pub token: Option<String>,
52 pub salt: String,
53}
54
55impl AdminUser {
56 pub fn new(pwd: String, token: Option<String>, salt: String) -> Self {
57 Self { pwd, token, salt }
58 }
59}
60
61#[derive(Debug, Clone, PartialEq, Eq, Hash)]
62pub struct PgConString {
63 addr: String,
64 port: u16,
65 db: String,
66 user: String,
67 pwd: String,
68 admin: AdminUser,
69}
70
71impl PgConString {
72 pub fn new(addr: &str, port: u16, db: &str, user: &str, pwd: &str, admin: AdminUser) -> Self {
73 Self {
74 addr: addr.to_owned(),
75 port,
76 db: db.to_owned(),
77 user: user.to_owned(),
78 pwd: pwd.to_owned(),
79 admin,
80 }
81 }
82}
83
84impl From<&Settings> for PgConString {
85 fn from(s: &Settings) -> Self {
86 Self {
87 addr: s.postgresql.address.clone(),
88 port: s.postgresql.port,
89 db: s.postgresql.db.clone(),
90 user: s.postgresql.user.clone(),
91 pwd: s.postgresql.pwd.clone(),
92 admin: AdminUser {
93 pwd: s.setup.admin_pwd.clone(),
94 token: s.setup.admin_token.clone(),
95 salt: generate_salt(),
96 },
97 }
98 }
99}
100
101impl Display for PgConString {
102 fn fmt(&self, f: &mut Formatter) -> Result<(), std::fmt::Error> {
103 write!(
104 f,
105 "postgres://{}:{}@{}:{}/{}",
106 self.user, self.pwd, self.addr, self.port, self.db
107 )
108 }
109}
110
111#[derive(Debug, Clone, PartialEq, Eq, Hash)]
112pub struct SqliteConString {
113 pub path: PathBuf,
114 pub salt: String,
115 pub admin_pwd: String,
116 pub admin_token: Option<String>,
117 pub session_age: Duration,
118}
119
120impl SqliteConString {
121 pub fn new(
122 path: &Path,
123 salt: &str,
124 admin_pwd: &str,
125 admin_token: Option<String>,
126 session_age: Duration,
127 ) -> Self {
128 Self {
129 path: path.to_owned(),
130 salt: salt.to_owned(),
131 admin_pwd: admin_pwd.to_owned(),
132 admin_token,
133 session_age,
134 }
135 }
136}
137
138impl From<&Settings> for SqliteConString {
139 fn from(settings: &Settings) -> Self {
140 Self {
141 path: settings.sqlite_path(),
142 salt: generate_salt(),
143 admin_pwd: settings.setup.admin_pwd.clone(),
144 admin_token: settings.setup.admin_token.clone(),
145 session_age: Duration::from_secs(settings.registry.session_age_seconds),
146 }
147 }
148}
149
150impl Display for SqliteConString {
151 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
152 if self.path.to_str() == Some(":memory:") {
153 write!(f, "sqlite::memory:")
154 } else {
155 write!(f, "sqlite://{}?mode=rwc", self.path.display())
156 }
157 }
158}