Skip to content

Commit

Permalink
Merge pull request #4955 from wasmerio/cli-auth
Browse files Browse the repository at this point in the history
Move `WasmerConfig` out of the `registry_api` crate and introduce a `logout` subcommand
  • Loading branch information
xdoardo authored Jul 29, 2024
2 parents 94edff8 + 51d783f commit 531d30d
Show file tree
Hide file tree
Showing 46 changed files with 1,567 additions and 975 deletions.
5 changes: 4 additions & 1 deletion lib/backend-api/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -3011,6 +3011,8 @@ type Mutation {
updateUserInfo(input: UpdateUserInfoInput!): UpdateUserInfoPayload
validateUserPassword(input: ValidateUserPasswordInput!): ValidateUserPasswordPayload
generateApiToken(input: GenerateAPITokenInput!): GenerateAPITokenPayload

"""Request To revoke an API token; these start with 'wap_'."""
revokeApiToken(input: RevokeAPITokenInput!): RevokeAPITokenPayload
checkUserExists(input: CheckUserExistsInput!): CheckUserExistsPayload
readNotification(input: ReadNotificationInput!): ReadNotificationPayload
Expand Down Expand Up @@ -3656,6 +3658,7 @@ input GenerateAPITokenInput {
clientMutationId: String
}

"""Request To revoke an API token; these start with 'wap_'."""
type RevokeAPITokenPayload {
token: APIToken
success: Boolean
Expand All @@ -3664,7 +3667,7 @@ type RevokeAPITokenPayload {

input RevokeAPITokenInput {
"""The API token ID"""
tokenId: ID!
token: String!
clientMutationId: String
}

Expand Down
28 changes: 28 additions & 0 deletions lib/backend-api/src/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,34 @@ use crate::{
GraphQLApiFailure, WasmerClient,
};

/// Revoke an existing token
pub async fn revoke_token(
client: &WasmerClient,
token: String,
) -> Result<Option<bool>, anyhow::Error> {
client
.run_graphql_strict(types::RevokeToken::build(RevokeTokenVariables { token }))
.await
.map(|v| v.revoke_api_token.and_then(|v| v.success))
}

/// Generate a new Nonce
///
/// Takes a name and a callbackUrl and returns a nonce
pub async fn create_nonce(
client: &WasmerClient,
name: String,
callback_url: String,
) -> Result<Option<Nonce>, anyhow::Error> {
client
.run_graphql_strict(types::CreateNewNonce::build(CreateNewNonceVariables {
callback_url,
name,
}))
.await
.map(|v| v.new_nonce.map(|v| v.nonce))
}

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

#[derive(cynic::QueryVariables, Debug)]
pub struct RevokeTokenVariables {
pub token: String,
}

#[derive(cynic::QueryFragment, Debug)]
#[cynic(graphql_type = "Mutation", variables = "RevokeTokenVariables")]
pub struct RevokeToken {
#[arguments(input: { token: $token })]
pub revoke_api_token: Option<RevokeAPITokenPayload>,
}

#[derive(cynic::QueryFragment, Debug)]
pub struct RevokeAPITokenPayload {
pub success: Option<bool>,
}

#[derive(cynic::QueryVariables, Debug)]
pub struct CreateNewNonceVariables {
pub callback_url: String,
pub name: String,
}

#[derive(cynic::QueryFragment, Debug)]
#[cynic(graphql_type = "Mutation", variables = "CreateNewNonceVariables")]
pub struct CreateNewNonce {
#[arguments(input: { callbackUrl: $callback_url, name: $name })]
pub new_nonce: Option<NewNoncePayload>,
}

#[derive(cynic::QueryFragment, Debug)]
pub struct NewNoncePayload {
pub client_mutation_id: Option<String>,
pub nonce: Nonce,
}

#[derive(cynic::QueryFragment, Debug)]
pub struct Nonce {
pub auth_url: String,
pub callback_url: String,
pub created_at: DateTime,
pub expired: bool,
pub id: cynic::Id,
pub is_validated: bool,
pub name: String,
pub secret: String,
}

#[derive(cynic::QueryFragment, Debug)]
#[cynic(graphql_type = "Query")]
pub struct GetCurrentUser {
Expand Down
9 changes: 2 additions & 7 deletions lib/cli/src/commands/app/create.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ use wasmer_config::{app::AppConfigV1, package::PackageSource};
use super::{deploy::CmdAppDeploy, util::login_user};
use crate::{
commands::AsyncCliCommand,
opts::{ApiOpts, ItemFormatOpts, WasmerEnv},
config::WasmerEnv,
opts::ItemFormatOpts,
utils::{load_package_manifest, prompts::PackageCheckMode},
};

Expand Down Expand Up @@ -111,10 +112,6 @@ pub struct CmdAppCreate {
pub no_wait: bool,

// Common args.
#[clap(flatten)]
#[allow(missing_docs)]
pub api: ApiOpts,

#[clap(flatten)]
pub env: WasmerEnv,

Expand Down Expand Up @@ -730,7 +727,6 @@ the app:\n"
{
let cmd_deploy = CmdAppDeploy {
quiet: false,
api: self.api.clone(),
env: self.env.clone(),
fmt: ItemFormatOpts {
format: self.fmt.format,
Expand Down Expand Up @@ -767,7 +763,6 @@ impl AsyncCliCommand for CmdAppCreate {
} else {
Some(
login_user(
&self.api,
&self.env,
!self.non_interactive,
"retrieve informations about the owner of the app",
Expand Down
6 changes: 3 additions & 3 deletions lib/cli/src/commands/app/delete.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ use dialoguer::Confirm;
use is_terminal::IsTerminal;

use super::util::AppIdentOpts;
use crate::{commands::AsyncCliCommand, opts::ApiOpts};
use crate::{commands::AsyncCliCommand, config::WasmerEnv};

/// Delete an existing Edge app
#[derive(clap::Parser, Debug)]
pub struct CmdAppDelete {
#[clap(flatten)]
api: ApiOpts,
env: WasmerEnv,

#[clap(long, default_value_t = !std::io::stdin().is_terminal())]
non_interactive: bool,
Expand All @@ -25,7 +25,7 @@ impl AsyncCliCommand for CmdAppDelete {

async fn run_async(self) -> Result<(), anyhow::Error> {
let interactive = !self.non_interactive;
let client = self.api.client()?;
let client = self.env.client()?;

eprintln!("Looking up the app...");
let (_ident, app) = self.ident.load_app(&client).await?;
Expand Down
13 changes: 4 additions & 9 deletions lib/cli/src/commands/app/deploy.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use super::{util::login_user, AsyncCliCommand};
use crate::{
commands::{app::create::CmdAppCreate, package::publish::PackagePublish, PublishWait},
opts::{ApiOpts, ItemFormatOpts, WasmerEnv},
config::WasmerEnv,
opts::ItemFormatOpts,
utils::load_package_manifest,
};
use anyhow::Context;
Expand All @@ -27,9 +28,6 @@ static EDGE_HEADER_APP_VERSION_ID: http::HeaderName =
/// Deploy an app to Wasmer Edge.
#[derive(clap::Parser, Debug)]
pub struct CmdAppDeploy {
#[clap(flatten)]
pub api: ApiOpts,

#[clap(flatten)]
pub env: WasmerEnv,

Expand Down Expand Up @@ -156,7 +154,6 @@ impl CmdAppDeploy {
package_namespace: Some(owner),
non_interactive: self.non_interactive,
bump: self.bump,
api: self.api.clone(),
};

publish_cmd
Expand Down Expand Up @@ -211,7 +208,6 @@ impl CmdAppDeploy {
owner: self.owner.clone(),
app_name: self.app_name.clone(),
no_wait: self.no_wait,
api: self.api.clone(),
env: self.env.clone(),
fmt: ItemFormatOpts {
format: self.fmt.format,
Expand All @@ -232,8 +228,7 @@ impl AsyncCliCommand for CmdAppDeploy {
type Output = ();

async fn run_async(self) -> Result<Self::Output, anyhow::Error> {
let client =
login_user(&self.api, &self.env, !self.non_interactive, "deploy an app").await?;
let client = login_user(&self.env, !self.non_interactive, "deploy an app").await?;

let base_dir_path = self.dir.clone().unwrap_or_else(|| {
self.path
Expand Down Expand Up @@ -290,7 +285,7 @@ impl AsyncCliCommand for CmdAppDeploy {
"Enter the name of the app",
default_name.as_deref(),
&owner,
self.api.client().ok().as_ref(),
self.env.client().ok().as_ref(),
)
.await?;

Expand Down
14 changes: 5 additions & 9 deletions lib/cli/src/commands/app/get.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,19 @@
use wasmer_api::types::DeployApp;

use super::util::AppIdentOpts;
use crate::{
commands::AsyncCliCommand,
opts::{ApiOpts, ItemFormatOpts},
};

use crate::{commands::AsyncCliCommand, config::WasmerEnv, opts::ItemFormatOpts};

/// Retrieve detailed informations about an app
#[derive(clap::Parser, Debug)]
pub struct CmdAppGet {
#[clap(flatten)]
#[allow(missing_docs)]
pub api: ApiOpts,
pub env: WasmerEnv,

#[clap(flatten)]
#[allow(missing_docs)]
pub fmt: ItemFormatOpts,

#[clap(flatten)]
#[allow(missing_docs)]
pub ident: AppIdentOpts,
}

Expand All @@ -28,7 +24,7 @@ impl AsyncCliCommand for CmdAppGet {
type Output = DeployApp;

async fn run_async(self) -> Result<DeployApp, anyhow::Error> {
let client = self.api.client()?;
let client = self.env.client()?;
let (_ident, app) = self.ident.load_app(&client).await?;

println!("{}", self.fmt.format.render(&app));
Expand Down
6 changes: 3 additions & 3 deletions lib/cli/src/commands/app/info.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
//! Show short information about an Edge app.
use super::util::AppIdentOpts;
use crate::{commands::AsyncCliCommand, opts::ApiOpts};
use crate::{commands::AsyncCliCommand, config::WasmerEnv};

/// Show short information about an Edge app.
///
/// Use `app get` to get more detailed information.
#[derive(clap::Parser, Debug)]
pub struct CmdAppInfo {
#[clap(flatten)]
api: ApiOpts,
env: WasmerEnv,
#[clap(flatten)]
ident: AppIdentOpts,
}
Expand All @@ -19,7 +19,7 @@ impl AsyncCliCommand for CmdAppInfo {
type Output = ();

async fn run_async(self) -> Result<(), anyhow::Error> {
let client = self.api.client()?;
let client = self.env.client()?;
let (_ident, app) = self.ident.load_app(&client).await?;

let app_url = app.url;
Expand Down
10 changes: 4 additions & 6 deletions lib/cli/src/commands/app/list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,16 @@ use std::pin::Pin;
use futures::{Stream, StreamExt};
use wasmer_api::types::DeployApp;

use crate::{
commands::AsyncCliCommand,
opts::{ApiOpts, ListFormatOpts},
};
use crate::{commands::AsyncCliCommand, config::WasmerEnv, opts::ListFormatOpts};

/// List apps belonging to a namespace
#[derive(clap::Parser, Debug)]
pub struct CmdAppList {
#[clap(flatten)]
fmt: ListFormatOpts,

#[clap(flatten)]
api: ApiOpts,
env: WasmerEnv,

/// Get apps in a specific namespace.
///
Expand All @@ -43,7 +41,7 @@ impl AsyncCliCommand for CmdAppList {
type Output = ();

async fn run_async(self) -> Result<(), anyhow::Error> {
let client = self.api.client()?;
let client = self.env.client()?;

let apps_stream: Pin<
Box<dyn Stream<Item = Result<Vec<DeployApp>, anyhow::Error>> + Send + Sync>,
Expand Down
10 changes: 4 additions & 6 deletions lib/cli/src/commands/app/logs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,7 @@ use futures::StreamExt;
use time::{format_description::well_known::Rfc3339, OffsetDateTime};
use wasmer_api::types::{Log, LogStream};

use crate::{
opts::{ApiOpts, ListFormatOpts},
utils::render::CliRender,
};
use crate::{config::WasmerEnv, opts::ListFormatOpts, utils::render::CliRender};

use super::util::AppIdentOpts;

Expand All @@ -24,7 +21,8 @@ pub enum LogStreamArg {
#[derive(clap::Parser, Debug)]
pub struct CmdAppLogs {
#[clap(flatten)]
api: ApiOpts,
env: WasmerEnv,

#[clap(flatten)]
fmt: ListFormatOpts,

Expand Down Expand Up @@ -75,7 +73,7 @@ impl crate::commands::AsyncCliCommand for CmdAppLogs {
type Output = ();

async fn run_async(self) -> Result<(), anyhow::Error> {
let client = self.api.client()?;
let client = self.env.client()?;

let (_ident, app) = self.ident.load_app(&client).await?;

Expand Down
13 changes: 4 additions & 9 deletions lib/cli/src/commands/app/purge_cache.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
//! Get information about an edge app.
use super::util::AppIdentOpts;
use crate::{
commands::AsyncCliCommand,
opts::{ApiOpts, ItemFormatOpts},
};
use crate::{commands::AsyncCliCommand, config::WasmerEnv, opts::ItemFormatOpts};

/// Purge caches for applications.
///
Expand All @@ -15,14 +12,12 @@ use crate::{
#[derive(clap::Parser, Debug)]
pub struct CmdAppPurgeCache {
#[clap(flatten)]
#[allow(missing_docs)]
pub api: ApiOpts,
pub env: WasmerEnv,

#[clap(flatten)]
#[allow(missing_docs)]
pub fmt: ItemFormatOpts,

#[clap(flatten)]
#[allow(missing_docs)]
pub ident: AppIdentOpts,
}

Expand All @@ -31,7 +26,7 @@ impl AsyncCliCommand for CmdAppPurgeCache {
type Output = ();

async fn run_async(self) -> Result<(), anyhow::Error> {
let client = self.api.client()?;
let client = self.env.client()?;
let (_ident, app) = self.ident.load_app(&client).await?;

let version_id = app.active_version.id;
Expand Down
Loading

0 comments on commit 531d30d

Please sign in to comment.