From 5df67e772caec28122a4e23371579f48eedac9ab Mon Sep 17 00:00:00 2001 From: TheAwiteb Date: Fri, 29 Dec 2023 08:18:57 +0300 Subject: [PATCH 1/3] Add `export` command --- src/cli/export_command.rs | 63 ++++++++++++++++++++++++++++++++++ src/cli/mod.rs | 2 ++ src/password/bitwarden.rs | 71 +++++++++++++++++++++++++++++++++++++++ src/password/mod.rs | 29 ++++++++-------- 4 files changed, 151 insertions(+), 14 deletions(-) create mode 100644 src/cli/export_command.rs create mode 100644 src/password/bitwarden.rs diff --git a/src/cli/export_command.rs b/src/cli/export_command.rs new file mode 100644 index 0000000..d332b91 --- /dev/null +++ b/src/cli/export_command.rs @@ -0,0 +1,63 @@ +// Local CLI password manager +// Copyright (C) 2024 Awiteb +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +use std::{fs, path::PathBuf}; + +use clap::{Args, ValueEnum}; + +use crate::{ + password::{BitWardenPasswords, Passwords}, + LprsError, LprsResult, RunCommand, +}; + +#[derive(Clone, Debug, ValueEnum)] +pub enum ExportFormat { + Lprs, + BitWarden, +} + +#[derive(Debug, Args)] +#[command(author, version, about, long_about = None)] +pub struct Export { + /// The path to export to + path: PathBuf, + /// Format to export passwords in + #[arg(short, long, value_name = "FORMAT", default_value_t= ExportFormat::Lprs)] + format: ExportFormat, +} + +impl ToString for ExportFormat { + fn to_string(&self) -> String { + self.to_possible_value() + .expect("There is no skiped values") + .get_name() + .to_owned() + } +} + +impl RunCommand for Export { + fn run(&self, password_manager: Passwords) -> LprsResult<()> { + let exported_data = match self.format { + ExportFormat::Lprs => serde_json::to_string(&password_manager.encrypt()?.passwords), + ExportFormat::BitWarden => { + serde_json::to_string(&BitWardenPasswords::from(password_manager)) + } + } + .map_err(LprsError::from)?; + + fs::write(&self.path, exported_data).map_err(LprsError::from) + } +} diff --git a/src/cli/mod.rs b/src/cli/mod.rs index d9aa12e..f36890f 100644 --- a/src/cli/mod.rs +++ b/src/cli/mod.rs @@ -26,6 +26,7 @@ use crate::{ pub mod add_command; pub mod clean_command; pub mod edit_command; +pub mod export_command; pub mod gen_command; pub mod list_command; pub mod remove_command; @@ -38,6 +39,7 @@ crate::create_commands!( "Clean the password file", Clean => clean_command::Clean "Edit the password content", Edit => edit_command::Edit "Generate password", Gen => gen_command::Gen + "Export the passwords", Export => export_command::Export // TODO: Export command // TODO: Import command ); diff --git a/src/password/bitwarden.rs b/src/password/bitwarden.rs new file mode 100644 index 0000000..5a89ce4 --- /dev/null +++ b/src/password/bitwarden.rs @@ -0,0 +1,71 @@ +use serde::{Deserialize, Serialize}; + +use super::{Password, Passwords}; + +#[derive(Clone, Debug, Deserialize, Serialize)] +pub struct BitWardenLoginData { + pub username: String, + pub password: String, + pub uris: Option>, +} + +#[derive(Clone, Debug, Deserialize, Serialize)] +pub struct BitWardenUri { + #[serde(rename = "match")] + pub mt: Option, + pub uri: String, +} + +#[derive(Default, Deserialize, Serialize)] +pub struct BitWardenFolder { + pub id: String, + pub name: String, +} + +#[derive(Clone, Debug, Deserialize, Serialize)] +pub struct BitWardenPassword { + #[serde(rename = "type")] + pub ty: i32, + pub name: String, + pub login: BitWardenLoginData, + pub notes: Option, +} + +/// The bitwarden password struct +#[derive(Default, Deserialize, Serialize)] +pub struct BitWardenPasswords { + pub encrypted: bool, + pub folders: Vec, + pub items: Vec, +} + +impl From for BitWardenPassword { + fn from(value: Password) -> Self { + Self { + ty: 1, + name: value.name, + login: BitWardenLoginData { + username: value.username, + password: value.password, + uris: value + .service + .map(|s| vec![BitWardenUri { mt: None, uri: s }]), + }, + notes: value.note, + } + } +} + +impl From for BitWardenPasswords { + fn from(value: Passwords) -> Self { + Self { + encrypted: false, + folders: Vec::new(), + items: value + .passwords + .into_iter() + .map(BitWardenPassword::from) + .collect(), + } + } +} diff --git a/src/password/mod.rs b/src/password/mod.rs index f50873b..fbbaeb3 100644 --- a/src/password/mod.rs +++ b/src/password/mod.rs @@ -22,23 +22,13 @@ use serde::{Deserialize, Serialize}; use crate::{LprsError, LprsResult}; pub mod cipher; + +mod bitwarden; mod validator; +pub use bitwarden::*; pub use validator::*; -/// The passwords manager -#[derive(Default, Deserialize, Serialize)] -pub struct Passwords { - /// Hash of the master password - #[serde(skip)] - pub master_password: Vec, - /// The json passwords file - #[serde(skip)] - pub passwords_file: PathBuf, - /// The passwords - pub passwords: Vec, -} - /// The password struct #[serde_with_macros::skip_serializing_none] #[derive(Clone, Debug, Deserialize, Serialize, Parser)] @@ -60,6 +50,17 @@ pub struct Password { pub note: Option, } +/// The passwords manager +#[derive(Default)] +pub struct Passwords { + /// Hash of the master password + pub master_password: Vec, + /// The json passwords file + pub passwords_file: PathBuf, + /// The passwords + pub passwords: Vec, +} + impl Password { /// Encrypt the password data pub fn encrypt(self, master_password: &[u8]) -> LprsResult { @@ -111,7 +112,7 @@ impl Passwords { } /// Encrypt the passwords - fn encrypt(self) -> LprsResult { + pub fn encrypt(self) -> LprsResult { Ok(Self { passwords: self .passwords From 0f78b13cb8889c24ac28e404db27a8edb1180766 Mon Sep 17 00:00:00 2001 From: TheAwiteb Date: Fri, 29 Dec 2023 08:47:29 +0300 Subject: [PATCH 2/3] Update README.md --- README.md | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index fb81d5a..2f30065 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ Lprs is a local password manager designed to securely store and manage your pass To install Lprs, you will need to have the Cargo package manager installed. If you do not have Cargo installed, you can install it by following the instructions [here](https://doc.rust-lang.org/cargo/getting-started/installation.html). Note the Minimum Supported Rust Version (MSRV) for Lprs is `1.70.0`. -1. Clone the Lprs repository: +1. Install using [cargo-install](https://doc.rust-lang.org/cargo/commands/cargo-install.html): ```bash cargo install --locked --git https://github.com/theawiteb/lprs.git ``` @@ -31,13 +31,14 @@ Local CLI password manager Usage: lprs [OPTIONS] Commands: - add Add new password + add Add new password remove Remove password - list List your password and search - clean Clean the password file - edit Edit the password content - gen Generate password - help Print this message or the help of the given subcommand(s) + list List your password and search + clean Clean the password file + edit Edit the password content + gen Generate password + export Export the passwords + help Print this message or the help of the given subcommand(s) Options: -p, --passwords-file @@ -66,10 +67,16 @@ Master Password: *************** ``` - +It is important to regularly backup your passwords to prevent data loss. Lprs does not provide an automatic backup feature. To backup your passwords, you can use the `export` command provided by Lprs. This command allows you to export your encrypted passwords to a json file, which you can then manually backup to a secure location. + +#### Formats +The format of the exported file can be specified using the `--format` option. The following formats are supported: + +- `lprs`: The default format used by Lprs. This format is encrypted and can be imported back into Lprs using the `import` command. This is the recommended format to use for backups as it is encrypted and can be imported back into Lprs. +- `bit-warden`: The format used by [Bitwarden](https://bitwarden.com/). This format is not encrypted and can be imported into Bitwarden. This format is useful if you want to switch to Bitwarden or another password manager that supports this format. + ## Contributing From 07df4826e6c553c1a4d4297c14ca34889bb5a47e Mon Sep 17 00:00:00 2001 From: TheAwiteb Date: Fri, 29 Dec 2023 08:53:05 +0300 Subject: [PATCH 3/3] Update the Lprs description --- Cargo.toml | 2 +- README.md | 2 +- src/cli/add_command.rs | 2 +- src/cli/clean_command.rs | 2 +- src/cli/edit_command.rs | 2 +- src/cli/export_command.rs | 2 +- src/cli/gen_command.rs | 2 +- src/cli/list_command.rs | 2 +- src/cli/mod.rs | 2 +- src/cli/remove_command.rs | 2 +- src/errors.rs | 2 +- src/macros.rs | 2 +- src/main.rs | 2 +- src/password/cipher.rs | 2 +- src/password/mod.rs | 2 +- src/password/validator.rs | 2 +- src/traits.rs | 2 +- src/utils.rs | 2 +- 18 files changed, 18 insertions(+), 18 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index b539277..7507bc0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,7 +5,7 @@ edition = "2021" license = "GPL-3.0-only" authors = ["Awiteb "] readme = "README.md" -description = "Local CLI password manager" +description = "A local CLI password manager" repository = "https://github.com/TheAwiteb/lprs" rust-version = "1.70.0" keywords = ["password", "manager", "CLI"] diff --git a/README.md b/README.md index 2f30065..fea0130 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ cargo uninstall lprs Lprs provides a command-line interface for managing your passwords. The following commands are available: ``` -Local CLI password manager +A local CLI password manager Usage: lprs [OPTIONS] diff --git a/src/cli/add_command.rs b/src/cli/add_command.rs index ff47213..91e5125 100644 --- a/src/cli/add_command.rs +++ b/src/cli/add_command.rs @@ -1,4 +1,4 @@ -// Local CLI password manager +// Lprs - A local CLI password manager // Copyright (C) 2024 Awiteb // // This program is free software: you can redistribute it and/or modify diff --git a/src/cli/clean_command.rs b/src/cli/clean_command.rs index 2104359..9c6defd 100644 --- a/src/cli/clean_command.rs +++ b/src/cli/clean_command.rs @@ -1,4 +1,4 @@ -// Local CLI password manager +// Lprs - A local CLI password manager // Copyright (C) 2024 Awiteb // // This program is free software: you can redistribute it and/or modify diff --git a/src/cli/edit_command.rs b/src/cli/edit_command.rs index be3ca79..3143f92 100644 --- a/src/cli/edit_command.rs +++ b/src/cli/edit_command.rs @@ -1,4 +1,4 @@ -// Local CLI password manager +// Lprs - A local CLI password manager // Copyright (C) 2024 Awiteb // // This program is free software: you can redistribute it and/or modify diff --git a/src/cli/export_command.rs b/src/cli/export_command.rs index d332b91..531d613 100644 --- a/src/cli/export_command.rs +++ b/src/cli/export_command.rs @@ -1,4 +1,4 @@ -// Local CLI password manager +// Lprs - A local CLI password manager // Copyright (C) 2024 Awiteb // // This program is free software: you can redistribute it and/or modify diff --git a/src/cli/gen_command.rs b/src/cli/gen_command.rs index 52c0019..579f6fa 100644 --- a/src/cli/gen_command.rs +++ b/src/cli/gen_command.rs @@ -1,4 +1,4 @@ -// Local CLI password manager +// Lprs - A local CLI password manager // Copyright (C) 2024 Awiteb // // This program is free software: you can redistribute it and/or modify diff --git a/src/cli/list_command.rs b/src/cli/list_command.rs index 1f21708..235d0dc 100644 --- a/src/cli/list_command.rs +++ b/src/cli/list_command.rs @@ -1,4 +1,4 @@ -// Local CLI password manager +// Lprs - A local CLI password manager // Copyright (C) 2024 Awiteb // // This program is free software: you can redistribute it and/or modify diff --git a/src/cli/mod.rs b/src/cli/mod.rs index f36890f..cff9531 100644 --- a/src/cli/mod.rs +++ b/src/cli/mod.rs @@ -1,4 +1,4 @@ -// Local CLI password manager +// Lprs - A local CLI password manager // Copyright (C) 2024 Awiteb // // This program is free software: you can redistribute it and/or modify diff --git a/src/cli/remove_command.rs b/src/cli/remove_command.rs index 79ffc10..a7c3ab0 100644 --- a/src/cli/remove_command.rs +++ b/src/cli/remove_command.rs @@ -1,4 +1,4 @@ -// Local CLI password manager +// Lprs - A local CLI password manager // Copyright (C) 2024 Awiteb // // This program is free software: you can redistribute it and/or modify diff --git a/src/errors.rs b/src/errors.rs index 05d6265..4ed1966 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -1,4 +1,4 @@ -// Local CLI password manager +// Lprs - A local CLI password manager // Copyright (C) 2024 Awiteb // // This program is free software: you can redistribute it and/or modify diff --git a/src/macros.rs b/src/macros.rs index bfa7955..aa4f23f 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -1,4 +1,4 @@ -// Local CLI password manager +// Lprs - A local CLI password manager // Copyright (C) 2024 Awiteb // // This program is free software: you can redistribute it and/or modify diff --git a/src/main.rs b/src/main.rs index c19d1db..147e477 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,4 @@ -// Local CLI password manager +// Lprs - A local CLI password manager // Copyright (C) 2024 Awiteb // // This program is free software: you can redistribute it and/or modify diff --git a/src/password/cipher.rs b/src/password/cipher.rs index ecd3749..68572af 100644 --- a/src/password/cipher.rs +++ b/src/password/cipher.rs @@ -1,4 +1,4 @@ -// Local CLI password manager +// Lprs - A local CLI password manager // Copyright (C) 2024 Awiteb // // This program is free software: you can redistribute it and/or modify diff --git a/src/password/mod.rs b/src/password/mod.rs index fbbaeb3..f5693a0 100644 --- a/src/password/mod.rs +++ b/src/password/mod.rs @@ -1,4 +1,4 @@ -// Local CLI password manager +// Lprs - A local CLI password manager // Copyright (C) 2024 Awiteb // // This program is free software: you can redistribute it and/or modify diff --git a/src/password/validator.rs b/src/password/validator.rs index c4f28ea..e39b34e 100644 --- a/src/password/validator.rs +++ b/src/password/validator.rs @@ -1,4 +1,4 @@ -// Local CLI password manager +// Lprs - A local CLI password manager // Copyright (C) 2024 Awiteb // // This program is free software: you can redistribute it and/or modify diff --git a/src/traits.rs b/src/traits.rs index e3a1c5e..55a67be 100644 --- a/src/traits.rs +++ b/src/traits.rs @@ -1,4 +1,4 @@ -// Local CLI password manager +// Lprs - A local CLI password manager // Copyright (C) 2024 Awiteb // // This program is free software: you can redistribute it and/or modify diff --git a/src/utils.rs b/src/utils.rs index fbb9525..979ea26 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,4 +1,4 @@ -// Local CLI password manager +// Lprs - A local CLI password manager // Copyright (C) 2024 Awiteb // // This program is free software: you can redistribute it and/or modify