1use super::{
2 ExtensionSettings, SettingsDeserializeExt, SettingsDeserializer, SettingsSerializeExt,
3 SettingsSerializer,
4};
5use garde::Validate;
6use serde::{Deserialize, Serialize};
7use utoipa::ToSchema;
8
9#[derive(Clone, Copy, Validate, ToSchema, Serialize, Deserialize)]
10pub struct RatelimitConfiguration {
11 #[garde(range(min = 1))]
12 pub hits: u64,
13 #[garde(range(min = 1))]
14 pub window_seconds: u64,
15}
16
17#[derive(Clone, ToSchema, Serialize, Deserialize)]
18pub struct AppSettingsRatelimits {
19 pub auth_register: RatelimitConfiguration,
20 pub auth_login: RatelimitConfiguration,
21 pub auth_login_checkpoint: RatelimitConfiguration,
22 pub auth_login_checkpoint_email: RatelimitConfiguration,
23 pub auth_login_security_key: RatelimitConfiguration,
24 pub auth_password_forgot: RatelimitConfiguration,
25 pub auth_password_reset: RatelimitConfiguration,
26 pub auth_email_verification: RatelimitConfiguration,
27
28 pub client: RatelimitConfiguration,
29 pub client_account_email_resend_verification: RatelimitConfiguration,
30 pub client_servers_backups_create: RatelimitConfiguration,
31 pub client_servers_files_pull: RatelimitConfiguration,
32 pub client_servers_files_pull_query: RatelimitConfiguration,
33
34 pub remote: RatelimitConfiguration,
35 pub remote_sftp_auth: RatelimitConfiguration,
36}
37
38#[async_trait::async_trait]
39impl SettingsSerializeExt for AppSettingsRatelimits {
40 async fn serialize(
41 &self,
42 serializer: SettingsSerializer,
43 ) -> Result<SettingsSerializer, anyhow::Error> {
44 Ok(serializer
45 .write_serde_setting("auth_register", &self.auth_register)?
46 .write_serde_setting("auth_login", &self.auth_login)?
47 .write_serde_setting("auth_login_checkpoint", &self.auth_login_checkpoint)?
48 .write_serde_setting(
49 "auth_login_checkpoint_email",
50 &self.auth_login_checkpoint_email,
51 )?
52 .write_serde_setting("auth_login_security_key", &self.auth_login_security_key)?
53 .write_serde_setting("auth_password_forgot", &self.auth_password_forgot)?
54 .write_serde_setting("auth_password_reset", &self.auth_password_reset)?
55 .write_serde_setting("auth_email_verification", &self.auth_email_verification)?
56 .write_serde_setting("client", &self.client)?
57 .write_serde_setting(
58 "client_account_email_resend_verification",
59 &self.client_account_email_resend_verification,
60 )?
61 .write_serde_setting(
62 "client_servers_backups_create",
63 &self.client_servers_backups_create,
64 )?
65 .write_serde_setting("client_servers_files_pull", &self.client_servers_files_pull)?
66 .write_serde_setting(
67 "client_servers_files_pull_query",
68 &self.client_servers_files_pull_query,
69 )?
70 .write_serde_setting("remote", &self.remote)?
71 .write_serde_setting("remote_sftp_auth", &self.remote_sftp_auth)?)
72 }
73}
74
75pub struct AppSettingsRatelimitsDeserializer;
76
77#[async_trait::async_trait]
78impl SettingsDeserializeExt for AppSettingsRatelimitsDeserializer {
79 async fn deserialize_boxed(
80 &self,
81 deserializer: SettingsDeserializer<'_>,
82 ) -> Result<ExtensionSettings, anyhow::Error> {
83 Ok(Box::new(AppSettingsRatelimits {
84 auth_register: deserializer.read_serde_setting("auth_register").unwrap_or(
85 RatelimitConfiguration {
86 hits: 10,
87 window_seconds: 3600,
88 },
89 ),
90 auth_login: deserializer.read_serde_setting("auth_login").unwrap_or(
91 RatelimitConfiguration {
92 hits: 20,
93 window_seconds: 300,
94 },
95 ),
96 auth_login_checkpoint: deserializer
97 .read_serde_setting("auth_login_checkpoint")
98 .unwrap_or(RatelimitConfiguration {
99 hits: 10,
100 window_seconds: 300,
101 }),
102 auth_login_checkpoint_email: deserializer
103 .read_serde_setting("auth_login_checkpoint_email")
104 .unwrap_or(RatelimitConfiguration {
105 hits: 5,
106 window_seconds: 900,
107 }),
108 auth_login_security_key: deserializer
109 .read_serde_setting("auth_login_security_key")
110 .unwrap_or(RatelimitConfiguration {
111 hits: 10,
112 window_seconds: 300,
113 }),
114 auth_password_forgot: deserializer
115 .read_serde_setting("auth_password_forgot")
116 .unwrap_or(RatelimitConfiguration {
117 hits: 10,
118 window_seconds: 3600,
119 }),
120 auth_password_reset: deserializer
121 .read_serde_setting("auth_password_reset")
122 .unwrap_or(RatelimitConfiguration {
123 hits: 10,
124 window_seconds: 300,
125 }),
126 auth_email_verification: deserializer
127 .read_serde_setting("auth_email_verification")
128 .unwrap_or(RatelimitConfiguration {
129 hits: 10,
130 window_seconds: 3600,
131 }),
132 client: deserializer
133 .read_serde_setting("client")
134 .unwrap_or(RatelimitConfiguration {
135 hits: 360,
136 window_seconds: 30,
137 }),
138 client_account_email_resend_verification: deserializer
139 .read_serde_setting("client_account_email_resend_verification")
140 .unwrap_or(RatelimitConfiguration {
141 hits: 10,
142 window_seconds: 3600,
143 }),
144 client_servers_backups_create: deserializer
145 .read_serde_setting("client_servers_backups_create")
146 .unwrap_or(RatelimitConfiguration {
147 hits: 4,
148 window_seconds: 300,
149 }),
150 client_servers_files_pull: deserializer
151 .read_serde_setting("client_servers_files_pull")
152 .unwrap_or(RatelimitConfiguration {
153 hits: 5,
154 window_seconds: 60,
155 }),
156 client_servers_files_pull_query: deserializer
157 .read_serde_setting("client_servers_files_pull_query")
158 .unwrap_or(RatelimitConfiguration {
159 hits: 10,
160 window_seconds: 60,
161 }),
162 remote: deserializer
163 .read_serde_setting("remote")
164 .unwrap_or(RatelimitConfiguration {
165 hits: 720,
166 window_seconds: 30,
167 }),
168 remote_sftp_auth: deserializer
169 .read_serde_setting("remote_sftp_auth")
170 .unwrap_or(RatelimitConfiguration {
171 hits: 60,
172 window_seconds: 30,
173 }),
174 }))
175 }
176}