Skip to content

Commit cd078ed

Browse files
committed
org_claim
1 parent 026abb0 commit cd078ed

File tree

22 files changed

+464
-235
lines changed

22 files changed

+464
-235
lines changed

lib/api_auth/src/github.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,7 @@ async fn post_inner(
8282
} else if let Some(organization_uuid) = json_oauth.claim {
8383
let query_organization =
8484
QueryOrganization::from_uuid(conn_lock!(context), organization_uuid)?;
85-
let invite = query_organization.claim(context, &query_user).await?;
86-
query_user.accept_invite(conn_lock!(context), &context.token_key, &invite)?;
85+
query_organization.claim(context, &query_user).await?;
8786
}
8887
query_user
8988
} else {

lib/api_organizations/src/claim.rs

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
use bencher_endpoint::{CorsResponse, Endpoint, Post, ResponseCreated};
2+
use bencher_json::{JsonNewClaim, JsonOrganization, ResourceId};
3+
use bencher_schema::{
4+
conn_lock,
5+
context::ApiContext,
6+
model::{
7+
organization::QueryOrganization,
8+
user::auth::{AuthUser, BearerToken},
9+
},
10+
};
11+
use dropshot::{endpoint, HttpError, Path, RequestContext, TypedBody};
12+
use schemars::JsonSchema;
13+
use serde::Deserialize;
14+
15+
#[derive(Deserialize, JsonSchema)]
16+
pub struct OrgClaimParams {
17+
/// The slug or UUID for an organization.
18+
pub organization: ResourceId,
19+
}
20+
21+
#[allow(clippy::no_effect_underscore_binding, clippy::unused_async)]
22+
#[endpoint {
23+
method = OPTIONS,
24+
path = "/v0/organizations/{organization}/claim",
25+
tags = ["organizations"]
26+
}]
27+
pub async fn org_claim_options(
28+
_rqctx: RequestContext<ApiContext>,
29+
_path_params: Path<OrgClaimParams>,
30+
) -> Result<CorsResponse, HttpError> {
31+
Ok(Endpoint::cors(&[Post.into()]))
32+
}
33+
34+
/// Claim an organization
35+
///
36+
/// Claim an organization.
37+
/// The user must be authenticated and the organization must be unclaimed.
38+
#[endpoint {
39+
method = POST,
40+
path = "/v0/organizations/{organization}/claim",
41+
tags = ["organizations"]
42+
}]
43+
pub async fn org_claim_post(
44+
rqctx: RequestContext<ApiContext>,
45+
bearer_token: BearerToken,
46+
path_params: Path<OrgClaimParams>,
47+
body: TypedBody<JsonNewClaim>,
48+
) -> Result<ResponseCreated<JsonOrganization>, HttpError> {
49+
let auth_user = AuthUser::from_token(rqctx.context(), bearer_token).await?;
50+
let json = post_inner(
51+
rqctx.context(),
52+
path_params.into_inner(),
53+
body.into_inner(),
54+
auth_user,
55+
)
56+
.await?;
57+
Ok(Post::auth_response_created(json))
58+
}
59+
60+
async fn post_inner(
61+
context: &ApiContext,
62+
path_params: OrgClaimParams,
63+
_json_claim: JsonNewClaim,
64+
auth_user: AuthUser,
65+
) -> Result<JsonOrganization, HttpError> {
66+
let query_organization =
67+
QueryOrganization::from_resource_id(conn_lock!(context), &path_params.organization)?;
68+
query_organization.claim(context, &auth_user.user).await?;
69+
70+
Ok(query_organization.into_json(conn_lock!(context)))
71+
}

lib/api_organizations/src/lib.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
mod allowed;
2+
mod claim;
23
mod members;
34
mod organizations;
45
mod plan;
@@ -24,6 +25,12 @@ impl bencher_endpoint::Registrar for Api {
2425
api_description.register(organizations::organization_patch)?;
2526
api_description.register(organizations::organization_delete)?;
2627

28+
// Project Claim
29+
if http_options {
30+
api_description.register(claim::org_claim_options)?;
31+
}
32+
api_description.register(claim::org_claim_post)?;
33+
2734
// Organization Permission
2835
if http_options {
2936
api_description.register(allowed::org_allowed_options)?;

lib/api_projects/src/claim.rs

Lines changed: 0 additions & 100 deletions
This file was deleted.

lib/api_projects/src/lib.rs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ mod alerts;
22
mod allowed;
33
mod benchmarks;
44
mod branches;
5-
mod claim;
65
mod measures;
76
mod metrics;
87
mod perf;
@@ -33,12 +32,6 @@ impl bencher_endpoint::Registrar for Api {
3332
api_description.register(projects::project_patch)?;
3433
api_description.register(projects::project_delete)?;
3534

36-
// Project Claim
37-
if http_options {
38-
api_description.register(claim::proj_claim_options)?;
39-
}
40-
api_description.register(claim::proj_claim_post)?;
41-
4235
// Project Permission
4336
if http_options {
4437
api_description.register(allowed::proj_allowed_options)?;

lib/api_run/src/run.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,9 @@ async fn post_inner(
6565
.await?
6666
};
6767

68-
// If a project is unclaimed, don't check permissions
69-
if query_project.is_claimed(conn_lock!(context))? {
68+
let query_organization = query_project.organization(conn_lock!(context))?;
69+
// If the organization is claimed, check permissions
70+
if query_organization.is_claimed(conn_lock!(context))? {
7071
if let Some(auth_user) = auth_user.as_ref() {
7172
query_project.try_allowed(&context.rbac, auth_user, Permission::Create)?;
7273
} else {
@@ -75,6 +76,9 @@ async fn post_inner(
7576
query_project.slug
7677
)));
7778
}
79+
// If the organization is not claimed and the user is authenticated, claim it
80+
} else if let Some(auth_user) = auth_user.as_ref() {
81+
query_organization.claim(context, &auth_user.user).await?;
7882
}
7983
QueryReport::create(
8084
log,

lib/bencher_json/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ pub use organization::{plan::JsonPlan, usage::JsonUsage};
3131

3232
pub use big_int::BigInt;
3333
pub use organization::{
34+
claim::JsonNewClaim,
3435
member::{JsonMember, JsonMembers},
3536
JsonNewOrganization, JsonOrganization, JsonOrganizations, OrganizationUuid,
3637
};
@@ -40,7 +41,6 @@ pub use project::{
4041
benchmark::{BenchmarkUuid, JsonBenchmark, JsonBenchmarks},
4142
boundary::{BoundaryUuid, JsonBoundaries, JsonBoundary},
4243
branch::{BranchUuid, JsonBranch, JsonBranches, JsonNewBranch, JsonNewStartPoint},
43-
claim::JsonNewClaim,
4444
head::{HeadUuid, JsonHead, JsonStartPoint, VersionUuid},
4545
measure::{JsonMeasure, JsonMeasures, JsonNewMeasure, MeasureUuid},
4646
metric::{

lib/bencher_json/src/project/claim.rs renamed to lib/bencher_json/src/organization/claim.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,8 @@ use serde::{Deserialize, Serialize};
55
#[typeshare::typeshare]
66
#[derive(Debug, Clone, Serialize, Deserialize)]
77
#[cfg_attr(feature = "schema", derive(JsonSchema))]
8-
pub struct JsonNewClaim {}
8+
pub struct JsonNewClaim {
9+
// This is a bit of a kludge to make this an empty object
10+
#[serde(skip_serializing_if = "Option::is_none")]
11+
pub empty: Option<()>,
12+
}

lib/bencher_json/src/organization/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use serde::{
1111

1212
use crate::UserUuid;
1313

14+
pub mod claim;
1415
pub mod member;
1516
pub mod plan;
1617
pub mod usage;

lib/bencher_json/src/project/mod.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ pub mod alert;
1717
pub mod benchmark;
1818
pub mod boundary;
1919
pub mod branch;
20-
pub mod claim;
2120
pub mod head;
2221
pub mod measure;
2322
pub mod metric;

0 commit comments

Comments
 (0)