From 333ea1c51407a083e974f1900a9fd3c8a522dfce Mon Sep 17 00:00:00 2001 From: Morgante Pell Date: Wed, 1 May 2024 03:03:24 -0700 Subject: [PATCH] feat: expose improved auth utils (#294) --- Cargo.lock | 24 ++--- crates/auth/Cargo.toml | 3 + crates/auth/src/lib.rs | 1 + crates/auth/src/testing.rs | 32 +++++- crates/cli/src/commands/apply.rs | 4 + crates/cli/src/commands/apply_migration.rs | 6 ++ crates/core/Cargo.toml | 2 +- crates/graphql/Cargo.toml | 21 ---- crates/graphql/src/lib.rs | 1 - crates/graphql/src/rules.rs | 108 --------------------- crates/test_utils/Cargo.toml | 2 +- 11 files changed, 56 insertions(+), 148 deletions(-) delete mode 100644 crates/graphql/Cargo.toml delete mode 100644 crates/graphql/src/lib.rs delete mode 100644 crates/graphql/src/rules.rs diff --git a/Cargo.lock b/Cargo.lock index 79a8b28ae..0ec847495 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1329,19 +1329,9 @@ dependencies = [ "serde", ] -[[package]] -name = "grit_cache" -version = "0.1.0" -dependencies = [ - "anyhow", - "marzano-gritmodule", - "marzano-util", - "tokio", -] - [[package]] name = "grit-wasm-bindings" -version = "0.0.0" +version = "0.1.0" dependencies = [ "ai_builtins", "anyhow", @@ -1359,6 +1349,16 @@ dependencies = [ "web-tree-sitter-sg", ] +[[package]] +name = "grit_cache" +version = "0.1.0" +dependencies = [ + "anyhow", + "marzano-gritmodule", + "marzano-util", + "tokio", +] + [[package]] name = "h2" version = "0.3.24" @@ -2029,7 +2029,7 @@ dependencies = [ [[package]] name = "marzano-gritmodule" -version = "0.0.0" +version = "0.1.0" dependencies = [ "anyhow", "git2", diff --git a/crates/auth/Cargo.toml b/crates/auth/Cargo.toml index d26344b20..335a5f02b 100644 --- a/crates/auth/Cargo.toml +++ b/crates/auth/Cargo.toml @@ -24,3 +24,6 @@ tokio = { version = "1", features = ["full"] } log = { version = "0.4.19" } chrono = { version = "0.4.26" } marzano-util = { path = "../util" } + +[features] +test-utils = [] diff --git a/crates/auth/src/lib.rs b/crates/auth/src/lib.rs index 697ac9aca..82507ff3d 100644 --- a/crates/auth/src/lib.rs +++ b/crates/auth/src/lib.rs @@ -1,4 +1,5 @@ pub mod auth0; pub mod env; pub mod info; +#[cfg(any(test, feature = "test-utils"))] pub mod testing; diff --git a/crates/auth/src/testing.rs b/crates/auth/src/testing.rs index bff2f6824..30fa105a2 100644 --- a/crates/auth/src/testing.rs +++ b/crates/auth/src/testing.rs @@ -9,8 +9,33 @@ use crate::{ info::AuthInfo, }; +/// Attempts to read a variable, first from the environment, then from Doppler. +/// +/// If neither source has the variable, an error is returned. +fn get_config_var(var_name: &str) -> Result { + if let Ok(value) = env::var(var_name) { + return Ok(value); + } + + use std::process::Command; + let output = Command::new("doppler") + .args(["secrets", "get", var_name, "--plain"]) + .output(); + + match output { + Ok(output) if output.status.success() => { + let value = String::from_utf8_lossy(&output.stdout).trim().to_string(); + Ok(value) + } + _ => Err(anyhow::anyhow!( + "Variable {} not found in environment or Doppler", + var_name + )), + } +} + fn get_existing_token() -> Result { - let existing_token = env::var("API_TESTING_TOKEN")?; + let existing_token = get_config_var("API_TESTING_TOKEN")?; let info = AuthInfo { access_token: existing_token, }; @@ -24,8 +49,8 @@ fn get_existing_token() -> Result { fn get_new_tokens() -> Result { // Exchange client tokens for a test token - let client_id = env::var("API_TESTING_CLIENT_ID")?; - let client_secret = env::var("API_TESTING_CLIENT_SECRET")?; + let client_id = get_config_var("API_TESTING_CLIENT_ID")?; + let client_secret = get_config_var("API_TESTING_CLIENT_SECRET")?; let client = reqwest::blocking::Client::new(); @@ -68,7 +93,6 @@ mod tests { #[ignore = "eats up auth tokens, only enable when explicitly testing"] fn test_token_refresh() -> Result<()> { let auth_info = get_testing_auth_info().unwrap(); - println!("auth_info: {}", auth_info); assert!(!auth_info.is_expired()?); Ok(()) } diff --git a/crates/cli/src/commands/apply.rs b/crates/cli/src/commands/apply.rs index 2c097e1dd..a1394711d 100644 --- a/crates/cli/src/commands/apply.rs +++ b/crates/cli/src/commands/apply.rs @@ -52,6 +52,10 @@ pub(crate) async fn run_apply( ) -> Result<()> { #[cfg(feature = "workflows_v2")] { + if args.apply_migration_args.remote { + println!("Apply {} remotely", args.pattern_or_workflow); + anyhow::bail!("Remote workflows are not yet supported"); + } let current_dir = current_dir()?; let custom_workflow = find_workflow_file_from(current_dir, &args.pattern_or_workflow).await; if let Some(custom_workflow) = custom_workflow { diff --git a/crates/cli/src/commands/apply_migration.rs b/crates/cli/src/commands/apply_migration.rs index 2e70ba34f..7cb220627 100644 --- a/crates/cli/src/commands/apply_migration.rs +++ b/crates/cli/src/commands/apply_migration.rs @@ -21,6 +21,12 @@ pub struct ApplyMigrationArgs { help = "JSON input parameter to pass to the workflow" )] input: Option, + #[clap( + long, + help_heading = "Workflow options", + help = "Run the workflow remotely on Grit Cloud" + )] + pub(crate) remote: bool, /// Print verbose output #[clap(long)] verbose: bool, diff --git a/crates/core/Cargo.toml b/crates/core/Cargo.toml index a08acb631..224a82981 100644 --- a/crates/core/Cargo.toml +++ b/crates/core/Cargo.toml @@ -46,7 +46,7 @@ similar = "2.2.1" lazy_static = "1.4.0" insta = { version = "1.30.0", features = ["yaml", "redactions"] } trim-margin = "0.1.0" -marzano-auth = { path = "../auth" } +marzano-auth = { path = "../auth", features = ["test-utils"] } walkdir = "2.3.3" [features] diff --git a/crates/graphql/Cargo.toml b/crates/graphql/Cargo.toml deleted file mode 100644 index eb6005a41..000000000 --- a/crates/graphql/Cargo.toml +++ /dev/null @@ -1,21 +0,0 @@ -[package] -name = "marzano-graphql" -version = "0.1.0" -edition = "2021" -authors.workspace = true -description.workspace = true -documentation.workspace = true -homepage.workspace = true -license = "MIT" -publish = false - -[lints] -rust.unused_crate_dependencies = "warn" - -[dependencies] -marzano-auth = { path = "../auth", features = [], default-features = true } -marzano-gritmodule = { path = "../gritmodule" } -serde = { version = "1.0.164", features = ["derive"] } -serde_json = { version = "1.0.96" } -anyhow = { version = "1.0.70" } -reqwest = { version = "0.11.22", features = ["blocking", "json"] } diff --git a/crates/graphql/src/lib.rs b/crates/graphql/src/lib.rs deleted file mode 100644 index a4b5b6cd2..000000000 --- a/crates/graphql/src/lib.rs +++ /dev/null @@ -1 +0,0 @@ -pub mod rules; diff --git a/crates/graphql/src/rules.rs b/crates/graphql/src/rules.rs deleted file mode 100644 index 1e6d11ee1..000000000 --- a/crates/graphql/src/rules.rs +++ /dev/null @@ -1,108 +0,0 @@ -use anyhow::{bail, Context, Result}; -use marzano_auth::{env::get_graphql_api_url, info::AuthInfo}; -use marzano_gritmodule::fetcher::ModuleRepo; -use reqwest::Client; -use serde::{Deserialize, Serialize}; -use std::{mem, str::FromStr}; - -#[derive(Serialize, Debug)] -struct RepoInput<'a> { - repo: &'a str, - host: &'a str, -} - -#[derive(Serialize)] -struct RulesQuery<'a> { - query: &'a str, - variables: RepoInput<'a>, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct AutoReviewRule { - id: String, - title: String, - description: String, - level: String, - created_at: String, -} - -#[derive(Serialize, Deserialize, Debug)] -struct RuleProject { - review_rules: Vec, -} - -#[derive(Serialize, Deserialize, Debug)] -struct RulesData { - pattern_analysis_project: Vec, -} - -#[derive(Serialize, Deserialize, Debug)] -struct RulesResponse { - data: RulesData, -} - -#[derive(Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub enum PatternLevel { - None = 0, - Warn = 2, - Error = 3, -} - -impl FromStr for PatternLevel { - type Err = anyhow::Error; - fn from_str(s: &str) -> Result { - match s { - "none" => Ok(PatternLevel::None), - "warn" => Ok(PatternLevel::Warn), - "error" => Ok(PatternLevel::Error), - _ => bail!("'{}' is not a valid level", s), - } - } -} - -#[allow(dead_code)] -async fn fetch_project_rules(repo: &ModuleRepo, auth: &AuthInfo) -> Result> { - let token = &auth.access_token; - let client = Client::new(); - let query = r#" - query GetProjectRules($repo: String!, $host: String!) { - pattern_analysis_project(where: { repo: { _eq: $repo }, host: { _eq: $host }}) { - id - review_rules { - id - title - description - level - created_at - } - } - } - "#; - - let variables = RepoInput { - repo: &repo.full_name, - host: &repo.host, - }; - - let graphql_query = RulesQuery { query, variables }; - let url = format!("{}/graphql", get_graphql_api_url()); - let res = client - .post(&url) - .bearer_auth(token) - .json(&graphql_query) - .send() - .await?; - - let response_body = res.text().await?; - let mut response = serde_json::from_str::(&response_body) - .context("Failed to parse rules response")?; - let project = response - .data - .pattern_analysis_project - .get_mut(0) - .context("No project found")?; - let rules = mem::take(&mut project.review_rules); - - Ok(rules) -} diff --git a/crates/test_utils/Cargo.toml b/crates/test_utils/Cargo.toml index 113b26352..772333820 100644 --- a/crates/test_utils/Cargo.toml +++ b/crates/test_utils/Cargo.toml @@ -16,7 +16,7 @@ rust.unused_crate_dependencies = "warn" [dependencies] anyhow = { version = "1.0.70" } -marzano-auth = { path = "../auth" } +marzano-auth = { path = "../auth", features = ["test-utils"] } assert_cmd = { version = "2.0.12" } tempfile = { version = "3.1" } fs_extra = { version = "1.3" }