Skip to main content

kellnr_db/
con_string.rs

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    /// Maximum lifetime of a session before it is considered expired.
48    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}