Support optional passwords as well for info command
This commit is contained in:
parent
ff93b13b22
commit
e1d0ddee0d
4 changed files with 98 additions and 29 deletions
|
@ -76,7 +76,12 @@ impl<'a> Download<'a> {
|
|||
}
|
||||
|
||||
// Ensure a password is set when required
|
||||
ensure_password(&mut password, exists.requires_password(), &matcher_main);
|
||||
ensure_password(
|
||||
&mut password,
|
||||
exists.requires_password(),
|
||||
&matcher_main,
|
||||
false,
|
||||
);
|
||||
|
||||
// Fetch the file metadata
|
||||
let metadata = ApiMetadata::new(&file, password.clone(), false).invoke(&client)?;
|
||||
|
|
|
@ -59,7 +59,12 @@ impl<'a> Info<'a> {
|
|||
|
||||
// Get the password, ensure the password is set when required
|
||||
let mut password = matcher_info.password();
|
||||
ensure_password(&mut password, exists.requires_password(), &matcher_main);
|
||||
let has_password = ensure_password(
|
||||
&mut password,
|
||||
exists.requires_password(),
|
||||
&matcher_main,
|
||||
true,
|
||||
);
|
||||
|
||||
// Fetch both file info and metadata
|
||||
let info = if has_owner {
|
||||
|
@ -67,12 +72,16 @@ impl<'a> Info<'a> {
|
|||
} else {
|
||||
None
|
||||
};
|
||||
let metadata = ApiMetadata::new(&file, password, false)
|
||||
.invoke(&client)
|
||||
.map_err(|err| {
|
||||
print_error(err.context("failed to fetch file metadata, showing limited info"))
|
||||
})
|
||||
.ok();
|
||||
let metadata = if has_password {
|
||||
ApiMetadata::new(&file, password, false)
|
||||
.invoke(&client)
|
||||
.map_err(|err| {
|
||||
print_error(err.context("failed to fetch file metadata, showing limited info"))
|
||||
})
|
||||
.ok()
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
// Update history file TTL if info is known
|
||||
if let Some(info) = &info {
|
||||
|
@ -92,7 +101,7 @@ impl<'a> Info<'a> {
|
|||
// Add the ID
|
||||
table.add_row(Row::new(vec![Cell::new("ID:"), Cell::new(file.id())]));
|
||||
|
||||
// Metadata related details
|
||||
// Show file metadata if available
|
||||
if let Some(metadata) = &metadata {
|
||||
// The file name
|
||||
table.add_row(Row::new(vec![
|
||||
|
@ -118,8 +127,9 @@ impl<'a> Info<'a> {
|
|||
]));
|
||||
}
|
||||
|
||||
// The download count
|
||||
// Show file info if available
|
||||
if let Some(info) = &info {
|
||||
// The download count
|
||||
table.add_row(Row::new(vec![
|
||||
Cell::new("Downloads:"),
|
||||
Cell::new(&format!(
|
||||
|
|
|
@ -40,7 +40,7 @@ impl<'a> CmdArgOption<'a> for ArgPassword {
|
|||
// Get the password argument value, or prompt
|
||||
let password = match Self::value_raw(matches) {
|
||||
Some(password) => password.into(),
|
||||
None => prompt_password(&matcher_main),
|
||||
None => prompt_password(&matcher_main, false).unwrap(),
|
||||
};
|
||||
|
||||
// Check for empty passwords
|
||||
|
|
90
src/util.rs
90
src/util.rs
|
@ -376,9 +376,9 @@ pub fn check_empty_password(password: &str, matcher_main: &MainMatcher) {
|
|||
/// Prompt the user to enter a password.
|
||||
///
|
||||
/// If `empty` is `false`, emtpy passwords aren't allowed unless forced.
|
||||
pub fn prompt_password(main_matcher: &MainMatcher) -> String {
|
||||
pub fn prompt_password(main_matcher: &MainMatcher, optional: bool) -> Option<String> {
|
||||
// Quit with an error if we may not interact
|
||||
if main_matcher.no_interact() {
|
||||
if !optional && main_matcher.no_interact() {
|
||||
quit_error_msg(
|
||||
"missing password, must be specified in no-interact mode",
|
||||
ErrorHintsBuilder::default()
|
||||
|
@ -390,35 +390,89 @@ pub fn prompt_password(main_matcher: &MainMatcher) -> String {
|
|||
}
|
||||
|
||||
// Prompt for the password
|
||||
match prompt_password_stderr("Password: ") {
|
||||
Ok(password) => password,
|
||||
Err(err) => quit_error(
|
||||
err.context("failed to read password from password prompt"),
|
||||
ErrorHints::default(),
|
||||
),
|
||||
let prompt = if optional {
|
||||
"Password (optional): "
|
||||
} else {
|
||||
"Password: "
|
||||
};
|
||||
match prompt_password_stderr(prompt) {
|
||||
// If optional and nothing is entered, regard it as not defined
|
||||
Ok(password) => {
|
||||
if password.is_empty() && optional {
|
||||
None
|
||||
} else {
|
||||
Some(password)
|
||||
}
|
||||
}
|
||||
|
||||
// On input error, propegate the error or don't use a password if optional
|
||||
Err(err) => {
|
||||
if !optional {
|
||||
quit_error(
|
||||
err.context("failed to read password from password prompt"),
|
||||
ErrorHints::default(),
|
||||
)
|
||||
} else {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Get a password if required.
|
||||
/// This method will ensure a password is set (or not) in the given `password`
|
||||
/// parameter, as defined by `needs`.
|
||||
/// If a password is needed, it may optionally be entered if `option` is set to true.
|
||||
///
|
||||
/// This method will prompt the user for a password, if one is required but
|
||||
/// wasn't set. An ignore message will be shown if it was not required while it
|
||||
/// was set.
|
||||
pub fn ensure_password(password: &mut Option<String>, needs: bool, main_matcher: &MainMatcher) {
|
||||
// Return if we're fine
|
||||
///
|
||||
/// Returns true if a password is now set, false if not.
|
||||
pub fn ensure_password(
|
||||
password: &mut Option<String>,
|
||||
needs: bool,
|
||||
main_matcher: &MainMatcher,
|
||||
optional: bool,
|
||||
) -> bool {
|
||||
// Return if we're fine, ignore if set but we don't need it
|
||||
if password.is_some() == needs {
|
||||
return;
|
||||
return needs;
|
||||
}
|
||||
if !needs {
|
||||
// Notify the user a set password is ignored
|
||||
if password.is_some() {
|
||||
println!("Ignoring password, it is not required");
|
||||
*password = None;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Prompt for the password, or clear it if not required
|
||||
if needs {
|
||||
println!("This file is protected with a password.");
|
||||
*password = Some(prompt_password(main_matcher));
|
||||
} else {
|
||||
println!("Ignoring password, it is not required");
|
||||
*password = None;
|
||||
// Check whehter we allow interaction
|
||||
let interact = !main_matcher.no_interact();
|
||||
|
||||
loop {
|
||||
// Prompt for an owner token if not set yet
|
||||
if password.is_none() {
|
||||
// Do not ask for a token if optional when non-interactive or forced
|
||||
if optional && (!interact || main_matcher.force()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Ask for the password
|
||||
*password = prompt_password(main_matcher, optional);
|
||||
}
|
||||
|
||||
// The token must not be empty, unless it's optional
|
||||
let empty = password.is_none();
|
||||
if empty && !optional {
|
||||
eprintln!(
|
||||
"No password given, which is required. Use {} to cancel.",
|
||||
highlight("[CTRL+C]"),
|
||||
);
|
||||
} else {
|
||||
return !empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue