Skip to content

Commit

Permalink
Merge pull request #4994 from wasmerio/improve-deploy-viewercan
Browse files Browse the repository at this point in the history
Check if a user can deploy an app before deploying it
  • Loading branch information
xdoardo authored Aug 9, 2024
2 parents eb91270 + cfeb622 commit c0122bc
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 1 deletion.
12 changes: 12 additions & 0 deletions lib/backend-api/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ type User implements Node & PackageOwner & Owner {
id: ID!
globalName: String!
globalId: ID!
viewerCan(action: OwnerAction!): Boolean!
avatar(size: Int = 80): String!
isViewer: Boolean!
hasUsablePassword: Boolean
Expand Down Expand Up @@ -76,12 +77,19 @@ type User implements Node & PackageOwner & Owner {
interface PackageOwner {
globalName: String!
globalId: ID!
viewerCan(action: OwnerAction!): Boolean!
}

enum OwnerAction {
DEPLOY_APP
PUBLISH_PACKAGE
}

"""An owner of a package."""
interface Owner {
globalName: String!
globalId: ID!
viewerCan(action: OwnerAction!): Boolean!
}

"""
Expand Down Expand Up @@ -204,6 +212,7 @@ type Namespace implements Node & PackageOwner & Owner {
userSet(offset: Int, before: String, after: String, first: Int, last: Int): UserConnection!
globalName: String!
globalId: ID!
viewerCan(action: OwnerAction!): Boolean!
avatar: String!
packages(offset: Int, before: String, after: String, first: Int, last: Int): PackageConnection!
apps(sortBy: DeployAppsSortBy, offset: Int, before: String, after: String, first: Int, last: Int): DeployAppConnection!
Expand Down Expand Up @@ -372,6 +381,7 @@ type Package implements Likeable & Node & PackageOwner {
viewerHasLiked: Boolean!
globalName: String!
globalId: ID!
viewerCan(action: OwnerAction!): Boolean!
alias: String
displayName: String!

Expand Down Expand Up @@ -926,6 +936,7 @@ type DeployApp implements Node & Owner {
activeVersion: DeployAppVersion!
globalName: String!
globalId: ID!
viewerCan(action: OwnerAction!): Boolean!
url: String!
adminUrl: String!
permalink: String!
Expand Down Expand Up @@ -2388,6 +2399,7 @@ type Query {
getPackageRelease(hash: String!): PackageWebc
getPackageInstanceByVersionOrHash(name: String!, version: String, hash: String): PackageInstance
categories(offset: Int, before: String, after: String, first: Int, last: Int): CategoryConnection!
viewerCan(action: OwnerAction!, ownerName: String!): Boolean!
blogposts(tags: [String!], before: String, after: String, first: Int, last: Int): BlogPostConnection!
getBlogpost(slug: String, featured: Boolean): BlogPost
allBlogpostTags(offset: Int, before: String, after: String, first: Int, last: Int): BlogPostTagConnection
Expand Down
13 changes: 13 additions & 0 deletions lib/backend-api/src/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,19 @@ use crate::{
GraphQLApiFailure, WasmerClient,
};

pub async fn viewer_can_deploy_to_namespace(
client: &WasmerClient,
owner_name: &str,
) -> Result<bool, anyhow::Error> {
client
.run_graphql_strict(types::ViewerCan::build(ViewerCanVariables {
action: OwnerAction::DeployApp,
owner_name,
}))
.await
.map(|v| v.viewer_can)
}

pub async fn redeploy_app_by_id(
client: &WasmerClient,
app_id: impl Into<String>,
Expand Down
19 changes: 19 additions & 0 deletions lib/backend-api/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,25 @@ mod queries {
Viewer,
}

#[derive(cynic::QueryVariables, Debug)]
pub struct ViewerCanVariables<'a> {
pub action: OwnerAction,
pub owner_name: &'a str,
}

#[derive(cynic::QueryFragment, Debug)]
#[cynic(graphql_type = "Query", variables = "ViewerCanVariables")]
pub struct ViewerCan {
#[arguments(action: $action, ownerName: $owner_name)]
pub viewer_can: bool,
}

#[derive(cynic::Enum, Clone, Copy, Debug)]
pub enum OwnerAction {
DeployApp,
PublishPackage,
}

#[derive(cynic::QueryVariables, Debug)]
pub struct RevokeTokenVariables {
pub token: String,
Expand Down
29 changes: 28 additions & 1 deletion lib/cli/src/commands/app/deploy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -279,10 +279,37 @@ impl AsyncCliCommand for CmdAppDeploy {
None
};

let owner = self
let mut owner = self
.get_owner(&client, &mut app_yaml, maybe_edge_app.as_ref())
.await?;

if !wasmer_api::query::viewer_can_deploy_to_namespace(&client, &owner).await? {
eprintln!("It seems you don't have access to {}", owner.bold());
if self.non_interactive {
anyhow::bail!("Please, change the owner before deploying or check your current user with `{} whoami`.", std::env::args().next().unwrap_or("wasmer".into()));
} else {
let user = wasmer_api::query::current_user_with_namespaces(&client, None).await?;
owner = crate::utils::prompts::prompt_for_namespace(
"Who should own this app?",
None,
Some(&user),
)?;

app_yaml
.as_mapping_mut()
.unwrap()
.insert("owner".into(), owner.clone().into());

if app_yaml.get("app_id").is_some() {
app_yaml.as_mapping_mut().unwrap().remove("app_id");
}

if app_yaml.get("name").is_some() {
app_yaml.as_mapping_mut().unwrap().remove("name");
}
}
}

if app_yaml.get("name").is_none() && self.app_name.is_some() {
app_yaml.as_mapping_mut().unwrap().insert(
"name".into(),
Expand Down

0 comments on commit c0122bc

Please sign in to comment.