1extern crate core;
6
7mod pwsfile;
8pub mod pwserrors;
9pub mod pwsdb;
10mod util;
11
12use std::collections::HashSet;
13use std::fs::File;
14use std::io::Read;
15use std::path::{Path, PathBuf};
16use std::slice::Iter;
17use crate::pwsdb::PwDb;
18use crate::pwsdb::record::DbRecord;
19use crate::pwserrors::PwSafeError;
20use crate::pwsfile::{PwSafeEncrypted, PwSafeTransition};
21use crate::PwSafeError::{FailedToOpenFile, FileNotFound, FileReadError};
22const BLOCK_SIZE: usize = 16;
24
25
26#[derive(Debug)]
45pub struct PwFile {
46 pub path: PathBuf,
47 pub db: PwDb,
48 s: PwSafeEncrypted,
49 pub is_open: bool,
50 pub is_valid: bool
51}
52
53impl PwFile {
54 pub fn iter(&self) -> Iter<DbRecord> {
56 self.db.records.iter()
57 }
58 pub fn groups(&self) -> HashSet<String> {
60 let mut groups = HashSet::new();
61 for record in &self.db.records {
62 if let Some(g) = record.group() {
63 groups.insert(g);
64 }
65 }
66 groups
67 }
68 pub fn by_broup(&self, group: String) -> Vec<&DbRecord> {
70 self.iter().filter(| &r | r.group().is_some())
71 .filter(| &r | r.group().unwrap() == group).collect::<Vec<&DbRecord>>()
72 }
73 pub fn unlock(&mut self, phrase: &str) -> Result<(), PwSafeError> {
75 let trans = self.s.prepare_db(phrase.to_string())?;
76 self.db = trans.try_into()?;
77 Ok(())
78 }
79
80 pub fn open(file_name: &str) -> Result<PwFile, PwSafeError> {
82 let path = Path::new(file_name);
83 if !path.exists() {
84 return Err(FileNotFound)
85 }
86 let mut fs = match File::open(file_name) {
87 Ok(fs) => fs,
88 Err(_) => return Err(FailedToOpenFile)
89 };
90 let mut buff = Vec::new();
91 let _ = match fs.read_to_end(&mut buff) {
92 Ok(s) => s,
93 Err(_) => return Err(FileReadError)
94 };
95
96 let mut safe = PwSafeEncrypted::new();
97 safe.check_format(&buff)?;
98 safe.load(&buff)?;
99 Ok(PwFile {
100 is_open: true,
101 is_valid: true,
102 s: safe,
103 db: PwDb::new(),
104 path: path.to_path_buf()
105 })
106 }
107}
108
109impl TryFrom<PwSafeTransition> for PwDb {
110 type Error = PwSafeError;
111
112 fn try_from(value: PwSafeTransition) -> Result<Self, Self::Error> {
113 let mut db = PwDb{
114 header: vec![],
115 records: vec![],
116 hmac: Some(value.hmac),
117 sig: value.sig
118 };
119 db.load(value.plt)?;
120 Ok(db)
121 }
122}