diff --git a/src/bin/cargo.rs b/src/bin/cargo.rs index e92bcdbe5ff..bfd0740f92a 100644 --- a/src/bin/cargo.rs +++ b/src/bin/cargo.rs @@ -132,6 +132,7 @@ macro_rules! each_subcommand{ $mac!(update); $mac!(verify_project); $mac!(version); + $mac!(whoami); $mac!(yank); } } diff --git a/src/bin/whoami.rs b/src/bin/whoami.rs new file mode 100644 index 00000000000..2cb71500337 --- /dev/null +++ b/src/bin/whoami.rs @@ -0,0 +1,51 @@ +use cargo::ops; +use cargo::util::{CliResult, Config}; + +#[derive(Deserialize)] +pub struct Options { + flag_index: Option, + flag_verbose: u32, + flag_quiet: Option, + flag_color: Option, + flag_frozen: bool, + flag_locked: bool, + #[serde(rename = "flag_Z")] + flag_z: Vec, +} + +pub const USAGE: &'static str = " +Check if an api token exists locally and who it belongs to + +Usage: + cargo whoami [options] [] + +Options: + -h, --help Print this message + --index INDEX Registry index to search in + -v, --verbose ... Use verbose output (-vv very verbose/build.rs output) + -q, --quiet No output printed to stdout + --color WHEN Coloring: auto, always, never + --frozen Require Cargo.lock and cache are up to date + --locked Require Cargo.lock is up to date + -Z FLAG ... Unstable (nightly-only) flags to Cargo + +"; + +pub fn execute(options: Options, config: &mut Config) -> CliResult { + config.configure( + options.flag_verbose, + options.flag_quiet, + &options.flag_color, + options.flag_frozen, + options.flag_locked, + &options.flag_z, + )?; + + let Options { + flag_index: index, + .. + } = options; + + ops::registry_whoami(config, index)?; + Ok(()) +} diff --git a/src/cargo/ops/mod.rs b/src/cargo/ops/mod.rs index 0cd1ec718e0..49eacfc4e79 100644 --- a/src/cargo/ops/mod.rs +++ b/src/cargo/ops/mod.rs @@ -17,7 +17,7 @@ pub use self::lockfile::{load_pkg_lockfile, write_pkg_lockfile}; pub use self::cargo_test::{run_tests, run_benches, TestOptions}; pub use self::cargo_package::{package, PackageOpts}; pub use self::registry::{publish, registry_configuration, RegistryConfig}; -pub use self::registry::{registry_login, search, http_proxy_exists, http_handle}; +pub use self::registry::{registry_login, registry_whoami, search, http_proxy_exists, http_handle}; pub use self::registry::{modify_owners, yank, OwnersOptions, PublishOpts}; pub use self::cargo_fetch::fetch; pub use self::cargo_pkgid::pkgid; diff --git a/src/cargo/ops/registry.rs b/src/cargo/ops/registry.rs index 42ff2f87207..71f34bad4e8 100644 --- a/src/cargo/ops/registry.rs +++ b/src/cargo/ops/registry.rs @@ -296,6 +296,18 @@ pub fn registry_login(config: &Config, token: String) -> CargoResult<()> { config::save_credentials(config, token) } +pub fn registry_whoami(config: &Config, index: Option) -> CargoResult<()> { + let RegistryConfig { token, .. } = registry_configuration(config)?; + let (mut registry, _) = registry(config, token.clone(), index)?; + + match registry.whoami() { + Ok(user) => config.shell().status("Whoami", format!("Currently logged in as `{}`", user.login))?, + Err(e) => config.shell().status("Whoami", format!("{}", e))?, + }; + + Ok(()) +} + pub struct OwnersOptions { pub krate: Option, pub token: Option, diff --git a/src/crates-io/lib.rs b/src/crates-io/lib.rs index 910d51a3730..ecd4de11a68 100644 --- a/src/crates-io/lib.rs +++ b/src/crates-io/lib.rs @@ -116,6 +116,7 @@ pub struct Warnings { } #[derive(Deserialize)] struct R { ok: bool } +#[derive(Deserialize)] struct MeResponse { user: Option } #[derive(Deserialize)] struct OwnerResponse { ok: bool, msg: String } #[derive(Deserialize)] struct ApiErrorList { errors: Vec } #[derive(Deserialize)] struct ApiError { detail: String } @@ -256,6 +257,15 @@ impl Registry { Ok(()) } + pub fn whoami(&mut self) -> Result { + let body = self.get(String::from("/me"))?; + + match serde_json::from_str::(&body)?.user { + Some(user) => Ok(user), + _ => Err(Error::from_kind(ErrorKind::TokenMissing)) + } + } + fn put(&mut self, path: String, b: &[u8]) -> Result { self.handle.put(true)?; self.req(path, Some(b), Auth::Authorized)