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 pub fn session_age(&self) -> Duration {
49 match self {
50 ConString::Postgres(p) => p.session_age,
51 ConString::Sqlite(s) => s.session_age,
52 }
53 }
54}
55
56#[derive(Debug, Clone, PartialEq, Eq, Hash)]
57pub struct AdminUser {
58 pub pwd: String,
59 pub token: Option<String>,
60 pub salt: String,
61}
62
63impl AdminUser {
64 pub fn new(pwd: String, token: Option<String>, salt: String) -> Self {
65 Self { pwd, token, salt }
66 }
67}
68
69#[derive(Debug, Clone, PartialEq, Eq, Hash)]
70pub struct PgConString {
71 addr: String,
72 port: u16,
73 db: String,
74 user: String,
75 pwd: String,
76 admin: AdminUser,
77 pub session_age: Duration,
78}
79
80impl PgConString {
81 pub fn new(
82 addr: &str,
83 port: u16,
84 db: &str,
85 user: &str,
86 pwd: &str,
87 admin: AdminUser,
88 session_age: Duration,
89 ) -> Self {
90 Self {
91 addr: addr.to_owned(),
92 port,
93 db: db.to_owned(),
94 user: user.to_owned(),
95 pwd: pwd.to_owned(),
96 admin,
97 session_age,
98 }
99 }
100}
101
102impl From<&Settings> for PgConString {
103 fn from(s: &Settings) -> Self {
104 Self {
105 addr: s.postgresql.address.clone(),
106 port: s.postgresql.port,
107 db: s.postgresql.db.clone(),
108 user: s.postgresql.user.clone(),
109 pwd: s.postgresql.pwd.clone(),
110 admin: AdminUser {
111 pwd: s.setup.admin_pwd.clone(),
112 token: s.setup.admin_token.clone(),
113 salt: generate_salt(),
114 },
115 session_age: Duration::from_secs(s.registry.session_age_seconds),
116 }
117 }
118}
119
120impl Display for PgConString {
121 fn fmt(&self, f: &mut Formatter) -> Result<(), std::fmt::Error> {
122 write!(
123 f,
124 "postgres://{}:{}@{}:{}/{}",
125 self.user, self.pwd, self.addr, self.port, self.db
126 )
127 }
128}
129
130#[derive(Debug, Clone, PartialEq, Eq, Hash)]
131pub struct SqliteConString {
132 pub path: PathBuf,
133 pub salt: String,
134 pub admin_pwd: String,
135 pub admin_token: Option<String>,
136 pub session_age: Duration,
137}
138
139impl SqliteConString {
140 pub fn new(
141 path: &Path,
142 salt: &str,
143 admin_pwd: &str,
144 admin_token: Option<String>,
145 session_age: Duration,
146 ) -> Self {
147 Self {
148 path: path.to_owned(),
149 salt: salt.to_owned(),
150 admin_pwd: admin_pwd.to_owned(),
151 admin_token,
152 session_age,
153 }
154 }
155}
156
157impl From<&Settings> for SqliteConString {
158 fn from(settings: &Settings) -> Self {
159 Self {
160 path: settings.sqlite_path(),
161 salt: generate_salt(),
162 admin_pwd: settings.setup.admin_pwd.clone(),
163 admin_token: settings.setup.admin_token.clone(),
164 session_age: Duration::from_secs(settings.registry.session_age_seconds),
165 }
166 }
167}
168
169impl Display for SqliteConString {
170 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
171 if self.path.to_str() == Some(":memory:") {
172 write!(f, "sqlite::memory:")
173 } else {
174 write!(f, "sqlite://{}?mode=rwc", self.path.display())
175 }
176 }
177}