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 #[serde(default = "default_fluffle")]
63 pub fluffle: String,
64}
65
66fn default_shrimpcamp() -> String {
67 "https://about.shrimpcamp.com".to_string()
68}
69
70fn default_tetratto() -> String {
71 "https://tetratto.com".to_string()
72}
73
74fn default_askall() -> String {
75 "https://askall.cc".to_string()
76}
77
78fn default_issuestack() -> String {
79 "https://stack.shrimpcamp.com".to_string()
80}
81
82fn default_fluffle() -> String {
83 "https://fluffle.cc".to_string()
84}
85
86fn default_buckets() -> String {
87 "http://localhost:8020".to_string()
88}
89
90impl Default for ServiceHostsConfig {
91 fn default() -> Self {
92 Self {
93 shrimpcamp: default_shrimpcamp(),
94 tetratto: default_tetratto(),
95 buckets: default_buckets(),
96 askall: default_askall(),
97 issuestack: default_issuestack(),
98 fluffle: default_fluffle(),
99 }
100 }
101}
102
103#[derive(Clone, Debug, Serialize, Deserialize)]
104pub struct DirectoriesConfig {
105 #[serde(default = "default_media")]
106 pub media: String,
107}
108
109fn default_media() -> String {
110 "media".to_string()
111}
112
113impl Default for DirectoriesConfig {
114 fn default() -> Self {
115 Self {
116 media: default_media(),
117 }
118 }
119}
120
121fn default_name() -> String {
122 "Autter".to_string()
123}
124
125fn default_real_ip_header() -> String {
126 "CF-Connecting-IP".to_string()
127}
128
129fn default_database() -> DatabaseConfig {
130 DatabaseConfig::default()
131}
132
133#[derive(Clone, Serialize, Deserialize, Debug, Default)]
144pub struct StripeConfig {
145 pub secret: String,
147 pub webhook_signing_secret: String,
155 pub billing_portal_url: String,
159 pub price_texts: StripePriceTexts,
161 pub product_ids: StripeProductIds,
165 pub price_ids: StripePriceIds,
167}
168
169#[derive(Clone, Serialize, Deserialize, Debug, Default)]
170pub struct StripePriceTexts {
171 pub organization: String,
172 pub user_reg: String,
173}
174
175#[derive(Clone, Serialize, Deserialize, Debug, Default)]
176pub struct StripeProductIds {
177 pub organization: String,
178 pub user_reg: String,
179}
180
181#[derive(Clone, Serialize, Deserialize, Debug, Default)]
182pub struct StripePriceIds {
183 pub organization: String,
184 pub user_reg: String,
185}
186
187impl Configuration for Config {
188 fn db_config(&self) -> DatabaseConfig {
189 self.database.to_owned()
190 }
191}
192
193impl Default for Config {
194 fn default() -> Self {
195 Self {
196 name: default_name(),
197 database: default_database(),
198 service_hosts: ServiceHostsConfig::default(),
199 host: String::new(),
200 banned_usernames: default_banned_usernames(),
201 security: SecurityConfig::default(),
202 dirs: DirectoriesConfig::default(),
203 stripe: StripeConfig::default(),
204 }
205 }
206}
207
208impl Config {
209 pub fn read() -> Self {
211 toml::from_str(
212 &match std::fs::read_to_string(PathBufD::current().join("app.toml")) {
213 Ok(x) => x,
214 Err(_) => {
215 let x = Config::default();
216
217 std::fs::write(
218 PathBufD::current().join("app.toml"),
219 toml::to_string_pretty(&x).expect("failed to serialize config"),
220 )
221 .expect("failed to write config");
222
223 return x;
224 }
225 },
226 )
227 .expect("failed to deserialize config")
228 }
229}