@@ -20,9 +20,9 @@ pg_enum! {
20
20
impl LimitedAction {
21
21
pub fn default_rate_seconds ( & self ) -> u64 {
22
22
match self {
23
- LimitedAction :: PublishNew => 60 * 60 ,
24
- LimitedAction :: PublishUpdate => 60 ,
25
- LimitedAction :: YankUnyank => 60 ,
23
+ LimitedAction :: PublishNew => 10 * 60 , // 10 minutes
24
+ LimitedAction :: PublishUpdate => 60 , // 1 minute
25
+ LimitedAction :: YankUnyank => 60 , // 1 minute
26
26
}
27
27
}
28
28
@@ -176,6 +176,74 @@ mod tests {
176
176
use crate :: email:: Emails ;
177
177
use crate :: test_util:: * ;
178
178
179
+ #[ test]
180
+ fn default_rate_limits ( ) -> QueryResult < ( ) > {
181
+ let conn = & mut pg_connection ( ) ;
182
+ let now = now ( ) ;
183
+
184
+ // Set the defaults as if no env vars have been set in production
185
+ let mut rate_limiter = HashMap :: new ( ) ;
186
+ for action in LimitedAction :: VARIANTS {
187
+ rate_limiter. insert (
188
+ * action,
189
+ RateLimiterConfig {
190
+ rate : Duration :: from_secs ( action. default_rate_seconds ( ) ) ,
191
+ burst : action. default_burst ( ) ,
192
+ } ,
193
+ ) ;
194
+ }
195
+ let rate = RateLimiter :: new ( rate_limiter) ;
196
+
197
+ let user_id = new_user_bucket ( conn, 5 , now) ?. user_id ;
198
+
199
+ // Publishing new crates has a burst of 5 and refill time of 1 every 10 minutes, which
200
+ // means we should be able to publish every 10 min, always have tokens remaining, and
201
+ // set the last_refill based on the refill time.
202
+ let action = LimitedAction :: PublishNew ;
203
+ let mut last_refill_times = vec ! [ ] ;
204
+ let mut expected_last_refill_times = vec ! [ ] ;
205
+ for publish_num in 1 ..=10 {
206
+ let publish_time = now + chrono:: Duration :: minutes ( 10 * publish_num) ;
207
+ let bucket = rate. take_token ( user_id, action, publish_time, conn) ?;
208
+
209
+ last_refill_times. push ( bucket. last_refill ) ;
210
+ expected_last_refill_times. push ( publish_time) ;
211
+ }
212
+ assert_eq ! ( expected_last_refill_times, last_refill_times) ;
213
+
214
+ // Publishing new versions has a burst of 30 and refill time of every minute, which
215
+ // means we should be able to publish every min, always have tokens remaining, and
216
+ // set the last_refill based on the refill time.
217
+ let action = LimitedAction :: PublishUpdate ;
218
+ let mut last_refill_times = vec ! [ ] ;
219
+ let mut expected_last_refill_times = vec ! [ ] ;
220
+ for publish_num in 1 ..=35 {
221
+ let publish_time = now + chrono:: Duration :: minutes ( publish_num) ;
222
+ let bucket = rate. take_token ( user_id, action, publish_time, conn) ?;
223
+
224
+ last_refill_times. push ( bucket. last_refill ) ;
225
+ expected_last_refill_times. push ( publish_time) ;
226
+ }
227
+ assert_eq ! ( expected_last_refill_times, last_refill_times) ;
228
+
229
+ // Yanking/unyanking has a burst of 100 and refill time of every minute, which
230
+ // means we should be able to yank/unyank every min, always have tokens remaining, and
231
+ // set the last_refill based on the refill time.
232
+ let action = LimitedAction :: YankUnyank ;
233
+ let mut last_refill_times = vec ! [ ] ;
234
+ let mut expected_last_refill_times = vec ! [ ] ;
235
+ for publish_num in 1 ..=110 {
236
+ let publish_time = now + chrono:: Duration :: minutes ( publish_num) ;
237
+ let bucket = rate. take_token ( user_id, action, publish_time, conn) ?;
238
+
239
+ last_refill_times. push ( bucket. last_refill ) ;
240
+ expected_last_refill_times. push ( publish_time) ;
241
+ }
242
+ assert_eq ! ( expected_last_refill_times, last_refill_times) ;
243
+
244
+ Ok ( ( ) )
245
+ }
246
+
179
247
#[ test]
180
248
fn take_token_with_no_bucket_creates_new_one ( ) -> QueryResult < ( ) > {
181
249
let conn = & mut pg_connection ( ) ;
0 commit comments