Browse Source

storage & git begin

fix-typo
Coin de Gamma 3 months ago
parent
commit
4190c93e9e
  1. 1
      Cargo.toml
  2. 14
      README.md
  3. 35
      src/main.rs
  4. 69
      src/storage.rs

1
Cargo.toml

@ -9,7 +9,6 @@ edition = "2021"
aes-gcm = "0.10.3"
clap = { version = "4.5.16", features = ["derive"] }
hex = "0.4.3"
once_cell = "1.19.0"
rpassword = "7.3.1"
tempfile = "3.12.0"

14
README.md

@ -1,3 +1,13 @@
# mps
# MPS
A small tool for storing passwords locally with git sync
## Installation
1. Create empty repository for storing your passwords on gitlab or somewhere you prefer
2. Clone to your home folder ~/.mps/storage
3. Set variable $MPS_HOME="~/.mps/"
4. Add to your $PATH:<path_to_msp> where you installed your mps
5. Run ./mps init
A small tool for storing passwords locally with git sync

35
src/main.rs

@ -78,20 +78,41 @@ impl MPS {
MPS { storage: None }
}
fn init() -> io::Result<()> {
if Storage::is_inited() {
return Err(io::Error::new(io::ErrorKind::AlreadyExists, "Reinitialization attempted"));
}
fn prompt_new_password() -> io::Result<String> {
print!("Enter passphrase for storage: ");
io::stdout().flush()?;
let ps = rpassword::read_password()?;
if ps.len() < 8 {
return Err(io::Error::new(io::ErrorKind::InvalidInput, "Passphrase must be longet that 8 letters"));
}
if ps.len() > 32 {
return Err(io::Error::new(io::ErrorKind::InvalidInput, "Passphrase must be shorted that 32 letters"));
}
print!("Reenter passphrase: ");
io::stdout().flush()?;
let ps2 = rpassword::read_password()?;
if ps != ps2 {
return Err(io::Error::new(io::ErrorKind::InvalidInput, "Passphrases must be equal"));
}
Storage::init(ps)?;
Ok(ps)
}
fn init() -> io::Result<()> {
if Storage::is_inited()? {
return Err(io::Error::new(io::ErrorKind::AlreadyExists, "Reinitialization attempted"));
}
let mut passphrase = String::from("");
loop {
match MPS::prompt_new_password() {
Ok(ps) => {
passphrase = ps;
break;
},
Err(_) => continue
}
}
Storage::init(passphrase)?;
Ok(())
}
@ -200,10 +221,10 @@ fn run_command() -> io::Result<()> {
mps.edit(id)?
}
None => {
if !Storage::is_inited() {
if !Storage::is_inited()? {
match get_prompt("Do you want to init your storage?")? {
PROMPT::YES => MPS::init()?,
PROMPT::NO => Storage::print_init_hint(),
PROMPT::NO => Storage::print_init_hint()?,
}
} else {
let mut mps = MPS::new();

69
src/storage.rs

@ -2,11 +2,10 @@ use crate::encoder;
use encoder::Encoder;
use once_cell::sync::Lazy;
use std::collections::HashSet;
use std::hash::{Hash, Hasher};
use std::env;
use std::fs;
use std::path::Path;
use std::io::{self, Write, BufRead};
@ -14,10 +13,10 @@ use std::fmt;
use std::cmp::{PartialEq, Ordering};
static STORAGE_FOLDER: Lazy<String> = Lazy::new(|| "storage".to_string() );
static STORAGE_PATH: Lazy<String> = Lazy::new(|| {
format!("{}/db.mps", &*STORAGE_FOLDER)
});
static ENV_MPS_HOME: &str = "MPS_HOME";
static PATH_STORAGE: &str = "storage"; // should be under git
static PATH_DB: &str = "db.mps";
#[derive(Clone)]
@ -82,15 +81,30 @@ impl Storage {
encoder: Encoder::from(&passphrase)
}
}
fn get_storage_path() -> io::Result<String> {
let mps_home = env::var(ENV_MPS_HOME).map_err(|err| {
io::Error::new(io::ErrorKind::NotFound, format!("{} error: {}", ENV_MPS_HOME, err))
})?;
let result = format!("{}/{}", mps_home, PATH_STORAGE);
Ok(result)
}
fn get_storage_db_path() -> io::Result<String> {
let st = Storage::get_storage_path()?;
let result = format!("{}/{}", st, PATH_DB);
Ok(result)
}
pub fn from_db(passphrase: String) -> io::Result<Storage> {
if !Storage::is_inited() {
if !Storage::is_inited()? {
return Err(io::Error::new(
io::ErrorKind::Other,
"Storage is not initialized"
));
}
let encoder = Encoder::from(&passphrase);
let file = fs::File::open(&*STORAGE_PATH)?;
let file = fs::File::open(Storage::get_storage_db_path()?)?;
let reader = io::BufReader::new(file);
let mut items = HashSet::<Item>::new();
let mut id: Option<String> = None;
@ -129,31 +143,36 @@ impl Storage {
}
pub fn init(passphrase: String) -> io::Result<()> {
fs::create_dir(&*STORAGE_FOLDER)?;
println!("Storage folder created");
fs::File::create(&*STORAGE_PATH)?;
let st = Storage::new(passphrase);
st.dump()?;
println!("Storage db created.");
println!("Initialization complete.");
println!("");
println!("Now it's required to add folder `{}` under git manually.", &*STORAGE_FOLDER);
println!("Don't worry it's going to be encrypted.");
// TODO: revrite all logic
// Check if the folder exists and is a directory
//if path.exists() && path.is_dir() {
// Err(io::Error::new(io::ErrorKind::NotFound, "Folder does not exist"))
//}
//fs::File::create(&*STORAGE_PATH)?;
//let st = Storage::new(passphrase);
//st.dump()?;
//println!("Storage db created.");
//println!("Initialization complete.");
//println!("");
//println!("Now it's required to add folder `{}` under git manually.", &*STORAGE_FOLDER);
//println!("Don't worry it's going to be encrypted.");
Ok(())
}
pub fn print_init_hint() {
pub fn print_init_hint() -> io::Result<()> {
println!("mps can work only when storage inited.");
println!("Hint: you can restore your storage if you have it already:");
println!(" git clone <your_storage_git_url> {}", &*STORAGE_FOLDER);
println!("to init manually your storage and config")
println!(" git clone <your_storage_git_url> {}", Storage::get_storage_path()?);
println!("to init manually your storage and config");
Ok(())
}
pub fn is_inited() -> bool {
pub fn is_inited() -> io::Result<bool> {
// TODO: check db
// TODO check git
let path = Path::new(&*STORAGE_FOLDER);
return path.exists();
//let path = Path::new(&*STORAGE_FOLDER);
//return path.exists();
Ok(true)
}
@ -189,7 +208,7 @@ impl Storage {
let mut file = fs::OpenOptions::new()
.write(true)
.append(false)
.open(&*STORAGE_PATH)?;
.open(Storage::get_storage_db_path()?)?;
writeln!(file, "{}", self.encoder.get_encoded_test_passphrase()?)?;
for item in self.items.iter() {

Loading…
Cancel
Save