diff --git a/hel/src/commands.rs b/hel/src/commands.rs index 240a135..30cf67e 100644 --- a/hel/src/commands.rs +++ b/hel/src/commands.rs @@ -134,16 +134,22 @@ impl<'a> LKEval<'a> { } } - pub fn cmd_pass(&self, out: &LKOut, name: &String) { + pub fn cmd_pass(&self, out: &LKOut, name: &String, pass: &Option) { match self.get_password(name) { Some(p) => { - let pwd = (self.read_password)(format!("Password for {}: ", p.lock().borrow().name)).unwrap(); + let pwd = match pass { + Some(pp) => pp.to_string(), + None => (self.read_password)(format!("Password for {}: ", p.lock().borrow().name)).unwrap(), + }; self.cmd_correct(&out, &p.lock().borrow().name, true, Some(pwd.clone())); self.state.lock().borrow_mut().secrets.insert(p.lock().borrow().name.to_string(), pwd); } None => { if name == "/" { - let pwd = (self.read_password)("Master: ".to_string()).unwrap(); + let pwd = match pass { + Some(pp) => pp.to_string(), + None => (self.read_password)("Master: ".to_string()).unwrap(), + }; self.cmd_correct(&out, &"/".to_string(), true, Some(pwd.clone())); self.state.lock().borrow_mut().secrets.insert("/".to_string(), pwd); } else { diff --git a/hel/src/parser.rs b/hel/src/parser.rs index 5838940..ee838b5 100644 --- a/hel/src/parser.rs +++ b/hel/src/parser.rs @@ -95,7 +95,9 @@ peg::parser! { } rule error_cmd() -> Command<'input> = "error" _ e:$(([' '..='~'])+) { Command::Error(LKErr::Error(e)) } rule mv_cmd() -> Command<'input> = "mv" _ name:word() _ folder:word() { Command::Mv(name, folder) } - rule pass_cmd() -> Command<'input> = "pass" _ name:word() { Command::Pass(name) } + rule pass_short_cmd() -> Command<'input> = "pass" _ name:word() { Command::Pass(name, None) } + rule pass_long_cmd() -> Command<'input> = "pass" _ name:word() _ pass:$(([' '..='~'])+) { Command::Pass(name, Some(pass.to_string())) } + rule pass_cmd() -> Command<'input> = p:(pass_long_cmd() / pass_short_cmd()) { p } rule correct_cmd() -> Command<'input> = "correct" _ name:word() { Command::Correct(name) } rule uncorrect_cmd() -> Command<'input> = "uncorrect" _ name:word() { Command::Uncorrect(name) } rule unpass_cmd() -> Command<'input> = "unpass" _ name:word() { Command::UnPass(name) } diff --git a/hel/src/repl.rs b/hel/src/repl.rs index 61b308f..a82f41e 100644 --- a/hel/src/repl.rs +++ b/hel/src/repl.rs @@ -122,7 +122,7 @@ impl<'a> LKEval<'a> { quit = self.cmd_source(&out, script); } Command::Dump(script) => self.cmd_dump(&out, script), - Command::Pass(name) => self.cmd_pass(&out, &name), + Command::Pass(name, pass) => self.cmd_pass(&out, &name, &pass), Command::UnPass(name) => match self.state.lock().borrow_mut().secrets.remove(name) { Some(_) => out.o(format!("Removed saved password for {}", name)), None => out.e(format!("error: saved password for {} not found", name)), @@ -412,4 +412,23 @@ mod tests { ) ); } + + #[test] + fn exec_cmd_pass() { + let lk = Arc::new(ReentrantMutex::new(RefCell::new(LK::new()))); + let t1 = Password::from_password(Password::new( + None, + "t1".to_string(), + None, + Mode::Regular, + 99, + Date::new(2022, 12, 30), + None, + )); + LKEval::news(Command::Add(t1.clone()), lk.clone()).eval(); + ({ let mut e = LKEval::news(Command::Pass("t1".to_string(), None), lk.clone()); e.read_password = |_| { Ok("test pwd1".to_string()) }; e }).eval(); + assert_eq!(lk.lock().borrow().secrets[&"t1".to_string()], "test pwd1"); + LKEval::news(Command::Pass("t1".to_string(), Some("other pw".to_string())), lk.clone()).eval(); + assert_eq!(lk.lock().borrow().secrets[&"t1".to_string()], "other pw"); + } } diff --git a/hel/src/structs.rs b/hel/src/structs.rs index 8e46352..d7dacb9 100644 --- a/hel/src/structs.rs +++ b/hel/src/structs.rs @@ -67,7 +67,7 @@ pub enum Command<'a> { Rm(Name), Enc(Name), Gen(u32, PasswordRef), - Pass(Name), + Pass(Name, Option), UnPass(Name), Correct(Name), Uncorrect(Name), @@ -92,7 +92,7 @@ impl<'a> PartialEq for Command<'a> { (Command::Rm(s), Command::Rm(o)) => s == o, (Command::Enc(s), Command::Enc(o)) => s == o, (Command::Gen(a, b), Command::Gen(x, y)) => a == x && *b.lock() == *y.lock(), - (Command::Pass(s), Command::Pass(o)) => s == o, + (Command::Pass(a, b), Command::Pass(x, y)) => a == x && b == y, (Command::UnPass(s), Command::UnPass(o)) => s == o, (Command::Correct(s), Command::Correct(o)) => s == o, (Command::Uncorrect(s), Command::Uncorrect(o)) => s == o,