Skip to content
This repository has been archived by the owner on Aug 3, 2023. It is now read-only.

Add support for printing api token email on whoami #1212

Merged
merged 5 commits into from
Apr 22, 2020
Merged
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
78 changes: 70 additions & 8 deletions src/commands/whoami/mod.rs
Original file line number Diff line number Diff line change
@@ -1,28 +1,86 @@
use crate::http;
use crate::settings::global_user::GlobalUser;
use crate::terminal::emoji;
use crate::terminal::{emoji, message};

use cloudflare::endpoints::account::{self, Account};
use cloudflare::endpoints::user::GetUserDetails;
use cloudflare::framework::apiclient::ApiClient;
use cloudflare::framework::response::ApiFailure;

use console::Style;
use prettytable::{Cell, Row, Table};

pub fn whoami(user: &GlobalUser) -> Result<(), failure::Error> {
// If using email + API key for auth, simply prints out email from config file.
let mut missing_permissions: Vec<String> = Vec::with_capacity(2);
// Attempt to print email for both GlobalKeyAuth and TokenAuth users
let auth: String = match user {
GlobalUser::GlobalKeyAuth { email, .. } => {
format!("a Global API Key, associated with the email '{}'", email,)
}
GlobalUser::TokenAuth { .. } => "an API Token".to_string(),
GlobalUser::TokenAuth { .. } => {
let token_auth_email = fetch_api_token_email(user, &mut missing_permissions)?;

if let Some(token_auth_email) = token_auth_email {
format!(
"an API Token, associated with the email '{}'",
token_auth_email,
)
} else {
"an API Token".to_string()
}
}
};

println!("\n{} You are logged in with {}.\n", emoji::WAVING, auth,);
let accounts = fetch_accounts(user)?;
let table = format_accounts(user, accounts);
println!("{}", &table);
let table = format_accounts(user, accounts, &mut missing_permissions);
let mut msg = format!("{} You are logged in with {}!\n", emoji::WAVING, auth);
let num_permissions_missing = missing_permissions.len();
if num_permissions_missing > 0 {
let bold_yellow = Style::new().bold().yellow();
let config_msg = bold_yellow.apply_to("`wrangler config`");
let whoami_msg = bold_yellow.apply_to("`wrangler whoami`");
if missing_permissions.len() == 1 {
msg.push_str(&format!(
"\nYour token is missing the '{}' permission.",
bold_yellow.apply_to(missing_permissions.get(0).unwrap())
));
} else if missing_permissions.len() == 2 {
msg.push_str(&format!(
"\nYour token is missing the '{}' and '{}' permissions.",
bold_yellow.apply_to(missing_permissions.get(0).unwrap()),
bold_yellow.apply_to(missing_permissions.get(1).unwrap())
));
}
msg.push_str(&format!("\n\nPlease generate a new token and authenticate with {}\nfor more information when running {}", config_msg, whoami_msg));
}
message::billboard(&msg);
if table.len() > 1 {
println!("{}", &table);
}
Ok(())
}

fn fetch_api_token_email(
user: &GlobalUser,
missing_permissions: &mut Vec<String>,
) -> Result<Option<String>, failure::Error> {
let client = http::cf_v4_client(user)?;
let response = client.request(&GetUserDetails {});
match response {
Ok(res) => Ok(Some(res.result.email)),
Err(e) => match e {
ApiFailure::Error(_, api_errors) => {
let error = &api_errors.errors[0];
if error.code == 9109 {
missing_permissions.push("User Details: Read".to_string());
}
Ok(None)
}
ApiFailure::Invalid(_) => failure::bail!(http::format_error(e, None)),
},
}
}

fn fetch_accounts(user: &GlobalUser) -> Result<Vec<Account>, failure::Error> {
let client = http::cf_v4_client(user)?;
let response = client.request(&account::ListAccounts { params: None });
Expand All @@ -32,14 +90,18 @@ fn fetch_accounts(user: &GlobalUser) -> Result<Vec<Account>, failure::Error> {
}
}

fn format_accounts(user: &GlobalUser, accounts: Vec<Account>) -> Table {
fn format_accounts(
user: &GlobalUser,
accounts: Vec<Account>,
missing_permissions: &mut Vec<String>,
) -> Table {
let mut table = Table::new();
let table_head = Row::new(vec![Cell::new("Account Name"), Cell::new("Account ID")]);
table.add_row(table_head);

if let GlobalUser::TokenAuth { .. } = user {
if accounts.is_empty() {
println!("Your token is missing the 'Account Settings: Read' permission.\n\nPlease generate and auth with a new token that has these perms to be able to list your accounts.\n");
missing_permissions.push("Account Settings: Read".to_string());
}
}

Expand Down