mirror of
https://github.com/timvisee/ffsend.git
synced 2025-10-05 02:09:27 +02:00
Automatically derive owner tokens from history
This commit is contained in:
parent
f2336467a2
commit
77fb9c436d
8 changed files with 84 additions and 8 deletions
|
@ -1,11 +1,11 @@
|
||||||
# Release 0.1
|
# Release 0.1
|
||||||
|
- Sort history entries
|
||||||
|
- Panic when secret is missing from URL with info action
|
||||||
- History compiler flag
|
- History compiler flag
|
||||||
- Lowercase error messages
|
- Lowercase error messages
|
||||||
- Automatically get owner token, from file history when setting password
|
|
||||||
- Switch to `directories` instead of `app_dirs2`?
|
- Switch to `directories` instead of `app_dirs2`?
|
||||||
- Allow file/directory archiving on upload
|
- Allow file/directory archiving on upload
|
||||||
- Allow unarchiving on download
|
- Allow unarchiving on download
|
||||||
- Show a simplified command list when calling `ffsend` without arguments
|
|
||||||
- Use clipboard through `xclip` on Linux if available for persistence
|
- Use clipboard through `xclip` on Linux if available for persistence
|
||||||
- Allow environment variable settings using `Arg.env(NAME)`
|
- Allow environment variable settings using `Arg.env(NAME)`
|
||||||
- Automated releases through CI
|
- Automated releases through CI
|
||||||
|
@ -13,7 +13,12 @@
|
||||||
- Ubuntu PPA package
|
- Ubuntu PPA package
|
||||||
- Implement error handling everywhere properly
|
- Implement error handling everywhere properly
|
||||||
- Embed request errors
|
- Embed request errors
|
||||||
|
- Extract utility module
|
||||||
|
- Think of a new description:
|
||||||
|
Securely and easily share files from the command line;
|
||||||
|
a fully featured Firefox Send client.
|
||||||
- Check all TODOs, solve them when possible
|
- Check all TODOs, solve them when possible
|
||||||
|
- Windows, macOS and Redox support
|
||||||
|
|
||||||
# Future releases
|
# Future releases
|
||||||
- Color usage flag
|
- Color usage flag
|
||||||
|
|
|
@ -252,11 +252,20 @@ impl RemoteFile {
|
||||||
&mut self.owner_token
|
&mut self.owner_token
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set the owner token.
|
/// Set the owner token, wrapped in an option.
|
||||||
|
/// If `None` is given, the owner token will be unset.
|
||||||
pub fn set_owner_token(&mut self, token: Option<String>) {
|
pub fn set_owner_token(&mut self, token: Option<String>) {
|
||||||
self.owner_token = token;
|
self.owner_token = token;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Check whether an owner token is set in this remote file.
|
||||||
|
pub fn has_owner_token(&self) -> bool {
|
||||||
|
self.owner_token
|
||||||
|
.clone()
|
||||||
|
.map(|t| !t.is_empty())
|
||||||
|
.unwrap_or(false)
|
||||||
|
}
|
||||||
|
|
||||||
/// Get the host URL for this remote file.
|
/// Get the host URL for this remote file.
|
||||||
pub fn host(&self) -> Url {
|
pub fn host(&self) -> Url {
|
||||||
self.host.clone()
|
self.host.clone()
|
||||||
|
|
|
@ -44,8 +44,9 @@ impl<'a> Delete<'a> {
|
||||||
// Create a reqwest client
|
// Create a reqwest client
|
||||||
let client = Client::new();
|
let client = Client::new();
|
||||||
|
|
||||||
// Parse the remote file based on the share URL, get the owner token
|
// Parse the remote file based on the share URL, derive the owner token from history
|
||||||
let mut file = RemoteFile::parse_url(url, matcher_delete.owner())?;
|
let mut file = RemoteFile::parse_url(url, matcher_delete.owner())?;
|
||||||
|
history_tool::derive_owner_token(&matcher_main, &mut file);
|
||||||
|
|
||||||
// Ensure the owner token is set
|
// Ensure the owner token is set
|
||||||
ensure_owner_token(file.owner_token_mut(), &matcher_main);
|
ensure_owner_token(file.owner_token_mut(), &matcher_main);
|
||||||
|
|
|
@ -50,9 +50,9 @@ impl<'a> Info<'a> {
|
||||||
// Create a reqwest client
|
// Create a reqwest client
|
||||||
let client = Client::new();
|
let client = Client::new();
|
||||||
|
|
||||||
// Parse the remote file based on the share URL, get the password
|
// Parse the remote file based on the share URL, derive the owner token from history
|
||||||
let mut file = RemoteFile::parse_url(url, matcher_info.owner())?;
|
let mut file = RemoteFile::parse_url(url, matcher_info.owner())?;
|
||||||
let mut password = matcher_info.password();
|
history_tool::derive_owner_token(&matcher_main, &mut file);
|
||||||
|
|
||||||
// Ensure the owner token is set
|
// Ensure the owner token is set
|
||||||
ensure_owner_token(file.owner_token_mut(), &matcher_main);
|
ensure_owner_token(file.owner_token_mut(), &matcher_main);
|
||||||
|
@ -66,6 +66,9 @@ impl<'a> Info<'a> {
|
||||||
return Err(Error::Expired);
|
return Err(Error::Expired);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get the password
|
||||||
|
let mut password = matcher_info.password();
|
||||||
|
|
||||||
// Ensure a password is set when required
|
// Ensure a password is set when required
|
||||||
ensure_password(&mut password, exists.has_password(), &matcher_main);
|
ensure_password(&mut password, exists.has_password(), &matcher_main);
|
||||||
|
|
||||||
|
|
|
@ -42,8 +42,9 @@ impl<'a> Params<'a> {
|
||||||
// Create a reqwest client
|
// Create a reqwest client
|
||||||
let client = Client::new();
|
let client = Client::new();
|
||||||
|
|
||||||
// Parse the remote file based on the share URL
|
// Parse the remote file based on the share URL, derive the owner token from history
|
||||||
let mut file = RemoteFile::parse_url(url, matcher_params.owner())?;
|
let mut file = RemoteFile::parse_url(url, matcher_params.owner())?;
|
||||||
|
history_tool::derive_owner_token(&matcher_main, &mut file);
|
||||||
|
|
||||||
// Ensure the owner token is set
|
// Ensure the owner token is set
|
||||||
ensure_owner_token(file.owner_token_mut(), &matcher_main);
|
ensure_owner_token(file.owner_token_mut(), &matcher_main);
|
||||||
|
|
|
@ -41,8 +41,9 @@ impl<'a> Password<'a> {
|
||||||
// Create a reqwest client
|
// Create a reqwest client
|
||||||
let client = Client::new();
|
let client = Client::new();
|
||||||
|
|
||||||
// Parse the remote file based on the share URL
|
// Parse the remote file based on the share URL, derive the owner token from history
|
||||||
let mut file = RemoteFile::parse_url(url, matcher_password.owner())?;
|
let mut file = RemoteFile::parse_url(url, matcher_password.owner())?;
|
||||||
|
history_tool::derive_owner_token(&matcher_main, &mut file);
|
||||||
|
|
||||||
// Ensure the owner token is set
|
// Ensure the owner token is set
|
||||||
ensure_owner_token(file.owner_token_mut(), &matcher_main);
|
ensure_owner_token(file.owner_token_mut(), &matcher_main);
|
||||||
|
|
|
@ -198,6 +198,16 @@ impl History {
|
||||||
&self.files
|
&self.files
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get a file from the history, based on the given remote file.
|
||||||
|
/// The file ID and host will be compared against all files in this history.
|
||||||
|
/// If multiple files exist within the history that are equal, only one is returned.
|
||||||
|
/// If no matching file was found, `None` is returned.
|
||||||
|
pub fn get_file(&self, file: &RemoteFile) -> Option<&RemoteFile> {
|
||||||
|
self.files.iter()
|
||||||
|
.filter(|f| f.id() == file.id() && f.host() == file.host())
|
||||||
|
.next()
|
||||||
|
}
|
||||||
|
|
||||||
/// Garbage collect (remove) all files that have been expired,
|
/// Garbage collect (remove) all files that have been expired,
|
||||||
/// as defined by their `expire_at` property.
|
/// as defined by their `expire_at` property.
|
||||||
///
|
///
|
||||||
|
|
|
@ -78,3 +78,49 @@ pub fn remove(matcher_main: &MainMatcher, file: &RemoteFile) -> bool {
|
||||||
}
|
}
|
||||||
ok
|
ok
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Derive an owner token of a remote file from the current history.
|
||||||
|
/// The newly derived owner token will be set into the given borrowed remote file.
|
||||||
|
/// This method may be used to automatically derive the owner token for some file actions
|
||||||
|
/// requiring this token, to prevent the user from having to enter it manually.
|
||||||
|
///
|
||||||
|
/// If the file already has an owner token set,
|
||||||
|
/// nothing will be derived and `false` is returned.
|
||||||
|
/// If an error occurred while deriving,
|
||||||
|
/// the error is printed and `false` is returned.
|
||||||
|
/// If there was no matching file in the history,
|
||||||
|
/// and no owner token could be derived, `false` is returned.
|
||||||
|
/// If in incognito mode, nothing is derived and `false` is returned.
|
||||||
|
///
|
||||||
|
/// If an owner token was successfully derived from the history,
|
||||||
|
/// `true` is returned.
|
||||||
|
///
|
||||||
|
/// Note, to check if an owner token is set in the remote file,
|
||||||
|
/// use the `file.has_owner_token()` method instead of the returned boolean from this method.
|
||||||
|
pub fn derive_owner_token(matcher_main: &MainMatcher, file: &mut RemoteFile) -> bool {
|
||||||
|
// Return if the remote file already has an owner token set, or if we're incognito
|
||||||
|
if file.has_owner_token() || matcher_main.incognito() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load the history
|
||||||
|
let history = match History::load_or_new(matcher_main.history()) {
|
||||||
|
Ok(history) => history,
|
||||||
|
Err(err) => {
|
||||||
|
print_error(err.context(
|
||||||
|
"Failed to derive file owner token from history, ignoring",
|
||||||
|
));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Find a matching file, grab and set the owner token if available
|
||||||
|
match history.get_file(file) {
|
||||||
|
Some(f) if f.has_owner_token() => {
|
||||||
|
file.set_owner_token(f.owner_token().cloned());
|
||||||
|
println!("DEBUG: Owner token set from history");
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
_ => return false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue