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

Support login tokens for multiple registries #4680

Merged
merged 9 commits into from
Nov 1, 2017
27 changes: 17 additions & 10 deletions src/bin/login.rs
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ pub struct Options {
flag_locked: bool,
#[serde(rename = "flag_Z")]
flag_z: Vec<String>,
flag_registry: Option<String>,
}

pub const USAGE: &'static str = "
Expand All @@ -34,6 +35,7 @@ Options:
--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
--registry REGISTRY Registry to use

";

Expand All @@ -44,26 +46,31 @@ pub fn execute(options: Options, config: &mut Config) -> CliResult {
options.flag_frozen,
options.flag_locked,
&options.flag_z)?;
let token = match options.arg_token.clone() {
let token = match options.arg_token {
Some(token) => token,
None => {
let src = SourceId::crates_io(config)?;
let mut src = RegistrySource::remote(&src, config);
src.update()?;
let config = src.config()?.unwrap();
let host = options.flag_host.clone().unwrap_or(config.api.unwrap());
let host = match options.flag_registry {
Some(ref registry) => {
config.get_registry_index(registry)?
}
None => {
let src = SourceId::crates_io(config)?;
let mut src = RegistrySource::remote(&src, config);
src.update()?;
let config = src.config()?.unwrap();
options.flag_host.clone().unwrap_or(config.api.unwrap())
}
};
println!("please visit {}me and paste the API Token below", host);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm I think this should only get printed for the crates.io registry, right? We may not want to assume the layout of another registry per se just yet, and instead we could probably just return an error if no token was passed and --registry was passed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was wondering if the /me API should be required for publish, I am happy to switch to just return an error stating that the token should be provided.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah this is one where we haven't done much to sketch out the path towards "what does a custom registry need HTTP-wise", so I think it's ok to err on the side of caution for now and just return an error

let mut line = String::new();
let input = io::stdin();
input.lock().read_line(&mut line).chain_err(|| {
"failed to read stdin"
})?;
line
line.trim().to_string()
}
};

let token = token.trim().to_string();
ops::registry_login(config, token)?;
ops::registry_login(config, token, options.flag_registry)?;
Ok(())
}

3 changes: 3 additions & 0 deletions src/bin/owner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ pub struct Options {
flag_locked: bool,
#[serde(rename = "flag_Z")]
flag_z: Vec<String>,
flag_registry: Option<String>,
}

pub const USAGE: &'static str = "
Expand All @@ -37,6 +38,7 @@ Options:
--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
--registry REGISTRY Registry to use

This command will modify the owners for a package on the specified registry (or
default). Note that owners of a package can upload new versions, yank old
Expand All @@ -61,6 +63,7 @@ pub fn execute(options: Options, config: &mut Config) -> CliResult {
to_add: options.flag_add,
to_remove: options.flag_remove,
list: options.flag_list,
registry: options.flag_registry,
};
ops::modify_owners(config, &opts)?;
Ok(())
Expand Down
4 changes: 4 additions & 0 deletions src/bin/publish.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ pub struct Options {
flag_locked: bool,
#[serde(rename = "flag_Z")]
flag_z: Vec<String>,
flag_registry: Option<String>,
}

pub const USAGE: &'static str = "
Expand All @@ -46,6 +47,7 @@ Options:
--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
--registry REGISTRY Registry to publish to

";

Expand All @@ -67,6 +69,7 @@ pub fn execute(options: Options, config: &mut Config) -> CliResult {
flag_jobs: jobs,
flag_dry_run: dry_run,
flag_target: target,
flag_registry: registry,
..
} = options;

Expand Down Expand Up @@ -100,6 +103,7 @@ about this warning.";
target: target.as_ref().map(|t| &t[..]),
jobs: jobs,
dry_run: dry_run,
registry: registry,
})?;
Ok(())
}
5 changes: 4 additions & 1 deletion src/bin/search.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ pub struct Options {
arg_query: Vec<String>,
#[serde(rename = "flag_Z")]
flag_z: Vec<String>,
flag_registry: Option<String>,
}

pub const USAGE: &'static str = "
Expand All @@ -36,6 +37,7 @@ Options:
--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
--registry REGISTRY Registry to use
";

pub fn execute(options: Options, config: &mut Config) -> CliResult {
Expand All @@ -50,6 +52,7 @@ pub fn execute(options: Options, config: &mut Config) -> CliResult {
flag_host: host, // TODO: Depricated, remove
flag_limit: limit,
arg_query: query,
flag_registry: registry,
..
} = options;

Expand Down Expand Up @@ -77,6 +80,6 @@ about this warning.";
host
};

ops::search(&query.join("+"), config, index, cmp::min(100, limit.unwrap_or(10)) as u8)?;
ops::search(&query.join("+"), config, index, cmp::min(100, limit.unwrap_or(10)) as u8, registry)?;
Ok(())
}
5 changes: 4 additions & 1 deletion src/bin/yank.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ pub struct Options {
flag_locked: bool,
#[serde(rename = "flag_Z")]
flag_z: Vec<String>,
flag_registry: Option<String>,
}

pub static USAGE: &'static str = "
Expand All @@ -35,6 +36,7 @@ Options:
--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
--registry REGISTRY Registry to use

The yank command removes a previously pushed crate's version from the server's
index. This command does not delete any data, and the crate will still be
Expand All @@ -57,7 +59,8 @@ pub fn execute(options: Options, config: &mut Config) -> CliResult {
options.flag_vers,
options.flag_token,
options.flag_index,
options.flag_undo)?;
options.flag_undo,
options.flag_registry)?;
Ok(())
}

23 changes: 11 additions & 12 deletions src/cargo/core/source/source_id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ impl SourceId {
/// This is the main cargo registry by default, but it can be overridden in
/// a `.cargo/config`.
pub fn crates_io(config: &Config) -> CargoResult<SourceId> {
let cfg = ops::registry_configuration(config)?;
let cfg = ops::registry_configuration(config, None)?;
let url = if let Some(ref index) = cfg.index {
static WARNED: AtomicBool = ATOMIC_BOOL_INIT;
if !WARNED.swap(true, SeqCst) {
Expand All @@ -183,17 +183,16 @@ impl SourceId {
}

pub fn alt_registry(config: &Config, key: &str) -> CargoResult<SourceId> {
if let Some(index) = config.get_string(&format!("registries.{}.index", key))? {
let url = index.val.to_url()?;
Ok(SourceId {
inner: Arc::new(SourceIdInner {
kind: Kind::Registry,
canonical_url: git::canonicalize_url(&url)?,
url: url,
precise: None,
}),
})
} else { Err(format!("No index found for registry: `{}`", key).into()) }
let index = config.get_registry_index(key)?;
let url = index.to_url()?;
Ok(SourceId {
inner: Arc::new(SourceIdInner {
kind: Kind::Registry,
canonical_url: git::canonicalize_url(&url)?,
url: url,
precise: None,
}),
})
}

/// Get this source URL
Expand Down
79 changes: 58 additions & 21 deletions src/cargo/ops/registry.rs
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use core::dependency::Kind;
use core::manifest::ManifestMetadata;
use ops;
use sources::{RegistrySource};
use util::config::{self, Config};
use util::config::{self, Config, ConfigValue};
use util::paths;
use util::ToUrl;
use util::errors::{CargoError, CargoResult, CargoResultExt};
Expand All @@ -36,6 +36,7 @@ pub struct PublishOpts<'cfg> {
pub jobs: Option<u32>,
pub target: Option<&'cfg str>,
pub dry_run: bool,
pub registry: Option<String>,
}

pub fn publish(ws: &Workspace, opts: &PublishOpts) -> CargoResult<()> {
Expand All @@ -51,7 +52,8 @@ pub fn publish(ws: &Workspace, opts: &PublishOpts) -> CargoResult<()> {

let (mut registry, reg_id) = registry(opts.config,
opts.token.clone(),
opts.index.clone())?;
opts.index.clone(),
opts.registry.clone())?;
verify_dependencies(pkg, &reg_id)?;

// Prepare a tarball, with a non-surpressable warning if metadata
Expand Down Expand Up @@ -189,24 +191,48 @@ fn transmit(config: &Config,
}
}

pub fn registry_configuration(config: &Config) -> CargoResult<RegistryConfig> {
let index = config.get_string("registry.index")?.map(|p| p.val);
let token = config.get_string("registry.token")?.map(|p| p.val);
Ok(RegistryConfig { index: index, token: token })
pub fn registry_configuration(config: &Config,
registry: Option<String>) -> CargoResult<RegistryConfig> {

let (index, token) = match registry {
Some(registry) => {
let index = Some(config.get_registry_index(&registry)?);
let table = config.get_table(&format!("registry.{}", registry))?.map(|t| t.val);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could this use get_string perhaps? That'll allow overrides via env var (table support isn't implemented there yet)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did originally try using get_string, but that caused problems if there was a '.' in the registry name (which I think is allowed). I will have a play and see if I can get something working.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Turns out it does just work switching to get_string, so I have made the change.

let token = table.and_then(|table| {
match table.get("token".into()) {
Some(&ConfigValue::String(ref i, _)) => Some(i.to_string()),
_ => None,
}
});

(index, token)
}
None => {
// Checking out for default index and token
(config.get_string("registry.index")?.map(|p| p.val),
config.get_string("registry.token")?.map(|p| p.val))
}
};

Ok(RegistryConfig {
index: index,
token: token
})
}

pub fn registry(config: &Config,
token: Option<String>,
index: Option<String>) -> CargoResult<(Registry, SourceId)> {
index: Option<String>,
registry: Option<String>) -> CargoResult<(Registry, SourceId)> {
// Parse all configuration options
let RegistryConfig {
token: token_config,
index: _index_config,
} = registry_configuration(config)?;
index: index_config,
} = registry_configuration(config, registry.clone())?;
let token = token.or(token_config);
let sid = match index {
Some(index) => SourceId::for_registry(&index.to_url()?)?,
None => SourceId::crates_io(config)?,
let sid = match (index_config, index) {
(Some(index), _) | (None, Some(index)) => SourceId::for_registry(&index.to_url()?)?,
(None, None) => SourceId::crates_io(config)?,
};
let api_host = {
let mut src = RegistrySource::remote(&sid, config);
Expand Down Expand Up @@ -293,15 +319,21 @@ pub fn http_timeout(config: &Config) -> CargoResult<Option<i64>> {
Ok(env::var("HTTP_TIMEOUT").ok().and_then(|s| s.parse().ok()))
}

pub fn registry_login(config: &Config, token: String) -> CargoResult<()> {
let RegistryConfig { token: old_token, .. } = registry_configuration(config)?;
pub fn registry_login(config: &Config,
token: String,
registry: Option<String>) -> CargoResult<()> {
let RegistryConfig {
token: old_token,
..
} = registry_configuration(config, registry.clone())?;

if let Some(old_token) = old_token {
if old_token == token {
return Ok(());
}
}

config::save_credentials(config, token)
config::save_credentials(config, token, registry)
}

pub struct OwnersOptions {
Expand All @@ -311,6 +343,7 @@ pub struct OwnersOptions {
pub to_add: Option<Vec<String>>,
pub to_remove: Option<Vec<String>>,
pub list: bool,
pub registry: Option<String>,
}

pub fn modify_owners(config: &Config, opts: &OwnersOptions) -> CargoResult<()> {
Expand All @@ -323,8 +356,10 @@ pub fn modify_owners(config: &Config, opts: &OwnersOptions) -> CargoResult<()> {
}
};

let (mut registry, _) = registry(config, opts.token.clone(),
opts.index.clone())?;
let (mut registry, _) = registry(config,
opts.token.clone(),
opts.index.clone(),
opts.registry.clone())?;

if let Some(ref v) = opts.to_add {
let v = v.iter().map(|s| &s[..]).collect::<Vec<_>>();
Expand Down Expand Up @@ -367,7 +402,8 @@ pub fn yank(config: &Config,
version: Option<String>,
token: Option<String>,
index: Option<String>,
undo: bool) -> CargoResult<()> {
undo: bool,
reg: Option<String>) -> CargoResult<()> {
let name = match krate {
Some(name) => name,
None => {
Expand All @@ -381,7 +417,7 @@ pub fn yank(config: &Config,
None => bail!("a version must be specified to yank")
};

let (mut registry, _) = registry(config, token, index)?;
let (mut registry, _) = registry(config, token, index, reg)?;

if undo {
config.shell().status("Unyank", format!("{}:{}", name, version))?;
Expand All @@ -401,7 +437,8 @@ pub fn yank(config: &Config,
pub fn search(query: &str,
config: &Config,
index: Option<String>,
limit: u8) -> CargoResult<()> {
limit: u8,
reg: Option<String>) -> CargoResult<()> {
fn truncate_with_ellipsis(s: &str, max_length: usize) -> String {
if s.len() < max_length {
s.to_string()
Expand All @@ -410,7 +447,7 @@ pub fn search(query: &str,
}
}

let (mut registry, _) = registry(config, None, index)?;
let (mut registry, _) = registry(config, None, index, reg)?;
let (crates, total_crates) = registry.search(query, limit).map_err(|e| {
CargoError::from(format!("failed to retrieve search results from the registry: {}", e))
})?;
Expand Down
Loading