소스 검색

Add password handling to CLI info command

timvisee 7 년 전
부모
커밋
3778e82855
3개의 변경된 파일47개의 추가작업 그리고 7개의 파일을 삭제
  1. 14 5
      cli/src/action/info.rs
  2. 1 1
      cli/src/cmd/cmd_download.rs
  3. 32 1
      cli/src/cmd/cmd_info.rs

+ 14 - 5
cli/src/action/info.rs

@@ -39,9 +39,9 @@ impl<'a> Info<'a> {
         // Create a reqwest client
         let client = Client::new();
 
-        // Parse the remote file based on the share URL
-        // TODO: handle error here
+        // Parse the remote file based on the share URL, get the password
         let file = RemoteFile::parse_url(url, self.cmd.owner())?;
+        let password = self.cmd.password();
 
         // TODO: show an informative error if the owner token isn't set
 
@@ -54,12 +54,21 @@ impl<'a> Info<'a> {
             return Err(Error::Expired);
         }
 
-        // TODO: make sure a password is set if required
+        // Make sure a password is given when it is required
+        let has_password = password.is_some();
+        if has_password != exists_response.has_password() {
+            if has_password {
+                // TODO: show a proper message here
+                println!("file not password protected, ignoring password");
+            } else {
+                // TODO: show a propper error here, or prompt for the password
+                panic!("password required");
+            }
+        }
 
         // Fetch both file info and metadata
         let info = ApiInfo::new(&file, None).invoke(&client)?;
-        // TODO: supply a password here
-        let metadata = ApiMetadata::new(&file, None).invoke(&client)
+        let metadata = ApiMetadata::new(&file, password).invoke(&client)
             .map_err(|err| print_error(err.context(
                 "Failed to fetch file metadata, showing limited info",
             )))

+ 1 - 1
cli/src/cmd/cmd_download.rs

@@ -2,8 +2,8 @@ use std::path::PathBuf;
 
 use ffsend_api::url::{ParseError, Url};
 
-use super::clap::{App, Arg, ArgMatches, SubCommand};
 use rpassword::prompt_password_stderr;
+use super::clap::{App, Arg, ArgMatches, SubCommand};
 
 use util::quit_error_msg;
 

+ 32 - 1
cli/src/cmd/cmd_info.rs

@@ -1,5 +1,6 @@
 use ffsend_api::url::{ParseError, Url};
 
+use rpassword::prompt_password_stderr;
 use super::clap::{App, Arg, ArgMatches, SubCommand};
 
 use util::quit_error_msg;
@@ -28,7 +29,15 @@ impl<'a: 'b, 'b> CmdInfo<'a> {
                 .alias("owner-token")
                 .alias("token")
                 .value_name("TOKEN")
-                .help("File owner token"));
+                .help("File owner token"))
+            .arg(Arg::with_name("password")
+                .long("password")
+                .short("p")
+                .alias("pass")
+                .value_name("PASSWORD")
+                .min_values(0)
+                .max_values(1)
+                .help("Unlock a password protected file"));
 
         cmd
     }
@@ -75,4 +84,26 @@ impl<'a: 'b, 'b> CmdInfo<'a> {
             _ => quit_error_msg("The given host is invalid"),
         }
     }
+
+    /// Get the password.
+    /// `None` is returned if no password was specified.
+    pub fn password(&'a self) -> Option<String> {
+        // Return none if the property was not set
+        if !self.matches.is_present("password") {
+            return None;
+        }
+
+        // Get the password from the arguments
+        if let Some(password) = self.matches.value_of("password") {
+            return Some(password.into());
+        }
+
+        // Prompt for the password
+        // TODO: don't unwrap/expect
+        // TODO: create utility function for this
+        Some(
+            prompt_password_stderr("Password: ")
+                .expect("failed to read password from stdin")
+        )
+    }
 }