mirror of
https://github.com/timvisee/ffsend.git
synced 2025-10-03 17:49:15 +02:00
Check for expired files everywehere, propogate their errors
This commit is contained in:
parent
7526bdb5a3
commit
cb2d5f7844
8 changed files with 159 additions and 58 deletions
|
@ -37,7 +37,9 @@ impl<'a> Delete<'a> {
|
|||
|
||||
// Create owned data, to send to the server for authentication
|
||||
let data = OwnedData::from(DeleteData::new(), &self.file)
|
||||
.map_err(|err| -> PrepareError { err.into() })?;
|
||||
.map_err(|err| PrepareError::DeleteData(
|
||||
DeleteDataError::Owned(err),
|
||||
))?;
|
||||
|
||||
// Send the delete request
|
||||
self.request_delete(client, data).map_err(|err| err.into())
|
||||
|
@ -45,12 +47,12 @@ impl<'a> Delete<'a> {
|
|||
|
||||
/// Fetch the authentication nonce for the file from the remote server.
|
||||
fn fetch_auth_nonce(&self, client: &Client)
|
||||
-> Result<Vec<u8>, PrepareError>
|
||||
-> Result<Vec<u8>, Error>
|
||||
{
|
||||
request_nonce(
|
||||
client,
|
||||
UrlBuilder::download(self.file, false),
|
||||
).map_err(|err| PrepareError::Auth(err))
|
||||
).map_err(|err| err.into())
|
||||
}
|
||||
|
||||
/// Send a request to delete the remote file, with the given data.
|
||||
|
@ -58,7 +60,7 @@ impl<'a> Delete<'a> {
|
|||
&self,
|
||||
client: &Client,
|
||||
data: OwnedData<DeleteData>,
|
||||
) -> Result<(), DeleteError> {
|
||||
) -> Result<(), Error> {
|
||||
// Get the delete URL, and send the request
|
||||
let url = UrlBuilder::api_delete(self.file);
|
||||
let response = client.post(url)
|
||||
|
@ -68,7 +70,7 @@ impl<'a> Delete<'a> {
|
|||
|
||||
// Ensure the status code is succesful
|
||||
ensure_success(&response)
|
||||
.map_err(|err| DeleteError::Response(err))
|
||||
.map_err(|err| err.into())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -91,16 +93,25 @@ pub enum Error {
|
|||
#[fail(display = "Failed to prepare the action")]
|
||||
Prepare(#[cause] PrepareError),
|
||||
|
||||
// /// The given Send file has expired, or did never exist in the first place.
|
||||
// /// Therefore the file could not be downloaded.
|
||||
// #[fail(display = "The file has expired or did never exist")]
|
||||
// Expired,
|
||||
/// The given Send file has expired, or did never exist in the first place.
|
||||
/// Therefore the file could not be downloaded.
|
||||
#[fail(display = "The file has expired or did never exist")]
|
||||
Expired,
|
||||
|
||||
/// An error has occurred while sending the filedeletion request.
|
||||
#[fail(display = "Failed to send the file deletion request")]
|
||||
Delete(#[cause] DeleteError),
|
||||
}
|
||||
|
||||
impl From<NonceError> for Error {
|
||||
fn from(err: NonceError) -> Error {
|
||||
match err {
|
||||
NonceError::Expired => Error::Expired,
|
||||
err => Error::Prepare(PrepareError::Auth(err)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<PrepareError> for Error {
|
||||
fn from(err: PrepareError) -> Error {
|
||||
Error::Prepare(err)
|
||||
|
@ -134,12 +145,6 @@ pub enum PrepareError {
|
|||
DeleteData(#[cause] DeleteDataError),
|
||||
}
|
||||
|
||||
impl From<DataError> for PrepareError {
|
||||
fn from(err: DataError) -> PrepareError {
|
||||
PrepareError::DeleteData(DeleteDataError::Owned(err))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Fail, Debug)]
|
||||
pub enum DeleteError {
|
||||
/// Sending the file deletion request failed.
|
||||
|
@ -150,3 +155,12 @@ pub enum DeleteError {
|
|||
#[fail(display = "Bad response from server while deleting file")]
|
||||
Response(#[cause] ResponseError),
|
||||
}
|
||||
|
||||
impl From<ResponseError> for Error {
|
||||
fn from(err: ResponseError) -> Self {
|
||||
match err {
|
||||
ResponseError::Expired => Error::Expired,
|
||||
err => Error::Delete(DeleteError::Response(err)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -81,12 +81,7 @@ impl<'a> Download<'a> {
|
|||
self.password.clone(),
|
||||
self.check_exists,
|
||||
)
|
||||
.invoke(&client)
|
||||
.map_err(|err| match err {
|
||||
MetadataError::PasswordRequired => Error::PasswordRequired,
|
||||
MetadataError::Expired => Error::Expired,
|
||||
_ => err.into(),
|
||||
})?
|
||||
.invoke(&client)?
|
||||
};
|
||||
key.set_iv(metadata.metadata().iv());
|
||||
|
||||
|
@ -149,6 +144,7 @@ impl<'a> Download<'a> {
|
|||
return self.target.clone();
|
||||
}
|
||||
|
||||
// TODO: are these todos below already implemented in CLI client?
|
||||
// TODO: canonicalize the path when possible
|
||||
// TODO: allow using `file.toml` as target without directory indication
|
||||
// TODO: return a nice error here as the path may be invalid
|
||||
|
@ -235,7 +231,8 @@ impl<'a> Download<'a> {
|
|||
.start(len);
|
||||
|
||||
// Write to the output file
|
||||
io::copy(&mut reader, &mut writer).map_err(|_| DownloadError::Download)?;
|
||||
io::copy(&mut reader, &mut writer)
|
||||
.map_err(|_| DownloadError::Download)?;
|
||||
|
||||
// Finish
|
||||
reporter.lock()
|
||||
|
@ -284,7 +281,11 @@ pub enum Error {
|
|||
|
||||
impl From<MetadataError> for Error {
|
||||
fn from(err: MetadataError) -> Error {
|
||||
Error::Meta(err)
|
||||
match err {
|
||||
MetadataError::Expired => Error::Expired,
|
||||
MetadataError::PasswordRequired => Error::PasswordRequired,
|
||||
err => Error::Meta(err),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -50,12 +50,12 @@ impl<'a> Info<'a> {
|
|||
|
||||
/// Fetch the authentication nonce for the file from the remote server.
|
||||
fn fetch_auth_nonce(&self, client: &Client)
|
||||
-> Result<Vec<u8>, PrepareError>
|
||||
-> Result<Vec<u8>, Error>
|
||||
{
|
||||
request_nonce(
|
||||
client,
|
||||
UrlBuilder::download(self.file, false),
|
||||
).map_err(|err| PrepareError::Auth(err))
|
||||
).map_err(|err| err.into())
|
||||
}
|
||||
|
||||
/// Send the request for fetching the remote file info.
|
||||
|
@ -63,7 +63,7 @@ impl<'a> Info<'a> {
|
|||
&self,
|
||||
client: &Client,
|
||||
data: OwnedData<InfoData>,
|
||||
) -> Result<InfoResponse, InfoError> {
|
||||
) -> Result<InfoResponse, Error> {
|
||||
// Get the info URL, and send the request
|
||||
let url = UrlBuilder::api_info(self.file);
|
||||
let mut response = client.post(url)
|
||||
|
@ -72,13 +72,12 @@ impl<'a> Info<'a> {
|
|||
.map_err(|_| InfoError::Request)?;
|
||||
|
||||
// Ensure the response is successful
|
||||
ensure_success(&response)
|
||||
.map_err(|err| InfoError::Response(err))?;
|
||||
ensure_success(&response)?;
|
||||
|
||||
// Decode the JSON response
|
||||
let response: InfoResponse = match response.json() {
|
||||
Ok(response) => response,
|
||||
Err(err) => return Err(InfoError::Decode(err)),
|
||||
Err(err) => return Err(InfoError::Decode(err).into()),
|
||||
};
|
||||
|
||||
Ok(response)
|
||||
|
@ -143,22 +142,40 @@ pub enum Error {
|
|||
#[fail(display = "Failed to prepare the action")]
|
||||
Prepare(#[cause] PrepareError),
|
||||
|
||||
// /// The given Send file has expired, or did never exist in the first place.
|
||||
// /// Therefore the file could not be downloaded.
|
||||
// #[fail(display = "The file has expired or did never exist")]
|
||||
// Expired,
|
||||
/// The given Send file has expired, or did never exist in the first place.
|
||||
/// Therefore the file could not be downloaded.
|
||||
#[fail(display = "The file has expired or did never exist")]
|
||||
Expired,
|
||||
|
||||
/// An error has occurred while sending the info request to the server.
|
||||
#[fail(display = "Failed to send the file info request")]
|
||||
Info(#[cause] InfoError),
|
||||
}
|
||||
|
||||
impl From<NonceError> for Error {
|
||||
fn from(err: NonceError) -> Error {
|
||||
match err {
|
||||
NonceError::Expired => Error::Expired,
|
||||
err => Error::Prepare(PrepareError::Auth(err)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<PrepareError> for Error {
|
||||
fn from(err: PrepareError) -> Error {
|
||||
Error::Prepare(err)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ResponseError> for Error {
|
||||
fn from(err: ResponseError) -> Error {
|
||||
match err {
|
||||
ResponseError::Expired => Error::Expired,
|
||||
err => Error::Info(InfoError::Response(err)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<InfoError> for Error {
|
||||
fn from(err: InfoError) -> Error {
|
||||
Error::Info(err)
|
||||
|
|
|
@ -74,12 +74,12 @@ impl<'a> Metadata<'a> {
|
|||
|
||||
/// Fetch the authentication nonce for the file from the remote server.
|
||||
fn fetch_auth_nonce(&self, client: &Client)
|
||||
-> Result<Vec<u8>, RequestError>
|
||||
-> Result<Vec<u8>, Error>
|
||||
{
|
||||
request_nonce(
|
||||
client,
|
||||
UrlBuilder::download(self.file, false),
|
||||
).map_err(|err| RequestError::Auth(err))
|
||||
).map_err(|err| err.into())
|
||||
}
|
||||
|
||||
/// Create a metadata nonce, and fetch the metadata for the file from the
|
||||
|
@ -235,6 +235,15 @@ impl From<MetaError> for Error {
|
|||
}
|
||||
}
|
||||
|
||||
impl From<NonceError> for Error {
|
||||
fn from(err: NonceError) -> Error {
|
||||
match err {
|
||||
NonceError::Expired => Error::Expired,
|
||||
err => Error::Request(RequestError::Auth(err)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Fail, Debug)]
|
||||
pub enum RequestError {
|
||||
/// Failed authenticating, in order to fetch the file data.
|
||||
|
|
|
@ -67,12 +67,12 @@ impl<'a> Params<'a> {
|
|||
|
||||
/// Fetch the authentication nonce for the file from the remote server.
|
||||
fn fetch_auth_nonce(&self, client: &Client)
|
||||
-> Result<Vec<u8>, PrepareError>
|
||||
-> Result<Vec<u8>, Error>
|
||||
{
|
||||
request_nonce(
|
||||
client,
|
||||
UrlBuilder::download(self.file, false),
|
||||
).map_err(|err| PrepareError::Auth(err))
|
||||
).map_err(|err| err.into())
|
||||
}
|
||||
|
||||
/// Send the request for changing the parameters.
|
||||
|
@ -80,7 +80,7 @@ impl<'a> Params<'a> {
|
|||
&self,
|
||||
client: &Client,
|
||||
data: OwnedData<ParamsData>,
|
||||
) -> Result<(), ChangeError> {
|
||||
) -> Result<(), Error> {
|
||||
// Get the params URL, and send the change
|
||||
let url = UrlBuilder::api_params(self.file);
|
||||
let response = client.post(url)
|
||||
|
@ -90,7 +90,7 @@ impl<'a> Params<'a> {
|
|||
|
||||
// Ensure the response is successful
|
||||
ensure_success(&response)
|
||||
.map_err(|err| ChangeError::Response(err))
|
||||
.map_err(|err| err.into())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -165,10 +165,10 @@ pub enum Error {
|
|||
#[fail(display = "Failed to prepare setting the parameters")]
|
||||
Prepare(#[cause] PrepareError),
|
||||
|
||||
// /// The given Send file has expired, or did never exist in the first place.
|
||||
// /// Therefore the file could not be downloaded.
|
||||
// #[fail(display = "The file has expired or did never exist")]
|
||||
// Expired,
|
||||
/// The given Send file has expired, or did never exist in the first place.
|
||||
/// Therefore the file could not be downloaded.
|
||||
#[fail(display = "The file has expired or did never exist")]
|
||||
Expired,
|
||||
|
||||
/// An error has occurred while sending the parameter change request to
|
||||
/// the server.
|
||||
|
@ -176,6 +176,15 @@ pub enum Error {
|
|||
Change(#[cause] ChangeError),
|
||||
}
|
||||
|
||||
impl From<NonceError> for Error {
|
||||
fn from(err: NonceError) -> Error {
|
||||
match err {
|
||||
NonceError::Expired => Error::Expired,
|
||||
err => Error::Prepare(PrepareError::Auth(err)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<PrepareError> for Error {
|
||||
fn from(err: PrepareError) -> Error {
|
||||
Error::Prepare(err)
|
||||
|
@ -183,11 +192,20 @@ impl From<PrepareError> for Error {
|
|||
}
|
||||
|
||||
impl From<ChangeError> for Error {
|
||||
fn from(err: ChangeError) -> Error {
|
||||
fn from(err:ChangeError) -> Error {
|
||||
Error::Change(err)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ResponseError> for Error {
|
||||
fn from(err: ResponseError) -> Error {
|
||||
match err {
|
||||
ResponseError::Expired => Error::Expired,
|
||||
err => Error::Change(ChangeError::Response(err)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Fail)]
|
||||
pub enum ParamsDataError {
|
||||
/// The number of downloads is invalid, as it was out of the allowed
|
||||
|
|
|
@ -61,12 +61,12 @@ impl<'a> Password<'a> {
|
|||
|
||||
/// Fetch the authentication nonce for the file from the Send server.
|
||||
fn fetch_auth_nonce(&self, client: &Client)
|
||||
-> Result<Vec<u8>, PrepareError>
|
||||
-> Result<Vec<u8>, Error>
|
||||
{
|
||||
request_nonce(
|
||||
client,
|
||||
UrlBuilder::download(self.file, false),
|
||||
).map_err(|err| PrepareError::Auth(err))
|
||||
).map_err(|err| err.into())
|
||||
}
|
||||
|
||||
/// Send the request for changing the file password.
|
||||
|
@ -74,7 +74,7 @@ impl<'a> Password<'a> {
|
|||
&self,
|
||||
client: &Client,
|
||||
data: OwnedData<PasswordData>,
|
||||
) -> Result<(), ChangeError> {
|
||||
) -> Result<(), Error> {
|
||||
// Get the password URL, and send the change
|
||||
let url = UrlBuilder::api_password(self.file);
|
||||
let response = client.post(url)
|
||||
|
@ -84,7 +84,7 @@ impl<'a> Password<'a> {
|
|||
|
||||
// Ensure the response is successful
|
||||
ensure_success(&response)
|
||||
.map_err(|err| ChangeError::Response(err))
|
||||
.map_err(|err| err.into())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -111,10 +111,10 @@ pub enum Error {
|
|||
#[fail(display = "Failed to prepare setting the password")]
|
||||
Prepare(#[cause] PrepareError),
|
||||
|
||||
// /// The given Send file has expired, or did never exist in the first place.
|
||||
// /// Therefore the file could not be downloaded.
|
||||
// #[fail(display = "The file has expired or did never exist")]
|
||||
// Expired,
|
||||
/// The given Send file has expired, or did never exist in the first place.
|
||||
/// Therefore the file could not be downloaded.
|
||||
#[fail(display = "The file has expired or did never exist")]
|
||||
Expired,
|
||||
|
||||
/// An error has occurred while sending the password change request to
|
||||
/// the server.
|
||||
|
@ -122,6 +122,15 @@ pub enum Error {
|
|||
Change(#[cause] ChangeError),
|
||||
}
|
||||
|
||||
impl From<NonceError> for Error {
|
||||
fn from(err: NonceError) -> Error {
|
||||
match err {
|
||||
NonceError::Expired => Error::Expired,
|
||||
err => Error::Prepare(PrepareError::Auth(err)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<PrepareError> for Error {
|
||||
fn from(err: PrepareError) -> Error {
|
||||
Error::Prepare(err)
|
||||
|
@ -134,6 +143,15 @@ impl From<ChangeError> for Error {
|
|||
}
|
||||
}
|
||||
|
||||
impl From<ResponseError> for Error {
|
||||
fn from(err: ResponseError) -> Error {
|
||||
match err {
|
||||
ResponseError::Expired => Error::Expired,
|
||||
err => Error::Change(ChangeError::Response(err)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Fail, Debug)]
|
||||
pub enum PrepareError {
|
||||
/// Failed authenticating, needed to set a new password.
|
||||
|
|
|
@ -18,8 +18,7 @@ pub fn request_nonce(client: &Client, url: Url)
|
|||
.map_err(|_| NonceError::Request)?;
|
||||
|
||||
// Ensure the response is successful
|
||||
ensure_success(&response)
|
||||
.map_err(|err| NonceError::Response(err))?;
|
||||
ensure_success(&response)?;
|
||||
|
||||
// Extract the nonce
|
||||
header_nonce(&response)
|
||||
|
@ -48,6 +47,11 @@ pub fn header_nonce(response: &Response)
|
|||
|
||||
#[derive(Fail, Debug)]
|
||||
pub enum NonceError {
|
||||
/// Sending the request to fetch a nonce failed,
|
||||
/// as the file has expired or did never exist.
|
||||
#[fail(display = "The file has expired or did never exist")]
|
||||
Expired,
|
||||
|
||||
/// Sending the request to fetch a nonce failed.
|
||||
#[fail(display = "Failed to request encryption nonce")]
|
||||
Request,
|
||||
|
@ -67,3 +71,12 @@ pub enum NonceError {
|
|||
#[fail(display = "Received malformed nonce")]
|
||||
MalformedNonce,
|
||||
}
|
||||
|
||||
impl From<ResponseError> for NonceError {
|
||||
fn from(err: ResponseError) -> Self {
|
||||
match err {
|
||||
ResponseError::Expired => NonceError::Expired,
|
||||
err => NonceError::Response(err),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,10 +51,14 @@ impl<'a> Delete<'a> {
|
|||
ensure_owner_token(file.owner_token_mut(), &matcher_main);
|
||||
|
||||
// Send the file deletion request
|
||||
ApiDelete::new(&file, None).invoke(&client)?;
|
||||
let result = ApiDelete::new(&file, None).invoke(&client);
|
||||
if let Err(DeleteError::Expired) = result {
|
||||
// Remove the file from the history manager if it does not exist
|
||||
history_tool::remove(&matcher_main, &file);
|
||||
}
|
||||
result?;
|
||||
|
||||
// Remove the file from the history manager
|
||||
// TODO: also remove if it was expired
|
||||
history_tool::remove(&matcher_main, &file);
|
||||
|
||||
// Print a success message
|
||||
|
@ -71,6 +75,10 @@ pub enum Error {
|
|||
#[fail(display = "Invalid share URL")]
|
||||
InvalidUrl(#[cause] FileParseError),
|
||||
|
||||
/// Could not delete, the file has expired or did never exist.
|
||||
#[fail(display = "The file has expired or did never exist")]
|
||||
Expired,
|
||||
|
||||
/// An error occurred while deleting the remote file.
|
||||
#[fail(display = "Failed to delete the shared file")]
|
||||
Delete(#[cause] DeleteError),
|
||||
|
@ -84,6 +92,9 @@ impl From<FileParseError> for Error {
|
|||
|
||||
impl From<DeleteError> for Error {
|
||||
fn from(err: DeleteError) -> Error {
|
||||
Error::Delete(err)
|
||||
match err {
|
||||
DeleteError::Expired => Error::Expired,
|
||||
err => Error::Delete(err),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue