mirror of
https://github.com/timvisee/ffsend.git
synced 2025-10-03 17:49:15 +02:00
Create owned data structure for improved authentication on generic data
This commit is contained in:
parent
a516f8929f
commit
b62ba8b8fc
3 changed files with 75 additions and 21 deletions
|
@ -3,6 +3,10 @@
|
|||
use reqwest::{Client, StatusCode};
|
||||
use reqwest::header::Authorization;
|
||||
|
||||
use api::data::{
|
||||
Error as DataError,
|
||||
OwnedData,
|
||||
};
|
||||
use crypto::b64;
|
||||
use crypto::key_set::KeySet;
|
||||
use crypto::sig::signature_encoded;
|
||||
|
@ -56,8 +60,9 @@ impl<'a> Password<'a> {
|
|||
// Derive a new authentication key
|
||||
key.derive_auth_password(self.password, &self.file.download_url(true));
|
||||
|
||||
// Build the password data
|
||||
let data = PasswordData::from(self.file, &key)?;
|
||||
// Build the password data, wrap it as owned
|
||||
let data = OwnedData::from(PasswordData::from(&key), &self.file)
|
||||
.map_err(|err| -> PrepareError { err.into() })?;
|
||||
|
||||
// Send the request to change the password
|
||||
self.change_password(client, data, sig)
|
||||
|
@ -107,7 +112,7 @@ impl<'a> Password<'a> {
|
|||
fn change_password(
|
||||
&self,
|
||||
client: &Client,
|
||||
data: PasswordData,
|
||||
data: OwnedData<PasswordData>,
|
||||
sig: String,
|
||||
) -> Result<(), ChangeError> {
|
||||
// Get the password URL, and send the change
|
||||
|
@ -132,28 +137,18 @@ impl<'a> Password<'a> {
|
|||
|
||||
/// The data object to send to the password endpoint,
|
||||
/// which sets the file password.
|
||||
#[derive(Debug, Serialize)]
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
struct PasswordData {
|
||||
/// The file owner token
|
||||
owner_token: String,
|
||||
|
||||
/// The authentication key
|
||||
auth: String,
|
||||
}
|
||||
|
||||
impl PasswordData {
|
||||
/// Create the password data object from the given key set.
|
||||
pub fn from(file: &RemoteFile, key: &KeySet)
|
||||
-> Result<PasswordData, PrepareError>
|
||||
{
|
||||
Ok(
|
||||
pub fn from(key: &KeySet) -> PasswordData {
|
||||
PasswordData {
|
||||
owner_token: file.owner_token()
|
||||
.ok_or(PrepareError::NoOwnerToken)?
|
||||
.to_owned(),
|
||||
auth: key.auth_key_encoded().unwrap(),
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -202,9 +197,17 @@ pub enum PrepareError {
|
|||
#[fail(display = "Failed to compute cryptographic signature")]
|
||||
ComputeSignature,
|
||||
|
||||
/// The owner token was missing from the file, and is required.
|
||||
#[fail(display = "Missing owner token, must be specified")]
|
||||
NoOwnerToken,
|
||||
/// Some error occurred while building the data that will be sent.
|
||||
/// The owner token might possibly be missing, the wrapped error will
|
||||
/// describe this further.
|
||||
#[fail(display = "")]
|
||||
Data(#[cause] DataError),
|
||||
}
|
||||
|
||||
impl From<DataError> for PrepareError {
|
||||
fn from(err: DataError) -> PrepareError {
|
||||
PrepareError::Data(err)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Fail, Debug)]
|
||||
|
|
50
api/src/api/data.rs
Normal file
50
api/src/api/data.rs
Normal file
|
@ -0,0 +1,50 @@
|
|||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use file::remote_file::RemoteFile;
|
||||
|
||||
/// An owned data structure, that wraps generic data.
|
||||
/// This structure is used to send owned data to the Send server.
|
||||
/// This owned data is authenticated using an `owner_token`,
|
||||
/// wwhich this structure manages.
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct OwnedData<D> {
|
||||
/// The owner token, used for request authentication purposes.
|
||||
owner_token: String,
|
||||
|
||||
/// The wrapped data structure.
|
||||
#[serde(flatten)]
|
||||
inner: D,
|
||||
}
|
||||
|
||||
impl<'a, D> OwnedData<D>
|
||||
where
|
||||
D: Serialize + Deserialize<'a>,
|
||||
{
|
||||
/// Constructor.
|
||||
pub fn new(owner_token: String, inner: D) -> Self {
|
||||
OwnedData {
|
||||
owner_token,
|
||||
inner,
|
||||
}
|
||||
}
|
||||
|
||||
/// Wrap the given data structure with this owned data structure.
|
||||
/// A `file` must be given, having a set owner token.
|
||||
pub fn from(inner: D, file: &RemoteFile) -> Result<Self, Error> {
|
||||
Ok(
|
||||
Self::new(
|
||||
file.owner_token()
|
||||
.ok_or(Error::NoOwnerToken)?
|
||||
.to_owned(),
|
||||
inner,
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Fail)]
|
||||
pub enum Error {
|
||||
/// Missing owner token, which is required.
|
||||
#[fail(display = "Missing owner token, must be specified")]
|
||||
NoOwnerToken,
|
||||
}
|
1
api/src/api/mod.rs
Normal file
1
api/src/api/mod.rs
Normal file
|
@ -0,0 +1 @@
|
|||
pub mod data;
|
Loading…
Add table
Add a link
Reference in a new issue