瀏覽代碼

Fix password action for new API [WIP, dirty]

timvisee 7 年之前
父節點
當前提交
70944f071d
共有 3 個文件被更改,包括 51 次插入16 次删除
  1. 1 1
      api/src/action/download.rs
  2. 28 15
      api/src/action/password.rs
  3. 22 0
      api/src/file/file.rs

+ 1 - 1
api/src/action/download.rs

@@ -304,7 +304,7 @@ impl<'a> Download<'a> {
 #[derive(Debug, Deserialize)]
 struct MetadataResponse {
     /// The encrypted metadata.
-    #[serde(rename="metadata")]
+    #[serde(rename = "metadata")]
     meta: String,
 }
 

+ 28 - 15
api/src/action/password.rs

@@ -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(),
         }
     }

+ 22 - 0
api/src/file/file.rs

@@ -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 {