fluffle/
config.rs

1use oiseau::config::{Configuration, DatabaseConfig};
2use pathbufd::PathBufD;
3use serde::{Deserialize, Serialize};
4use tetratto_shared::hash::random_id;
5
6#[derive(Clone, Debug, Serialize, Deserialize)]
7pub struct ServiceHostsConfig {
8    pub tetratto: String,
9    pub buckets: String,
10}
11
12#[derive(Clone, Debug, Serialize, Deserialize)]
13pub struct Config {
14    /// The name of the site. Shown in the UI.
15    #[serde(default = "default_name")]
16    pub name: String,
17    /// The (CSS) theme color of the site. Shown in the UI.
18    #[serde(default = "default_theme_color")]
19    pub theme_color: String,
20    /// The slug of the instance's information page.
21    ///
22    /// Should be the pathname WITHOUT the leading slash.
23    #[serde(default = "default_what_page_slug")]
24    pub what_page_slug: String,
25    /// The username of the handler account in charge of this instance on the
26    /// linked Tetratto host.
27    #[serde(default = "default_tetratto_handler_account_username")]
28    pub tetratto_handler_account_username: String,
29    /// Database configuration.
30    #[serde(default = "default_database")]
31    pub database: DatabaseConfig,
32    /// Real IP header (for reverse proxy).
33    #[serde(default = "default_real_ip_header")]
34    pub real_ip_header: String,
35    /// The host URL of required services.
36    #[serde(default = "default_service_hosts")]
37    pub service_hosts: ServiceHostsConfig,
38    /// The master password which is allowed to do anything without password checks.
39    pub master_pass: String,
40}
41
42fn default_name() -> String {
43    "Fluffle".to_string()
44}
45
46fn default_theme_color() -> String {
47    "#a3b3ff".to_string()
48}
49
50fn default_what_page_slug() -> String {
51    "what".to_string()
52}
53
54fn default_tetratto_handler_account_username() -> String {
55    "fluffle".to_string()
56}
57
58fn default_database() -> DatabaseConfig {
59    DatabaseConfig::default()
60}
61
62fn default_real_ip_header() -> String {
63    "CF-Connecting-IP".to_string()
64}
65
66fn default_service_hosts() -> ServiceHostsConfig {
67    ServiceHostsConfig {
68        tetratto: "https://tetratto.com".to_string(),
69        buckets: "https://assetdelivery.tetratto.com".to_string(),
70    }
71}
72
73impl Configuration for Config {
74    fn db_config(&self) -> DatabaseConfig {
75        self.database.to_owned()
76    }
77}
78
79impl Default for Config {
80    fn default() -> Self {
81        Self {
82            name: default_name(),
83            theme_color: default_theme_color(),
84            what_page_slug: default_what_page_slug(),
85            tetratto_handler_account_username: default_tetratto_handler_account_username(),
86            database: default_database(),
87            real_ip_header: default_real_ip_header(),
88            service_hosts: default_service_hosts(),
89            master_pass: random_id(),
90        }
91    }
92}
93
94impl Config {
95    /// Read the configuration file.
96    pub fn read() -> Self {
97        toml::from_str(
98            &match std::fs::read_to_string(PathBufD::current().join("fluffle.toml")) {
99                Ok(x) => x,
100                Err(_) => {
101                    let x = Config::default();
102
103                    std::fs::write(
104                        PathBufD::current().join("fluffle.toml"),
105                        &toml::to_string_pretty(&x).expect("failed to serialize config"),
106                    )
107                    .expect("failed to write config");
108
109                    return x;
110                }
111            },
112        )
113        .expect("failed to deserialize config")
114    }
115}