Added enc and pass commands, change names of commands back to full.
This commit is contained in:
@@ -18,3 +18,4 @@ anyerror = "0.1.7"
|
||||
home = "0.5.4"
|
||||
sha1 = "0.10.5"
|
||||
base64 = "0.20.0"
|
||||
rpassword = "7.2.0"
|
||||
|
||||
@@ -6,6 +6,7 @@ use std::collections::HashMap;
|
||||
pub struct LK {
|
||||
pub db: HashMap<NameRef, PasswordRef>,
|
||||
pub ls: HashMap<String, PasswordRef>,
|
||||
pub secrets: HashMap<NameRef, String>,
|
||||
}
|
||||
|
||||
impl LK {
|
||||
@@ -13,6 +14,7 @@ impl LK {
|
||||
Self {
|
||||
db: HashMap::new(),
|
||||
ls: HashMap::new(),
|
||||
secrets: HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+18
-10
@@ -16,6 +16,8 @@ peg::parser! {
|
||||
/ ls_cmd()
|
||||
/ mv_cmd()
|
||||
/ rm_cmd()
|
||||
/ enc_cmd()
|
||||
/ pass_cmd()
|
||||
/ comment_cmd()
|
||||
) { c }
|
||||
|
||||
@@ -32,9 +34,13 @@ peg::parser! {
|
||||
{ Password::new(Some(pr), pn, pl, pm, 99, pd, pc) }
|
||||
rule sname() -> Password = &(word() _ num()? mode() _ date()) pn:word() _ pl:num()? pm:mode() _ pd:date() pc:comment()?
|
||||
{ Password::new(None, pn, pl, pm, 99, pd, pc) }
|
||||
rule ssname() -> Password = &(word()) pn:word()
|
||||
rule nname() -> Password = &(word() _ num()? mode()) pn:word() _ pl:num()? pm:mode()
|
||||
{ Password::new(None, pn, pl, pm, 99, Local::now().naive_local().date(), None) }
|
||||
rule qname() -> Password = &(word()) pn:word()
|
||||
{ Password::new(None, pn, None, Mode::NoSpaceCamel, 99, Local::now().naive_local().date(), None) }
|
||||
pub rule name() -> Password = name:(jname() / pname() / mname() / sname() / ssname())? {? match name { Some(n) => Ok(n), None => Err("failed to parse password description") } }
|
||||
pub rule name() -> Password = name:(jname() / pname() / mname() / sname() / nname() / qname())? {?
|
||||
match name { Some(n) => Ok(n), None => Err("failed to parse password description") }
|
||||
}
|
||||
|
||||
rule date() -> NaiveDate = y:$("-"? ['0'..='9']*<1,4>) "-" m:$(['0'..='9']*<1,2>) "-" d:$(['0'..='9']*<1,2>) {?
|
||||
let year: i32 = match y.parse() { Ok(n) => n, Err(_) => return Err("year") };
|
||||
@@ -51,7 +57,7 @@ peg::parser! {
|
||||
_ => Err("unknown mode"),
|
||||
}
|
||||
}
|
||||
rule rmode() -> Mode = m:$("R" / "r" / "U" / "u" / "N" / "n" / "C" / "H" / "h" / "B" / "b" / "D" / "d") {?
|
||||
rule rmode() -> Mode = m:$("R" / "r" / "U" / "u" / "N" / "n" / "C" / "c" / "H" / "h" / "B" / "b" / "D" / "d") {?
|
||||
match m.to_uppercase().as_str() {
|
||||
"R" => Ok(Mode::Regular),
|
||||
"N" => Ok(Mode::NoSpace),
|
||||
@@ -64,14 +70,16 @@ peg::parser! {
|
||||
}
|
||||
}
|
||||
rule mode() -> Mode = m:(umode() / rmode()) { m }
|
||||
rule help_cmd() -> Command<'input> = "h" { Command::Help }
|
||||
rule quit_cmd() -> Command<'input> = "q" { Command::Quit }
|
||||
rule ls_cmd() -> Command<'input> = "l" { Command::Ls }
|
||||
rule add_cmd() -> Command<'input> = "a" _ name:name() { Command::Add(Rc::new(RefCell::new(name))) }
|
||||
rule help_cmd() -> Command<'input> = "help" { Command::Help }
|
||||
rule quit_cmd() -> Command<'input> = "quit" { Command::Quit }
|
||||
rule ls_cmd() -> Command<'input> = "ls" { Command::Ls }
|
||||
rule add_cmd() -> Command<'input> = "add" _ name:name() { Command::Add(Rc::new(RefCell::new(name))) }
|
||||
rule error_cmd() -> Command<'input> = "error" _ e:$(([' '..='~'])+) { Command::Error(LKErr::Error(e)) }
|
||||
rule mv_cmd() -> Command<'input> = "m" _ name:word() _ folder:word() { Command::Mv(name, folder) }
|
||||
rule rm_cmd() -> Command<'input> = "r" _ name:word() { Command::Rm(name) }
|
||||
rule comment_cmd() -> Command<'input> = "c" _ name:word() c:comment()? { Command::Comment(name, c) }
|
||||
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 enc_cmd() -> Command<'input> = "enc" _ name:word() { Command::Enc(name) }
|
||||
rule rm_cmd() -> Command<'input> = "rm" _ name:word() { Command::Rm(name) }
|
||||
rule comment_cmd() -> Command<'input> = "comment" _ name:word() c:comment()? { Command::Comment(name, c) }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+80
-15
@@ -1,4 +1,5 @@
|
||||
use home::home_dir;
|
||||
use rpassword::prompt_password;
|
||||
use rustyline::Editor;
|
||||
use std::{cell::RefCell, rc::Rc};
|
||||
|
||||
@@ -84,7 +85,60 @@ impl<'a> LKEval<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
fn cmd_ls(&mut self, out: &mut Vec<String>) {
|
||||
fn read_master(&self, pwd: PasswordRef) -> String {
|
||||
let parent = match &pwd.borrow().parent {
|
||||
Some(p) => p.borrow().name.clone(),
|
||||
None => Rc::new("/".to_string()),
|
||||
};
|
||||
let secret = match self.state.borrow().secrets.get(&parent) {
|
||||
Some(p) => Some(p.clone()),
|
||||
None => None,
|
||||
};
|
||||
match (pwd.borrow().parent.clone(), secret) {
|
||||
(_, Some(s)) => s.to_string(),
|
||||
(None, None) => {
|
||||
let password = prompt_password("Master: ").unwrap();
|
||||
self.state.borrow_mut().secrets.insert(Rc::new("/".to_string()), password.clone());
|
||||
password
|
||||
}
|
||||
(Some(pn), None) => {
|
||||
let password = prompt_password(format!("Password for {}: ", pn.borrow().name)).unwrap();
|
||||
if password.len() > 0 {
|
||||
self.state.borrow_mut().secrets.insert(pn.borrow().name.clone(), password.clone());
|
||||
password
|
||||
} else {
|
||||
let master = self.read_master(pn.clone());
|
||||
let password = pn.borrow().encode(master.as_str());
|
||||
self.state.borrow_mut().secrets.insert(pn.borrow().name.clone(), password.clone());
|
||||
password
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn cmd_enc(&self, out: &mut Vec<String>, name: &String) {
|
||||
let root_folder = Rc::new("/".to_string());
|
||||
if name == "/" && self.state.borrow().secrets.contains_key(&root_folder) {
|
||||
out.push(self.state.borrow().secrets.get(&root_folder).unwrap().to_string());
|
||||
return;
|
||||
}
|
||||
let pwd = match self.get_password(name) {
|
||||
Some(p) => p.clone(),
|
||||
None => {
|
||||
out.push(format!("error: name {} not found", name));
|
||||
return;
|
||||
}
|
||||
};
|
||||
let name = pwd.borrow().name.clone();
|
||||
if self.state.borrow().secrets.contains_key(&name) {
|
||||
out.push(self.state.borrow().secrets.get(&name).unwrap().to_string());
|
||||
return;
|
||||
}
|
||||
let sec = self.read_master(pwd.clone());
|
||||
out.push(pwd.borrow().encode(sec.as_str()));
|
||||
}
|
||||
|
||||
fn cmd_ls(&self, out: &mut Vec<String>) {
|
||||
let mut tmp: Vec<PasswordRef> = vec![];
|
||||
for (_, name) in &self.state.borrow().db {
|
||||
tmp.push(name.clone());
|
||||
@@ -100,7 +154,7 @@ impl<'a> LKEval<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn eval(&mut self) -> LKPrint {
|
||||
pub fn eval(&self) -> LKPrint {
|
||||
let mut out: Vec<String> = vec![];
|
||||
let mut quit: bool = false;
|
||||
|
||||
@@ -134,27 +188,38 @@ impl<'a> LKEval<'a> {
|
||||
}
|
||||
None => out.push("error: password not found".to_string()),
|
||||
},
|
||||
Command::Enc(name) => self.cmd_enc(&mut out, name),
|
||||
Command::Pass(name) => match self.get_password(name) {
|
||||
Some(p) => {
|
||||
self.state.borrow_mut().secrets.insert(p.borrow().name.clone(), prompt_password(format!("Password for {}: ", p.borrow().name)).unwrap());
|
||||
}
|
||||
None => {
|
||||
if name == "/" {
|
||||
self.state.borrow_mut().secrets.insert(Rc::new("/".to_string()), prompt_password("Master: ").unwrap());
|
||||
} else {
|
||||
out.push(format!("error: password with name {} not found", name));
|
||||
}
|
||||
}
|
||||
},
|
||||
Command::Help => {
|
||||
out.push("HELP".to_string());
|
||||
}
|
||||
Command::Mv(name, folder) => {
|
||||
for (_, tmp) in &self.state.borrow().db {
|
||||
if *tmp.borrow().name == *name {
|
||||
Command::Mv(name, folder) => match self.get_password(name) {
|
||||
Some(pwd) => {
|
||||
if folder == "/" {
|
||||
tmp.borrow_mut().parent = None
|
||||
pwd.borrow_mut().parent = None
|
||||
} else {
|
||||
for (_, fld) in &self.state.borrow().db {
|
||||
if *fld.borrow().name == *folder {
|
||||
tmp.borrow_mut().parent = Some(fld.clone());
|
||||
fix_password_recursion(tmp.clone());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
match self.get_password(folder) {
|
||||
Some(fld) => {
|
||||
pwd.borrow_mut().parent = Some(fld.clone());
|
||||
fix_password_recursion(pwd.clone());
|
||||
}
|
||||
None => out.push(format!("error: folder {} not found", folder)),
|
||||
}
|
||||
}
|
||||
}
|
||||
None => out.push(format!("error: password with name {} not found", name)),
|
||||
},
|
||||
Command::Error(err) => match err {
|
||||
LKErr::ParseError(e) => out.push(e.to_string()),
|
||||
LKErr::ReadError(e) => out.push(e.to_string()),
|
||||
|
||||
@@ -17,6 +17,8 @@ pub enum Command<'a> {
|
||||
Ls,
|
||||
Mv(Name, Name),
|
||||
Rm(Name),
|
||||
Enc(Name),
|
||||
Pass(Name),
|
||||
Comment(Name, Comment),
|
||||
Error(LKErr<'a>),
|
||||
Help,
|
||||
@@ -108,3 +110,21 @@ impl fmt::Display for Radix {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
impl fmt::Display for Radix {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let sign = if self.x < 0 { '-' } else { ' ' };
|
||||
let mut x: u32 = self.x.abs() as u32;
|
||||
write!(f, "{}{}", sign, (0..).map(|_| {
|
||||
let m = x % self.radix;
|
||||
x /= self.radix;
|
||||
(x, std::char::from_digit(m, self.radix).unwrap())
|
||||
})
|
||||
.take_while(|a| a.0 > 0).map(|b| b.1).collect::<String>()
|
||||
.chars().rev().collect::<String>()
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user