mirror of
https://github.com/timvisee/ffsend.git
synced 2025-10-06 02:29:57 +02:00
Fix password action for new API [WIP, dirty]
This commit is contained in:
parent
16133ce667
commit
70944f071d
3 changed files with 51 additions and 16 deletions
|
@ -304,7 +304,7 @@ impl<'a> Download<'a> {
|
|||
#[derive(Debug, Deserialize)]
|
||||
struct MetadataResponse {
|
||||
/// The encrypted metadata.
|
||||
#[serde(rename="metadata")]
|
||||
#[serde(rename = "metadata")]
|
||||
meta: String,
|
||||
}
|
||||
|
||||
|
|
|
@ -19,35 +19,44 @@ pub struct Password<'a> {
|
|||
|
||||
/// The new password.
|
||||
password: &'a str,
|
||||
|
||||
/// The key set
|
||||
key: &'a mut KeySet,
|
||||
|
||||
/// The file upload nonce
|
||||
nonce: Vec<u8>,
|
||||
}
|
||||
|
||||
impl<'a> Password<'a> {
|
||||
/// Construct a new password action for the given file.
|
||||
pub fn new(file: &'a DownloadFile, password: &'a sts) -> Self {
|
||||
pub fn new(
|
||||
file: &'a DownloadFile,
|
||||
password: &'a str,
|
||||
key: &'a mut KeySet,
|
||||
nonce: Vec<u8>,
|
||||
) -> Self {
|
||||
Self {
|
||||
file,
|
||||
password,
|
||||
key,
|
||||
nonce,
|
||||
}
|
||||
}
|
||||
|
||||
/// Invoke the password action.
|
||||
// TODO: allow passing an optional existing authentication nonce
|
||||
pub fn invoke(self, client: &Client) -> Result<(), Error> {
|
||||
// Create a key set for the file
|
||||
let mut key = KeySet::from(self.file);
|
||||
|
||||
// Fetch the authentication nonce
|
||||
let auth_nonce = self.fetch_auth_nonce(client)?;
|
||||
|
||||
pub fn invoke(mut self, client: &Client) -> Result<(), Error> {
|
||||
// Compute a signature
|
||||
let sig = signature_encoded(key.auth_key().unwrap(), &nonce)
|
||||
let sig = signature_encoded(self.key.auth_key().unwrap(), &self.nonce)
|
||||
.map_err(|_| PrepareError::ComputeSignature)?;
|
||||
|
||||
// Derive a new authentication key
|
||||
key.derive_auth_password(self.password, &self.file.download_url(true));
|
||||
self.key.derive_auth_password(self.password, &self.file.download_url(true));
|
||||
|
||||
// Build the password data
|
||||
let password_data = PasswordData::from(self.file, &self.key);
|
||||
|
||||
// Send the request to change the password
|
||||
self.change_password(client, &key, sig).map_err(|err| err.into())
|
||||
self.change_password(client, password_data, sig).map_err(|err| err.into())
|
||||
}
|
||||
|
||||
/// Fetch the authentication nonce for the file from the Send server.
|
||||
|
@ -93,13 +102,13 @@ impl<'a> Password<'a> {
|
|||
fn change_password(
|
||||
&self,
|
||||
client: &Client,
|
||||
key: &KeySet,
|
||||
password_data: PasswordData,
|
||||
sig: String,
|
||||
) -> Result<(), ChangeError> {
|
||||
// Get the password URL, and send the change
|
||||
let url = self.file.api_password_url();
|
||||
let response = client.post(url)
|
||||
.json(&PasswordData::from(&key))
|
||||
.json(&password_data)
|
||||
.header(Authorization(
|
||||
format!("send-v1 {}", sig)
|
||||
))
|
||||
|
@ -120,15 +129,19 @@ impl<'a> Password<'a> {
|
|||
/// which sets the file password.
|
||||
#[derive(Debug, Serialize)]
|
||||
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(key: &KeySet) -> PasswordData {
|
||||
pub fn from(file: &DownloadFile, key: &KeySet) -> PasswordData {
|
||||
PasswordData {
|
||||
// TODO: do not unwrap here
|
||||
owner_token: file.owner_token().unwrap().to_owned(),
|
||||
auth: key.auth_key_encoded().unwrap(),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,6 +42,7 @@ pub struct File {
|
|||
secret: Vec<u8>,
|
||||
|
||||
/// The owner key, that can be used to manage the file on the server.
|
||||
// TODO: rename this to owner token
|
||||
owner_key: String,
|
||||
}
|
||||
|
||||
|
@ -83,6 +84,17 @@ impl File {
|
|||
)
|
||||
}
|
||||
|
||||
// TODO: this should be removed when merging the two file types
|
||||
pub fn to_download_file(&self) -> DownloadFile {
|
||||
DownloadFile::new(
|
||||
self.id.clone(),
|
||||
self.host.clone(),
|
||||
self.url.clone(),
|
||||
self.secret.clone(),
|
||||
Some(self.owner_key.clone()),
|
||||
)
|
||||
}
|
||||
|
||||
/// Get the raw secret.
|
||||
pub fn secret_raw(&self) -> &Vec<u8> {
|
||||
// A secret must have been set
|
||||
|
@ -133,6 +145,8 @@ pub struct DownloadFile {
|
|||
|
||||
/// The secret key that is required to download the file.
|
||||
secret: Vec<u8>,
|
||||
|
||||
owner_token: Option<String>,
|
||||
}
|
||||
|
||||
impl DownloadFile {
|
||||
|
@ -142,12 +156,14 @@ impl DownloadFile {
|
|||
host: Url,
|
||||
url: Url,
|
||||
secret: Vec<u8>,
|
||||
owner_token: Option<String>,
|
||||
) -> Self {
|
||||
Self {
|
||||
id,
|
||||
host,
|
||||
url,
|
||||
secret,
|
||||
owner_token,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -192,6 +208,7 @@ impl DownloadFile {
|
|||
host,
|
||||
url,
|
||||
secret,
|
||||
None,
|
||||
))
|
||||
}
|
||||
|
||||
|
@ -223,6 +240,11 @@ impl DownloadFile {
|
|||
self.secret = secret;
|
||||
}
|
||||
|
||||
/// Get the owner token if set.
|
||||
pub fn owner_token(&self) -> Option<&String> {
|
||||
self.owner_token.as_ref()
|
||||
}
|
||||
|
||||
/// Get the download URL of the file.
|
||||
/// Set `secret` to `true`, to include it in the URL if known.
|
||||
pub fn download_url(&self, secret: bool) -> Url {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue