message: Add support for printing api token email on `whoami`
  query the same api endpoint as we do with the global token, but now with the api token
  return errors, print helpful statement if the api token doesn't have the right permission
  Closes
diff: 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 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.
  + // 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: String = fetch_api_token_email(user)?;
  +
  + if token_auth_email == "" {
  + "an API Token".to_string()
  + } else {
  + format!(
  + "an API Token, associated with the email '{}'",
  + token_auth_email,
  + )
  + }
  + }
  };
  println!("\n{} You are logged in with {}.\n", emoji::WAVING, auth,);
  @@ -23,6 +36,26 @@ pub fn whoami(user: &GlobalUser) -> Result<(), failure::Error> {
  Ok(())
  }
  +fn fetch_api_token_email(user: &GlobalUser) -> Result<String, failure::Error> {
  + let client = http::cf_v4_client(user)?;
  + let response = client.request(&GetUserDetails {});
  + match response {
  + Ok(res) => Ok(res.result.email),
  + Err(e) => match e {
  + ApiFailure::Error(_, api_errors) => {
  + let error = &api_errors.errors[0];
  + if error.code == 9109 {
  + message::info("Your token is missing the 'User Details: Read' permission.\n\nPlease generate and auth with a new token that has these perms to be able to identify this token.\n");
  + Ok("".to_string())
  + } else {
  + Ok("".to_string())
  + }
  + }
  + 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 });
  @@ -39,7 +72,7 @@ fn format_accounts(user: &GlobalUser, accounts: Vec<Account>) -> Table {
  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");
  + message::info("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");
  }
  }
  