Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove unrelated output from parse-sandboxed #1334

Merged
merged 6 commits into from
Jan 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions cli/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@ pub fn app() -> Command {
.value_name("FILE")
.help("Sets a custom config file")
.value_hint(ValueHint::FilePath),
Arg::new("no-config")
cd-work marked this conversation as resolved.
Show resolved Hide resolved
maxrake marked this conversation as resolved.
Show resolved Hide resolved
.long("no-config")
.help("Ignore all configuration files")
.conflicts_with("config")
.action(ArgAction::SetTrue),
Arg::new("timeout")
.short('t')
.long("timeout")
Expand Down
49 changes: 18 additions & 31 deletions cli/src/bin/phylum.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
use std::fmt::Display;
use std::path::{Path, PathBuf};
use std::time::UNIX_EPOCH;

use anyhow::{anyhow, Context, Result};
use anyhow::{Context, Result};
#[cfg(feature = "selfmanage")]
use clap::ArgMatches;
use env_logger::Env;
Expand Down Expand Up @@ -34,24 +33,21 @@ fn exit_fail(message: impl Display, exit_code: ExitCode) -> ! {

/// Construct an instance of `PhylumApi` given configuration, optional timeout,
/// and whether we need API to ignore certificates.
async fn api_factory(
config: Config,
config_path: PathBuf,
timeout: Option<u64>,
) -> Result<PhylumApi> {
async fn api_factory(config: Config, timeout: Option<u64>) -> Result<PhylumApi> {
let api = PhylumApi::new(config, timeout).await?;

// PhylumApi may have had to log in, updating the auth info so we should save
// the config
config::save_config(&config_path, api.config()).with_context(|| {
format!("Failed to save configuration to '{}'", config_path.to_string_lossy())
})?;
let api_config = api.config();
api_config
.save()
.with_context(|| format!("Failed to save configuration to {:?}", api_config.path))?;

Ok(api)
}

/// Check for an updated release of the CLI
async fn check_for_updates(config: &mut Config, config_path: &Path) -> Result<()> {
async fn check_for_updates(config: &mut Config) -> Result<()> {
let now = UNIX_EPOCH.elapsed().expect("Time went backwards").as_secs() as usize;

if let Some(last_update) = config.last_update {
Expand All @@ -66,8 +62,7 @@ async fn check_for_updates(config: &mut Config, config_path: &Path) -> Result<()

// Update last update check timestamp.
config.last_update = Some(now);
config::save_config(config_path, &config)
.unwrap_or_else(|e| log::error!("Failed to save config: {}", e));
config.save().unwrap_or_else(|e| log::error!("Failed to save config: {}", e));

if update::needs_update(false).await {
print::print_update_message();
Expand Down Expand Up @@ -104,41 +99,33 @@ async fn handle_commands() -> CommandResult {
None => env_logger::Builder::from_env(Env::default().default_filter_or("warn")).init(),
};

let settings_path = config::get_home_settings_path()?;
let config_path = matches
.get_one::<String>("config")
.and_then(|config_path| shellexpand::env(config_path).ok())
.map(|config_path| PathBuf::from(config_path.to_string()))
.unwrap_or(settings_path);

log::debug!("Reading config from {}", config_path.to_string_lossy());
let mut config: Config = config::read_configuration(&config_path).map_err(|err| {
anyhow!("Failed to read configuration at `{}`: {}", config_path.to_string_lossy(), err)
})?;
config.set_ignore_certs_cli(matches.get_flag("no-check-certificate"));
let mut config = config::load_config(&matches)?;

config.set_ignore_certs_cli(matches.get_flag("no-check-certificate"));
if config.ignore_certs() {
log::warn!("Ignoring TLS server certificate verification per user request.");
}

// We initialize these value here, for later use by the PhylumApi object.
let timeout = matches.get_one::<String>("timeout").and_then(|t| t.parse::<u64>().ok());

// Check for updates if enabled and if we haven't explicitly invoked `update`.
if cfg!(feature = "selfmanage") && matches.subcommand_matches("update").is_none() {
check_for_updates(&mut config, &config_path).await?;
let (subcommand, sub_matches) = matches.subcommand().unwrap();

// Check for updates unless we're running without config or the `update`
// subcommand.
if cfg!(feature = "selfmanage") && config.path.is_some() && subcommand != "update" {
check_for_updates(&mut config).await?;
}

// Get the future, but don't await. Commands that require access to the API will
// await on this, so that the API is not instantiated ahead of time for
// subcommands that don't require it.
let api = api_factory(config.clone(), config_path.clone(), timeout);
let api = api_factory(config.clone(), timeout);

let (subcommand, sub_matches) = matches.subcommand().unwrap();
match subcommand {
"auth" => {
drop(api);
auth::handle_auth(config, &config_path, sub_matches, timeout).await
auth::handle_auth(config, sub_matches, timeout).await
},
"version" => handle_version(&app_name, &ver),
"parse" => parse::handle_parse(sub_matches),
Expand Down
29 changes: 9 additions & 20 deletions cli/src/commands/auth.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use std::borrow::Cow;
use std::path::Path;

use anyhow::{anyhow, Context, Result};
use chrono::{Duration, Utc};
Expand All @@ -11,17 +10,13 @@ use tokio::io::{self, AsyncBufReadExt, BufReader};
use crate::api::PhylumApi;
use crate::auth::{is_locksmith_token, AuthAction};
use crate::commands::{CommandResult, ExitCode};
use crate::config::{save_config, Config};
use crate::config::Config;
use crate::format::Format;
use crate::{auth, print_user_failure, print_user_success, print_user_warning};

/// Register a user. Opens a browser, and redirects the user to the oauth server
/// registration page
async fn handle_auth_register(
mut config: Config,
config_path: &Path,
matches: &ArgMatches,
) -> Result<()> {
async fn handle_auth_register(mut config: Config, matches: &ArgMatches) -> Result<()> {
let api_uri = &config.connection.uri;
let ignore_certs = config.ignore_certs();
config.auth_info = PhylumApi::register(
Expand All @@ -31,17 +26,13 @@ async fn handle_auth_register(
api_uri,
)
.await?;
save_config(config_path, &config).map_err(|error| anyhow!(error))?;
config.save().map_err(|error| anyhow!(error))?;
Ok(())
}

/// Login a user. Opens a browser, and redirects the user to the oauth server
/// login page
async fn handle_auth_login(
mut config: Config,
config_path: &Path,
matches: &ArgMatches,
) -> Result<()> {
async fn handle_auth_login(mut config: Config, matches: &ArgMatches) -> Result<()> {
let api_uri = &config.connection.uri;
let ignore_certs = config.ignore_certs();
config.auth_info = PhylumApi::login(
Expand All @@ -52,7 +43,7 @@ async fn handle_auth_login(
matches.get_flag("reauth"),
)
.await?;
save_config(config_path, &config).map_err(|error| anyhow!(error))?;
config.save().map_err(|error| anyhow!(error))?;
Ok(())
}

Expand Down Expand Up @@ -133,14 +124,13 @@ async fn stdin_read_token() -> Result<RefreshToken> {
pub async fn handle_auth_set_token(
mut config: Config,
matches: &clap::ArgMatches,
config_path: &Path,
) -> CommandResult {
let offline_access = match matches.get_one::<String>("token") {
Some(t) => RefreshToken::new(t),
None => stdin_read_token().await?,
};
config.auth_info.set_offline_access(offline_access);
save_config(config_path, &config)?;
config.save()?;
Ok(ExitCode::Ok)
}

Expand Down Expand Up @@ -247,19 +237,18 @@ pub async fn handle_auth_create_token(
/// Handle the subcommands for the `auth` subcommand.
pub async fn handle_auth(
config: Config,
config_path: &Path,
matches: &clap::ArgMatches,
timeout: Option<u64>,
) -> CommandResult {
match matches.subcommand() {
Some(("register", _)) => match handle_auth_register(config, config_path, matches).await {
Some(("register", _)) => match handle_auth_register(config, matches).await {
Ok(_) => {
print_user_success!("{}", "User successfuly regsistered");
Ok(ExitCode::Ok)
},
Err(error) => Err(error).context("User registration failed"),
},
Some(("login", matches)) => match handle_auth_login(config, config_path, matches).await {
Some(("login", matches)) => match handle_auth_login(config, matches).await {
Ok(_) => {
print_user_success!("{}", "User login successful");
Ok(ExitCode::Ok)
Expand All @@ -268,7 +257,7 @@ pub async fn handle_auth(
},
Some(("status", _)) => handle_auth_status(config, timeout).await,
Some(("token", matches)) => handle_auth_token(&config, matches).await,
Some(("set-token", matches)) => handle_auth_set_token(config, matches, config_path).await,
Some(("set-token", matches)) => handle_auth_set_token(config, matches).await,
Some(("list-tokens", matches)) => handle_auth_list_tokens(config, matches, timeout).await,
Some(("revoke-token", matches)) => handle_auth_revoke_token(config, matches, timeout).await,
Some(("create-token", matches)) => handle_auth_create_token(config, matches, timeout).await,
Expand Down
1 change: 1 addition & 0 deletions cli/src/commands/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,7 @@ fn parse_sandboxed_command(
) -> Result<Command> {
let current_exe = env::current_exe()?;
let mut command = Command::new(current_exe);
command.arg("--no-config");

command.arg("parse-sandboxed");
command.arg(path);
Expand Down
42 changes: 40 additions & 2 deletions cli/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ use std::os::unix::fs::{DirBuilderExt, OpenOptionsExt};
use std::path::{Path, PathBuf};
use std::{env, fs};

use anyhow::{anyhow, Result};
use anyhow::{anyhow, Context, Result};
use clap::ArgMatches;
use phylum_project::{DepfileConfig, ProjectConfig};
use phylum_types::types::auth::RefreshToken;
use serde::{Deserialize, Deserializer, Serialize};
Expand Down Expand Up @@ -50,6 +51,8 @@ pub struct Config {
pub auth_info: AuthInfo,
pub last_update: Option<usize>,
#[serde(skip)]
pub path: Option<PathBuf>,
#[serde(skip)]
ignore_certs_cli: bool,
#[serde(deserialize_with = "default_option_bool")]
ignore_certs: bool,
Expand All @@ -63,6 +66,7 @@ impl Default for Config {
ignore_certs_cli: false,
ignore_certs: false,
last_update: None,
path: None,
}
}
}
Expand All @@ -77,6 +81,16 @@ impl Config {
pub fn set_ignore_certs_cli(&mut self, ignore_certs_cli: bool) {
self.ignore_certs_cli = ignore_certs_cli;
}

/// Write updates to the configuration file.
pub fn save(&self) -> Result<()> {
let path = match &self.path {
Some(path) => path,
None => return Ok(()),
};

save_config(path, self)
cd-work marked this conversation as resolved.
Show resolved Hide resolved
}
}

fn default_option_bool<'de, D>(deserializer: D) -> Result<bool, D::Error>
Expand All @@ -86,6 +100,29 @@ where
Ok(Option::<bool>::deserialize(deserializer)?.unwrap_or_default())
}

/// Load the configuration file.
pub fn load_config(matches: &ArgMatches) -> Result<Config> {
// Early return with configuration disabled.
if matches.get_flag("no-config") {
return Ok(Config::default());
}

let settings_path = get_home_settings_path()?;
let config_path = matches
.get_one::<String>("config")
.and_then(|config_path| shellexpand::env(config_path).ok())
.map(|config_path| PathBuf::from(config_path.to_string()))
.unwrap_or(settings_path);

log::debug!("Reading config from {}", config_path.to_string_lossy());
let mut config: Config = read_configuration(&config_path)
.with_context(|| anyhow!("Failed to read configuration at {:?}", config_path))?;

config.path = Some(config_path);

Ok(config)
}

/// Atomically overwrite the configuration file.
#[cfg(unix)]
pub fn save_config<T>(path: &Path, config: &T) -> Result<()>
Expand Down Expand Up @@ -151,7 +188,7 @@ where
Ok(serde_yaml::from_str::<T>(&contents)?)
}

pub fn read_configuration(path: &Path) -> Result<Config> {
fn read_configuration(path: &Path) -> Result<Config> {
let mut config: Config = match parse_config(path) {
Ok(c) => c,
Err(orig_err) => match orig_err.downcast_ref::<io::Error>() {
Expand Down Expand Up @@ -244,6 +281,7 @@ mod tests {
ignore_certs_cli: false,
ignore_certs: false,
last_update: None,
path: None,
}
}

Expand Down
3 changes: 3 additions & 0 deletions docs/commands/phylum.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ Usage: phylum [OPTIONS] [COMMAND]
`-c`, `--config` `<FILE>`
&emsp; Sets a custom config file

`--no-config`
&emsp; Ignore all configuration files

`-t`, `--timeout` `<TIMEOUT>`
&emsp; Set the timeout (in seconds) for requests to the Phylum api

Expand Down