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::{Client, StatusCode};
|
||||||
use reqwest::header::Authorization;
|
use reqwest::header::Authorization;
|
||||||
|
|
||||||
|
use api::data::{
|
||||||
|
Error as DataError,
|
||||||
|
OwnedData,
|
||||||
|
};
|
||||||
use crypto::b64;
|
use crypto::b64;
|
||||||
use crypto::key_set::KeySet;
|
use crypto::key_set::KeySet;
|
||||||
use crypto::sig::signature_encoded;
|
use crypto::sig::signature_encoded;
|
||||||
|
@ -56,8 +60,9 @@ impl<'a> Password<'a> {
|
||||||
// Derive a new authentication key
|
// Derive a new authentication key
|
||||||
key.derive_auth_password(self.password, &self.file.download_url(true));
|
key.derive_auth_password(self.password, &self.file.download_url(true));
|
||||||
|
|
||||||
// Build the password data
|
// Build the password data, wrap it as owned
|
||||||
let data = PasswordData::from(self.file, &key)?;
|
let data = OwnedData::from(PasswordData::from(&key), &self.file)
|
||||||
|
.map_err(|err| -> PrepareError { err.into() })?;
|
||||||
|
|
||||||
// Send the request to change the password
|
// Send the request to change the password
|
||||||
self.change_password(client, data, sig)
|
self.change_password(client, data, sig)
|
||||||
|
@ -107,7 +112,7 @@ impl<'a> Password<'a> {
|
||||||
fn change_password(
|
fn change_password(
|
||||||
&self,
|
&self,
|
||||||
client: &Client,
|
client: &Client,
|
||||||
data: PasswordData,
|
data: OwnedData<PasswordData>,
|
||||||
sig: String,
|
sig: String,
|
||||||
) -> Result<(), ChangeError> {
|
) -> Result<(), ChangeError> {
|
||||||
// Get the password URL, and send the change
|
// 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,
|
/// The data object to send to the password endpoint,
|
||||||
/// which sets the file password.
|
/// which sets the file password.
|
||||||
#[derive(Debug, Serialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
struct PasswordData {
|
struct PasswordData {
|
||||||
/// The file owner token
|
|
||||||
owner_token: String,
|
|
||||||
|
|
||||||
/// The authentication key
|
/// The authentication key
|
||||||
auth: String,
|
auth: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PasswordData {
|
impl PasswordData {
|
||||||
/// Create the password data object from the given key set.
|
/// Create the password data object from the given key set.
|
||||||
pub fn from(file: &RemoteFile, key: &KeySet)
|
pub fn from(key: &KeySet) -> PasswordData {
|
||||||
-> Result<PasswordData, PrepareError>
|
PasswordData {
|
||||||
{
|
auth: key.auth_key_encoded().unwrap(),
|
||||||
Ok(
|
}
|
||||||
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")]
|
#[fail(display = "Failed to compute cryptographic signature")]
|
||||||
ComputeSignature,
|
ComputeSignature,
|
||||||
|
|
||||||
/// The owner token was missing from the file, and is required.
|
/// Some error occurred while building the data that will be sent.
|
||||||
#[fail(display = "Missing owner token, must be specified")]
|
/// The owner token might possibly be missing, the wrapped error will
|
||||||
NoOwnerToken,
|
/// describe this further.
|
||||||
|
#[fail(display = "")]
|
||||||
|
Data(#[cause] DataError),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<DataError> for PrepareError {
|
||||||
|
fn from(err: DataError) -> PrepareError {
|
||||||
|
PrepareError::Data(err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Fail, Debug)]
|
#[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