Skip to content

Commit d548813

Browse files
committed
head
1 parent 2ba4da0 commit d548813

File tree

3 files changed

+55
-2
lines changed

3 files changed

+55
-2
lines changed

lib/bencher_schema/src/macros/rate_limit.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,11 @@ use bencher_json::DateTime;
44

55
use crate::{
66
error::BencherResource,
7-
model::{organization::QueryOrganization, project::QueryProject, user::QueryUser},
7+
model::{
8+
organization::QueryOrganization,
9+
project::{branch::QueryBranch, QueryProject},
10+
user::QueryUser,
11+
},
812
};
913

1014
pub const DAY: Duration = Duration::from_secs(24 * 60 * 60);
@@ -28,6 +32,11 @@ pub enum RateLimitError {
2832
project: QueryProject,
2933
resource: BencherResource,
3034
},
35+
#[error("Branch ({uuid}) has exceeded the daily rate limit ({UNCLAIMED_RATE_LIMIT}) for {resource} creation. Please, reduce your daily usage.", uuid = branch.uuid)]
36+
Branch {
37+
branch: QueryBranch,
38+
resource: BencherResource,
39+
},
3140
#[error("User ({uuid}) has exceeded the daily rate limit ({UNCLAIMED_RATE_LIMIT}) for {resource} creation. Please, reduce your daily usage.", uuid = user.uuid)]
3241
User {
3342
user: QueryUser,

lib/bencher_schema/src/model/organization/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,7 @@ impl InsertOrganization {
307307
pub async fn rate_limit(context: &ApiContext, query_user: &QueryUser) -> Result<(), HttpError> {
308308
use crate::macros::rate_limit::{one_day, RateLimitError, UNCLAIMED_RATE_LIMIT};
309309

310-
let resource = BencherResource::Project;
310+
let resource = BencherResource::Organization;
311311
let (start_time, end_time) = one_day();
312312
let creation_count: u32 = schema::organization::table
313313
.inner_join(schema::organization_role::table)

lib/bencher_schema/src/model/project/branch/head.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,48 @@ pub struct CloneThresholds {
201201
}
202202

203203
impl InsertHead {
204+
#[cfg(feature = "plus")]
205+
pub async fn rate_limit(
206+
context: &ApiContext,
207+
query_branch: &QueryBranch,
208+
) -> Result<(), HttpError> {
209+
use crate::{
210+
error::BencherResource,
211+
macros::rate_limit::{one_day, RateLimitError, CLAIMED_RATE_LIMIT},
212+
};
213+
214+
let resource = BencherResource::Head;
215+
let (start_time, end_time) = one_day();
216+
let creation_count: u32 = schema::head::table
217+
.filter(schema::head::branch_id.eq(query_branch.id))
218+
.filter(schema::head::created.ge(start_time))
219+
.filter(schema::head::created.le(end_time))
220+
.count()
221+
.get_result::<i64>(conn_lock!(context))
222+
.map_err(resource_not_found_err!(Token, (query_branch, start_time, end_time)))?
223+
.try_into()
224+
.map_err(|e| {
225+
issue_error(
226+
"Failed to count creation",
227+
&format!("Failed to count {resource} creation for branch ({uuid}) between {start_time} and {end_time}.", uuid = query_branch.uuid),
228+
e
229+
)}
230+
)?;
231+
232+
// The only way that new `HEAD` can be crated is either through running a Report
233+
// or by updating an existing branch using the API.
234+
// The running of a Report will be rate limited already for unclaimed projects,
235+
// and the API endpoint to update an existing branch would require authentication and would therefore be a claimed project.
236+
if creation_count >= CLAIMED_RATE_LIMIT {
237+
Err(crate::error::too_many_requests(RateLimitError::Branch {
238+
branch: query_branch.clone(),
239+
resource,
240+
}))
241+
} else {
242+
Ok(())
243+
}
244+
}
245+
204246
fn new(branch_id: BranchId, start_point_id: Option<HeadVersionId>) -> Self {
205247
Self {
206248
uuid: HeadUuid::new(),
@@ -217,6 +259,8 @@ impl InsertHead {
217259
query_branch: QueryBranch,
218260
branch_start_point: Option<&StartPoint>,
219261
) -> Result<(QueryBranch, QueryHead), HttpError> {
262+
Self::rate_limit(context, &query_branch).await?;
263+
220264
// Create the head for the branch
221265
let insert_head = Self::new(
222266
query_branch.id,

0 commit comments

Comments
 (0)