1use oiseau::config::{Configuration, DatabaseConfig};
2use pathbufd::PathBufD;
3use serde::{Deserialize, Serialize};
4
5#[derive(Clone, Debug, Serialize, Deserialize)]
6pub struct Config {
7 #[serde(default = "default_name")]
9 pub name: String,
10 #[serde(default = "default_database")]
12 pub database: DatabaseConfig,
13 #[serde(default)]
15 pub service_hosts: ServiceHostsConfig,
16 #[serde(default)]
18 pub host: String,
19 #[serde(default = "default_banned_usernames")]
21 pub banned_usernames: Vec<String>,
22 #[serde(default)]
24 pub security: SecurityConfig,
25 #[serde(default)]
27 pub dirs: DirectoriesConfig,
28 pub stripe: StripeConfig,
30}
31
32fn default_banned_usernames() -> Vec<String> {
33 vec!["admin".to_string(), "settings".to_string()]
34}
35
36#[derive(Clone, Debug, Serialize, Deserialize, Default)]
37pub struct SecurityConfig {
38 #[serde(default)]
39 pub accepting_purchases: bool,
40 #[serde(default)]
41 pub registration_enabled: bool,
42 #[serde(default = "default_real_ip_header")]
44 pub real_ip_header: String,
45 #[serde(default)]
47 pub approved_login_redirects: Vec<String>,
48}
49
50#[derive(Clone, Debug, Serialize, Deserialize)]
51pub struct ServiceHostsConfig {
52 #[serde(default = "default_shrimpcamp")]
53 pub shrimpcamp: String,
54 #[serde(default = "default_tetratto")]
55 pub tetratto: String,
56 #[serde(default = "default_buckets")]
57 pub buckets: String,
58 #[serde(default = "default_askall")]
59 pub askall: String,
60 #[serde(default = "default_issuestack")]
61 pub issuestack: String,
62}
63
64fn default_shrimpcamp() -> String {
65 "https://about.shrimpcamp.com".to_string()
66}
67
68fn default_tetratto() -> String {
69 "https://tetratto.com".to_string()
70}
71
72fn default_askall() -> String {
73 "https://askall.cc".to_string()
74}
75
76fn default_issuestack() -> String {
77 "https://stack.shrimpcamp.com".to_string()
78}
79
80fn default_buckets() -> String {
81 "http://localhost:8020".to_string()
82}
83
84impl Default for ServiceHostsConfig {
85 fn default() -> Self {
86 Self {
87 shrimpcamp: default_shrimpcamp(),
88 tetratto: default_tetratto(),
89 buckets: default_buckets(),
90 askall: default_askall(),
91 issuestack: default_issuestack(),
92 }
93 }
94}
95
96#[derive(Clone, Debug, Serialize, Deserialize)]
97pub struct DirectoriesConfig {
98 #[serde(default = "default_media")]
99 pub media: String,
100}
101
102fn default_media() -> String {
103 "media".to_string()
104}
105
106impl Default for DirectoriesConfig {
107 fn default() -> Self {
108 Self {
109 media: default_media(),
110 }
111 }
112}
113
114fn default_name() -> String {
115 "Autter".to_string()
116}
117
118fn default_real_ip_header() -> String {
119 "CF-Connecting-IP".to_string()
120}
121
122fn default_database() -> DatabaseConfig {
123 DatabaseConfig::default()
124}
125
126#[derive(Clone, Serialize, Deserialize, Debug, Default)]
137pub struct StripeConfig {
138 pub secret: String,
140 pub webhook_signing_secret: String,
148 pub billing_portal_url: String,
152 pub price_texts: StripePriceTexts,
154 pub product_ids: StripeProductIds,
158 pub price_ids: StripePriceIds,
160}
161
162#[derive(Clone, Serialize, Deserialize, Debug, Default)]
163pub struct StripePriceTexts {
164 pub organization: String,
165}
166
167#[derive(Clone, Serialize, Deserialize, Debug, Default)]
168pub struct StripeProductIds {
169 pub organization: String,
170}
171
172#[derive(Clone, Serialize, Deserialize, Debug, Default)]
173pub struct StripePriceIds {
174 pub organization: String,
175}
176
177impl Configuration for Config {
178 fn db_config(&self) -> DatabaseConfig {
179 self.database.to_owned()
180 }
181}
182
183impl Default for Config {
184 fn default() -> Self {
185 Self {
186 name: default_name(),
187 database: default_database(),
188 service_hosts: ServiceHostsConfig::default(),
189 host: String::new(),
190 banned_usernames: default_banned_usernames(),
191 security: SecurityConfig::default(),
192 dirs: DirectoriesConfig::default(),
193 stripe: StripeConfig::default(),
194 }
195 }
196}
197
198impl Config {
199 pub fn read() -> Self {
201 toml::from_str(
202 &match std::fs::read_to_string(PathBufD::current().join("app.toml")) {
203 Ok(x) => x,
204 Err(_) => {
205 let x = Config::default();
206
207 std::fs::write(
208 PathBufD::current().join("app.toml"),
209 toml::to_string_pretty(&x).expect("failed to serialize config"),
210 )
211 .expect("failed to write config");
212
213 return x;
214 }
215 },
216 )
217 .expect("failed to deserialize config")
218 }
219}