Skip to content

Commit

Permalink
misc(provisioner): check project ownership in APIs (#1630)
Browse files Browse the repository at this point in the history
* misc(provisioner): check project ownership in APIs

* misc(provisioner): emit error events for unauthorized calls

* misc: remove envrc

* misc(provisioner): remove the errors event msg
iulianbarbu authored Feb 19, 2024

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
1 parent 46c71e7 commit 6e135a0
Showing 4 changed files with 43 additions and 1 deletion.
1 change: 0 additions & 1 deletion .envrc

This file was deleted.

1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -44,3 +44,4 @@ yarn.lock

*.wasm
*.sqlite*
.envrc
17 changes: 17 additions & 0 deletions common/src/backends/mod.rs
Original file line number Diff line number Diff line change
@@ -25,6 +25,12 @@ pub trait ClaimExt {
projects_dal: &G,
resource_dal: &mut R,
) -> Result<bool, client::Error>;
/// Verify if the claim subject has ownership of a project.
async fn owns_project<G: ProjectsDal>(
&self,
projects_dal: &G,
project_name: &str,
) -> Result<bool, client::Error>;
}

impl ClaimExt for Claim {
@@ -57,4 +63,15 @@ impl ClaimExt for Claim {

Ok(self.limits.rds_quota > (rds_count as u32))
}

#[instrument(skip_all)]
async fn owns_project<G: ProjectsDal>(
&self,
projects_dal: &G,
project_name: &str,
) -> Result<bool, client::Error> {
let token = self.token.as_ref().expect("token to be set");
let projects = projects_dal.get_user_projects(token).await?;
Ok(projects.iter().any(|project| project.name == project_name))
}
}
25 changes: 25 additions & 0 deletions provisioner/src/lib.rs
Original file line number Diff line number Diff line change
@@ -478,6 +478,18 @@ impl Provisioner for ShuttleProvisioner {
if !ProjectName::is_valid(&request.project_name) {
return Err(Status::invalid_argument("invalid project name"));
}

// Check project ownership.
if !claim
.owns_project(&self.gateway_client, &request.project_name)
.await
.map_err(|_| Status::internal("can not verify project ownership"))?
{
let status = Status::permission_denied("the request lacks the authorizations");
error!(error = &status as &dyn std::error::Error);
return Err(status);
}

let db_type = request.db_type.unwrap();

let reply = match db_type {
@@ -527,11 +539,24 @@ impl Provisioner for ShuttleProvisioner {
request: Request<DatabaseRequest>,
) -> Result<Response<DatabaseDeletionResponse>, Status> {
request.verify(Scope::ResourcesWrite)?;
let claim = request.get_claim()?;

let request = request.into_inner();
if !ProjectName::is_valid(&request.project_name) {
return Err(Status::invalid_argument("invalid project name"));
}

// Check project ownership.
if !claim
.owns_project(&self.gateway_client, &request.project_name)
.await
.map_err(|_| Status::internal("can not verify project ownership"))?
{
let status = Status::permission_denied("the request lacks the authorizations");
error!(error = &status as &dyn std::error::Error);
return Err(status);
}

let db_type = request.db_type.unwrap();

let reply = match db_type {

0 comments on commit 6e135a0

Please sign in to comment.