Skip to content

Commit 0272f81

Browse files
committed
total_members
1 parent 647bf44 commit 0272f81

File tree

4 files changed

+61
-17
lines changed

4 files changed

+61
-17
lines changed

lib/api_run/src/run.rs

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use bencher_endpoint::{CorsResponse, Endpoint, Post, ResponseCreated};
2-
use bencher_json::{JsonNewRun, JsonReport, RunContext};
2+
use bencher_json::{JsonNewRun, JsonReport, ResourceName, RunContext, Slug};
33
use bencher_rbac::project::Permission;
44
use bencher_schema::{
55
context::ApiContext,
@@ -50,21 +50,13 @@ async fn post_inner(
5050
) -> Result<JsonReport, HttpError> {
5151
let query_project = match (auth_user.as_ref(), json_run.project.as_ref()) {
5252
(Some(auth_user), Some(project)) => {
53-
QueryProject::get_or_create_from_project(log, context, auth_user, project)
53+
QueryProject::get_or_create(log, context, auth_user, project)
5454
.await
5555
.map_err(|e| forbidden_error(e.to_string()))?
5656
},
5757
(Some(auth_user), None) => {
58-
let Some(project_name) = json_run.context.as_ref().and_then(RunContext::name) else {
59-
return Err(bad_request_error(
60-
"The `project` field was not specified nor was a run `context` provided for the name",
61-
));
62-
};
63-
let Some(project_slug) = json_run.context.as_ref().map(RunContext::slug) else {
64-
return Err(bad_request_error(
65-
"The `project` field was not specified nor was a run `context` provided for the slug",
66-
));
67-
};
58+
let project_name = project_name(&json_run)?;
59+
let project_slug = project_slug(&json_run)?;
6860
QueryProject::get_or_create_from_context(
6961
log,
7062
context,
@@ -100,3 +92,27 @@ async fn post_inner(
10092
)
10193
.await
10294
}
95+
96+
fn project_name(json_run: &JsonNewRun) -> Result<ResourceName, HttpError> {
97+
json_run
98+
.context
99+
.as_ref()
100+
.and_then(RunContext::name)
101+
.ok_or_else(|| {
102+
bad_request_error(
103+
"The `project` field was not specified nor was a run `context` provided for the name",
104+
)
105+
})
106+
}
107+
108+
fn project_slug(json_run: &JsonNewRun) -> Result<Slug, HttpError> {
109+
json_run
110+
.context
111+
.as_ref()
112+
.map(RunContext::slug)
113+
.ok_or_else(|| {
114+
bad_request_error(
115+
"The `project` field was not specified nor was a run `context` provided for the slug",
116+
)
117+
})
118+
}

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

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@ use bencher_json::{
1111
use bencher_rbac::Organization;
1212
use diesel::{ExpressionMethods, QueryDsl, Queryable, RunQueryDsl};
1313
use dropshot::HttpError;
14-
use organization_role::InsertOrganizationRole;
14+
use organization_role::{InsertOrganizationRole, QueryOrganizationRole};
1515

1616
use crate::{
1717
conn_lock,
1818
context::{DbConnection, Rbac},
19-
error::{forbidden_error, resource_not_found_error, BencherResource},
19+
error::{forbidden_error, resource_not_found_error, unauthorized_error, BencherResource},
2020
macros::{
2121
fn_get::{fn_get, fn_get_id, fn_get_uuid},
2222
resource_id::{fn_eq_resource_id, fn_from_resource_id},
@@ -80,7 +80,19 @@ impl QueryOrganization {
8080
if let Ok(query_organization) =
8181
Self::from_resource_id(conn_lock!(context), &project_slug.clone().into())
8282
{
83-
return Ok(query_organization);
83+
// Get the total number of members for the organization
84+
let total_members =
85+
QueryOrganizationRole::count(conn_lock!(context), query_organization.id)?;
86+
// If the project is part of an organization that has zero members,
87+
// then the project can have anonymous reports.
88+
// That is, the project has not yet been claimed.
89+
return if total_members == 0 {
90+
Ok(query_organization)
91+
} else {
92+
Err(unauthorized_error(format!(
93+
"This project ({project_slug}) has already been claimed."
94+
)))
95+
};
8496
}
8597

8698
let json_organization = JsonNewOrganization {

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

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,16 @@ use bencher_json::{
33
DateTime, Jwt,
44
};
55
use bencher_token::TokenKey;
6+
use diesel::{ExpressionMethods, QueryDsl, RunQueryDsl};
67
use dropshot::HttpError;
78

89
use super::{OrganizationId, QueryOrganization};
910
use crate::{
1011
context::DbConnection,
1112
error::unauthorized_error,
1213
model::user::{QueryUser, UserId},
13-
schema::organization_role as organization_role_table,
14+
resource_not_found_err,
15+
schema::{self, organization_role as organization_role_table},
1416
};
1517

1618
crate::macros::typed_id::typed_id!(OrganizationRoleId);
@@ -25,6 +27,19 @@ pub struct QueryOrganizationRole {
2527
pub modified: DateTime,
2628
}
2729

30+
impl QueryOrganizationRole {
31+
pub fn count(
32+
conn: &mut DbConnection,
33+
organization_id: OrganizationId,
34+
) -> Result<i64, HttpError> {
35+
schema::organization_role::table
36+
.filter(schema::organization_role::organization_id.eq(&organization_id))
37+
.count()
38+
.get_result(conn)
39+
.map_err(resource_not_found_err!(OrganizationRole, organization_id))
40+
}
41+
}
42+
2843
#[derive(Debug, diesel::Insertable)]
2944
#[diesel(table_name = organization_role_table)]
3045
pub struct InsertOrganizationRole {

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ impl QueryProject {
8989
.map_err(resource_not_found_err!(Project, slug.clone()))
9090
}
9191

92-
pub async fn get_or_create_from_project(
92+
pub async fn get_or_create(
9393
log: &Logger,
9494
context: &ApiContext,
9595
auth_user: &AuthUser,
@@ -141,6 +141,7 @@ impl QueryProject {
141141
url: None,
142142
visibility: None,
143143
};
144+
144145
Self::create(log, context, auth_user, &query_organization, json_project).await
145146
}
146147

0 commit comments

Comments
 (0)