mirror of
https://github.com/timvisee/ffsend.git
synced 2025-10-06 02:29:57 +02:00
Add explicit error handling for expired files
This commit is contained in:
parent
160809efa2
commit
5ae016192c
1 changed files with 19 additions and 10 deletions
|
@ -25,6 +25,9 @@ use reader::{EncryptedFileWriter, ProgressReporter, ProgressWriter};
|
||||||
/// The name of the header that is used for the authentication nonce.
|
/// The name of the header that is used for the authentication nonce.
|
||||||
const HEADER_AUTH_NONCE: &'static str = "WWW-Authenticate";
|
const HEADER_AUTH_NONCE: &'static str = "WWW-Authenticate";
|
||||||
|
|
||||||
|
/// The HTTP status code that is returned for expired files.
|
||||||
|
const FILE_EXPIRED_STATUS: StatusCode = StatusCode::NotFound;
|
||||||
|
|
||||||
/// A file upload action to a Send server.
|
/// A file upload action to a Send server.
|
||||||
pub struct Download<'a> {
|
pub struct Download<'a> {
|
||||||
/// The Send file to download.
|
/// The Send file to download.
|
||||||
|
@ -49,8 +52,7 @@ impl<'a> Download<'a> {
|
||||||
let mut key = KeySet::from(self.file);
|
let mut key = KeySet::from(self.file);
|
||||||
|
|
||||||
// Fetch the authentication nonce
|
// Fetch the authentication nonce
|
||||||
let auth_nonce = self.fetch_auth_nonce(client)
|
let auth_nonce = self.fetch_auth_nonce(client)?;
|
||||||
.map_err(|err| Error::Request(RequestError::Auth(err)))?;
|
|
||||||
|
|
||||||
// Fetch the meta nonce, set the input vector
|
// Fetch the meta nonce, set the input vector
|
||||||
let meta_nonce = self.fetch_meta_nonce(&client, &mut key, auth_nonce)
|
let meta_nonce = self.fetch_meta_nonce(&client, &mut key, auth_nonce)
|
||||||
|
@ -86,7 +88,7 @@ impl<'a> Download<'a> {
|
||||||
|
|
||||||
/// Fetch the authentication nonce for the file from the Send server.
|
/// Fetch the authentication nonce for the file from the Send server.
|
||||||
fn fetch_auth_nonce(&self, client: &Client)
|
fn fetch_auth_nonce(&self, client: &Client)
|
||||||
-> Result<Vec<u8>, AuthError>
|
-> Result<Vec<u8>, Error>
|
||||||
{
|
{
|
||||||
// Get the download url, and parse the nonce
|
// Get the download url, and parse the nonce
|
||||||
let download_url = self.file.download_url(false);
|
let download_url = self.file.download_url(false);
|
||||||
|
@ -97,7 +99,12 @@ impl<'a> Download<'a> {
|
||||||
// Validate the status code
|
// Validate the status code
|
||||||
let status = response.status();
|
let status = response.status();
|
||||||
if !status.is_success() {
|
if !status.is_success() {
|
||||||
return Err(AuthError::NonceReqStatus(status, status.err_text()));
|
// Handle expired files
|
||||||
|
if status == FILE_EXPIRED_STATUS {
|
||||||
|
return Err(Error::Expired);
|
||||||
|
} else {
|
||||||
|
return Err(AuthError::NonceReqStatus(status, status.err_text()).into());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the authentication nonce
|
// Get the authentication nonce
|
||||||
|
@ -114,7 +121,7 @@ impl<'a> Download<'a> {
|
||||||
.skip(1)
|
.skip(1)
|
||||||
.next()
|
.next()
|
||||||
.ok_or(AuthError::MalformedNonce)?
|
.ok_or(AuthError::MalformedNonce)?
|
||||||
).map_err(|_| AuthError::MalformedNonce)
|
).map_err(|_| AuthError::MalformedNonce.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Fetch the metadata nonce.
|
/// Fetch the metadata nonce.
|
||||||
|
@ -282,7 +289,6 @@ impl<'a> Download<'a> {
|
||||||
.finish();
|
.finish();
|
||||||
|
|
||||||
// Verify the writer
|
// Verify the writer
|
||||||
// TODO: delete the file if verification failed, show a proper error
|
|
||||||
if writer.unwrap().verified() {
|
if writer.unwrap().verified() {
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
|
@ -308,7 +314,6 @@ impl MetadataResponse {
|
||||||
///
|
///
|
||||||
/// The decrypted data is verified using an included tag.
|
/// The decrypted data is verified using an included tag.
|
||||||
/// If verification failed, an error is returned.
|
/// If verification failed, an error is returned.
|
||||||
// TODO: do not unwrap, return a proper error
|
|
||||||
pub fn decrypt_metadata(&self, key_set: &KeySet) -> Result<Metadata, FailureError> {
|
pub fn decrypt_metadata(&self, key_set: &KeySet) -> Result<Metadata, FailureError> {
|
||||||
// Decode the metadata
|
// Decode the metadata
|
||||||
let raw = b64::decode(&self.meta)?;
|
let raw = b64::decode(&self.meta)?;
|
||||||
|
@ -319,7 +324,6 @@ impl MetadataResponse {
|
||||||
assert_eq!(tag.len(), 16);
|
assert_eq!(tag.len(), 16);
|
||||||
|
|
||||||
// Decrypt the metadata
|
// Decrypt the metadata
|
||||||
// TODO: do not unwrap, return an error
|
|
||||||
let meta = decrypt_aead(
|
let meta = decrypt_aead(
|
||||||
KeySet::cipher(),
|
KeySet::cipher(),
|
||||||
key_set.meta_key().unwrap(),
|
key_set.meta_key().unwrap(),
|
||||||
|
@ -344,7 +348,6 @@ pub enum Error {
|
||||||
|
|
||||||
/// The given Send file has expired, or did never exist in the first place.
|
/// The given Send file has expired, or did never exist in the first place.
|
||||||
/// Therefore the file could not be downloaded.
|
/// Therefore the file could not be downloaded.
|
||||||
// TODO: return this error when the file is expired
|
|
||||||
#[fail(display = "The file has expired or did never exist")]
|
#[fail(display = "The file has expired or did never exist")]
|
||||||
Expired,
|
Expired,
|
||||||
|
|
||||||
|
@ -356,12 +359,18 @@ pub enum Error {
|
||||||
#[fail(display = "Failed to decrypt the downloaded file")]
|
#[fail(display = "Failed to decrypt the downloaded file")]
|
||||||
Decrypt,
|
Decrypt,
|
||||||
|
|
||||||
// TODO: add description
|
/// An error occurred while opening or writing to the target file.
|
||||||
// TODO: show what file this is about
|
// TODO: show what file this is about
|
||||||
#[fail(display = "Could not open the file for writing")]
|
#[fail(display = "Could not open the file for writing")]
|
||||||
File(#[cause] FileError),
|
File(#[cause] FileError),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<AuthError> for Error {
|
||||||
|
fn from(err: AuthError) -> Error {
|
||||||
|
Error::Request(RequestError::Auth(err))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Fail, Debug)]
|
#[derive(Fail, Debug)]
|
||||||
pub enum RequestError {
|
pub enum RequestError {
|
||||||
/// Failed authenticating, in order to fetch the file data.
|
/// Failed authenticating, in order to fetch the file data.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue