feat: init commit

This commit is contained in:
2023-10-15 00:19:02 +08:00
parent 3c833e9574
commit 9c9abd1def
5 changed files with 157 additions and 0 deletions

1
.gitignore vendored
View File

@@ -1,3 +1,4 @@
.idea/
# ---> Rust
# Generated by Cargo
# will have compiled files and executables

14
Cargo.toml Normal file
View File

@@ -0,0 +1,14 @@
[package]
name = "local-stored-password"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
rust_util = "0.6.42"
[target.'cfg(any(windows, unix))'.dependencies]
rpassword = "7.2.0"
dirs = "5.0.1"

7
src/home.rs Normal file
View File

@@ -0,0 +1,7 @@
#[cfg(any(windows, unix))]
pub(crate) use dirs::home_dir as get_home_dir;
#[cfg(not(any(windows, unix)))]
pub(crate) fn get_home_dir() -> Option<PathBuf> {
Some(PathBuf::from("."))
}

132
src/lib.rs Normal file
View File

@@ -0,0 +1,132 @@
use std::{fs, io};
use std::fs::create_dir;
use std::io::Write;
use std::path::PathBuf;
use rust_util::{information, opt_result, simple_error, warning, XResult};
mod home;
const STORED_PASSWORD_DIR: &str = ".stored_passwords";
const STORED_PASSWORD_EXT: &str = ".spass";
enum StoredPasswordType {
Hmac,
HmacWithPass,
}
struct StoredPasswordBody {
ty: String,
content: String,
}
pub fn read_stored_password() -> XResult<Option<String>> {
let stored_pass_files = list_stored_passwords()?;
if stored_pass_files.is_empty() {
return Ok(None);
}
information!("Found {} stored passwords:", stored_pass_files.len());
for (i, entry) in stored_pass_files.iter().enumerate() {
println!("#{} : {}", (i + 1), entry.display());
}
let num = read_number("Please select(0 for skip)", 0, stored_pass_files.len() + 1);
if num == 0 { return Ok(None); }
let pass_file = &stored_pass_files[num - 1];
// TODO ...
Ok(None)
}
pub fn write_stored_password() {
// TODO ...
}
fn read_number(hint: &str, from: usize, to: usize) -> usize {
loop {
print!("{} ({}-{}): ", hint, from, to);
io::stdout().flush().ok();
let mut buff = String::new();
let _ = io::stdin().read_line(&mut buff).expect("Read line from stdin");
let buff = buff.trim();
match buff.parse() {
Err(_) => warning!("Input number error!"),
Ok(number) => if number < from || number > to {
warning!("Input number is not in range.");
} else {
return number;
},
}
}
}
fn list_stored_passwords() -> XResult<Vec<PathBuf>> {
let dir = get_stored_password_dir()?;
if !dir.is_dir() {
return Ok(vec![]);
}
let read_dir = match fs::read_dir(dir) {
Ok(read_dir) => read_dir,
Err(e) => return simple_error!("can't read dir: {}", dir.display()),
};
let mut stored_pass_files = vec![];
for entry in read_dir {
if let Ok(entry) = entry {
let path = entry.path();
if path.is_file() && path.display().to_string().ends_with(STORED_PASSWORD_EXT) {
stored_pass_files.push(path);
}
}
}
stored_pass_files.sort();
Ok(stored_pass_files)
}
fn extract_password_name(file: &PathBuf) -> XResult<String> {
let filename = file.display().to_string();
if !filename.ends_with(STORED_PASSWORD_EXT) {
return simple_error!("Not a stored password file: {}", filename);
}
Ok("".to_string())
}
fn decode_filename(filename: &str) -> XResult<String> {
if filename.starts_with("E") {
// TODO ...
Ok("".to_string())
} else if filename.starts_with("e") {
Ok(filename.chars().skip(1).collect())
} else {
Ok(filename.to_string())
}
}
fn encode_filename(filename: &str) -> String {
let need_encode = !filename.chars().filter(|c| {
let lower = *c >= 'a' && *c <= 'z';
let upper = *c >= 'A' && *c <= 'Z';
let digit = *c >= '0' && *c <= '9';
let other_chars = match *c {
'-' | '_' | '.' => true,
_ => false,
};
!lower && !upper && !digit && !other_chars
}).collect::<Vec<_>>().is_empty();
if need_encode {
// TODO ...
format!("E"{}, filename)
} else {
format!("e{}", filename)
}
}
fn get_stored_password_dir() -> XResult<PathBuf> {
let home_path = opt_result!(get_home_dir(), "can't find home dir: {}");
let mut complete_path = home_path;
complete_path.push(STORED_PASSWORD_DIR);
if !complete_path.exists() {
create_dir(&complete_path)?;
}
Ok(complete_path)
}

3
src/main.rs Normal file
View File

@@ -0,0 +1,3 @@
fn main() {
println!("Hello, world!");
}