Skip to content

Commit 227a4a4

Browse files
authored
Merge pull request #5294 from nappa85/5291-daily_limit
Introduce daily limit of published versions per crate
2 parents 2b6ed6f + c03f327 commit 227a4a4

File tree

5 files changed

+648
-0
lines changed

5 files changed

+648
-0
lines changed

src/config.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ pub struct Server {
2525
pub max_upload_size: u64,
2626
pub max_unpack_size: u64,
2727
pub publish_rate_limit: PublishRateLimit,
28+
pub new_version_rate_limit: Option<u32>,
2829
pub blocked_traffic: Vec<(String, Vec<String>)>,
2930
pub max_allowed_page_offset: u32,
3031
pub page_offset_ua_blocklist: Vec<String>,
@@ -118,6 +119,7 @@ impl Default for Server {
118119
max_upload_size: 10 * 1024 * 1024, // 10 MB default file upload size limit
119120
max_unpack_size: 512 * 1024 * 1024, // 512 MB max when decompressed
120121
publish_rate_limit: Default::default(),
122+
new_version_rate_limit: env_optional("MAX_NEW_VERSIONS_DAILY"),
121123
blocked_traffic: blocked_traffic(),
122124
max_allowed_page_offset: env_optional("WEB_MAX_ALLOWED_PAGE_OFFSET").unwrap_or(200),
123125
page_offset_ua_blocklist,

src/controllers/krate/publish.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,15 @@ pub fn publish(req: &mut dyn RequestExt) -> EndpointResult {
128128
)));
129129
}
130130

131+
if let Some(daily_version_limit) = app.config.new_version_rate_limit {
132+
let published_today = count_versions_published_today(krate.id, &conn)?;
133+
if published_today >= daily_version_limit as i64 {
134+
return Err(cargo_err(
135+
"You have published too many versions of this crate in the last 24 hours",
136+
));
137+
}
138+
}
139+
131140
// Length of the .crate tarball, which appears after the metadata in the request body.
132141
// TODO: Not sure why we're using the total content length (metadata + .crate file length)
133142
// to compare against the max upload size... investigate that and perhaps change to use
@@ -259,6 +268,19 @@ pub fn publish(req: &mut dyn RequestExt) -> EndpointResult {
259268
})
260269
}
261270

271+
/// Counts the number of versions for `krate_id` that were published within
272+
/// the last 24 hours.
273+
fn count_versions_published_today(krate_id: i32, conn: &PgConnection) -> QueryResult<i64> {
274+
use crate::schema::versions::dsl::*;
275+
use diesel::dsl::{now, IntervalDsl};
276+
277+
versions
278+
.filter(crate_id.eq(krate_id))
279+
.filter(created_at.gt(now - 24.hours()))
280+
.count()
281+
.get_result(conn)
282+
}
283+
262284
/// Used by the `krate::new` function.
263285
///
264286
/// This function parses the JSON headers to interpret the data and validates

0 commit comments

Comments
 (0)