mirror of
https://github.com/nishiki/manage-password.git
synced 2025-02-22 10:50:10 +00:00
merge text_editor branch
This commit is contained in:
commit
50a75450fd
24 changed files with 1230 additions and 715 deletions
128
README.md
128
README.md
|
@ -1,128 +0,0 @@
|
||||||
# Manage your passwords!
|
|
||||||
|
|
||||||
MPW is a little software which stores your passwords in an GPG encrypted file.
|
|
||||||
MPW can synchronize your password with SSH or FTP.
|
|
||||||
|
|
||||||
# Installation
|
|
||||||
|
|
||||||
This program work with ruby >= 2.0
|
|
||||||
|
|
||||||
* install ruby and rubygems on your computer
|
|
||||||
* install xclip
|
|
||||||
* gem install mpw
|
|
||||||
|
|
||||||
# How to use
|
|
||||||
|
|
||||||
* Show help
|
|
||||||
```
|
|
||||||
mpw --help
|
|
||||||
```
|
|
||||||
|
|
||||||
* Setup a new config file
|
|
||||||
```
|
|
||||||
mpw --setup
|
|
||||||
mpw --setup --config /path/conf/file.cfg
|
|
||||||
```
|
|
||||||
|
|
||||||
* Create and setup a new wallet
|
|
||||||
```
|
|
||||||
mpw --setup-wallet --wallet new_wallet_name
|
|
||||||
mpw --setup-wallet --wallet new_wallet_name --config /path/conf/file.cfg
|
|
||||||
```
|
|
||||||
|
|
||||||
* Add a GPG key in wallet
|
|
||||||
```
|
|
||||||
mpw --add --key root@localhost.local
|
|
||||||
mpw --add --key root@localhost.local --config /path/conf/file.cfg
|
|
||||||
mpw --add --key root@localhost.local --wallet wallet_name
|
|
||||||
mpw --add --key root@localhost.local --config /path/conf/file.cfg --wallet wallet_name
|
|
||||||
```
|
|
||||||
|
|
||||||
* Add a new GPG key in wallet
|
|
||||||
```
|
|
||||||
mpw --add --key root@localhost.local --file /path/gpg/file.pub
|
|
||||||
mpw --add --key root@localhost.local --file /path/gpg/file.pub --config /path/conf/file.cfg
|
|
||||||
mpw --add --key root@localhost.local --file /path/gpg/file.pub --wallet wallet_name
|
|
||||||
mpw --add --key root@localhost.local --file /path/gpg/file.pub --config /path/conf/file.cfg --wallet wallet_name
|
|
||||||
```
|
|
||||||
|
|
||||||
* Delete a GPG key in wallet
|
|
||||||
```
|
|
||||||
mpw --delete --key root@localhost.local
|
|
||||||
mpw --delete --key root@localhost.local --wallet wallet_name
|
|
||||||
mpw --delete --key root@localhost.local --wallet wallet_name --config /path/conf/file.cfg
|
|
||||||
```
|
|
||||||
|
|
||||||
* Add a new item in wallet
|
|
||||||
```
|
|
||||||
mpw --add
|
|
||||||
mpw --add --config /path/conf/file.cfg
|
|
||||||
mpw --add --wallet wallet_name
|
|
||||||
mpw --add --config /path/conf/file.cfg --wallet wallet_name
|
|
||||||
```
|
|
||||||
|
|
||||||
* Update an item
|
|
||||||
```
|
|
||||||
mpw --update --id uniq_id
|
|
||||||
mpw --update --id uniq_id --config /path/conf/file.cfg
|
|
||||||
mpw --update --id uniq_id --wallet wallet_name
|
|
||||||
mpw --update --id uniq_id --config /path/conf/file.cfg --wallet wallet_name
|
|
||||||
```
|
|
||||||
|
|
||||||
* Delete an item
|
|
||||||
```
|
|
||||||
mpw --delete --id uniq_id
|
|
||||||
mpw --delete --id uniq_id --config /path/conf/file.cfg
|
|
||||||
mpw --delete --id uniq_id --wallet wallet_name
|
|
||||||
mpw --delete --id uniq_id --config /path/conf/file.cfg --wallet wallet_name
|
|
||||||
```
|
|
||||||
|
|
||||||
* Show an item
|
|
||||||
```
|
|
||||||
mpw --show 'string to search'
|
|
||||||
mpw --show 'string to search' --config /path/conf/file.cfg
|
|
||||||
mpw --show 'string to search' --wallet wallet_name
|
|
||||||
mpw --show 'string to search' --config /path/conf/file.cfg --wallet wallet_name
|
|
||||||
mpw --show 'string to search' --group group_name
|
|
||||||
mpw --show 'string to search' --group group_name --config /path/conf/file.cfg
|
|
||||||
mpw --show 'string to search' --group group_name --wallet wallet_name
|
|
||||||
mpw --show 'string to search' --group group_name --config /path/conf/file.cfg --wallet wallet_name
|
|
||||||
```
|
|
||||||
|
|
||||||
* Export data in YAML file
|
|
||||||
```
|
|
||||||
mpw --export --file /path/file/to/export.yml
|
|
||||||
mpw --export --file /path/file/to/export.yml --config /path/conf/file.cfg
|
|
||||||
mpw --export --file /path/file/to/export.yml --wallet wallet_name
|
|
||||||
mpw --export --file /path/file/to/export.yml --config /path/conf/file.cfg --wallet wallet_name
|
|
||||||
```
|
|
||||||
|
|
||||||
* Import data from YAML file
|
|
||||||
```
|
|
||||||
mpw --import --file /path/file/to/export.yml
|
|
||||||
mpw --import --file /path/file/to/export.yml --config /path/conf/file.cfg
|
|
||||||
mpw --import --file /path/file/to/export.yml --wallet wallet_name
|
|
||||||
mpw --import --file /path/file/to/export.yml --config /path/conf/file.cfg --wallet wallet_name
|
|
||||||
```
|
|
||||||
|
|
||||||
Format file to import:
|
|
||||||
```
|
|
||||||
1:
|
|
||||||
name: Website perso
|
|
||||||
group: Perso
|
|
||||||
host: localhost.local
|
|
||||||
protocol: ftp
|
|
||||||
user: test
|
|
||||||
password: letoortue
|
|
||||||
port: 21
|
|
||||||
comment: Mysuper website
|
|
||||||
2:
|
|
||||||
name: Linuxfr
|
|
||||||
group: Pro
|
|
||||||
host: Linuxfr.org
|
|
||||||
protocol: https
|
|
||||||
user: test
|
|
||||||
password: coucou
|
|
||||||
port:
|
|
||||||
comment:
|
|
||||||
```
|
|
53
README.rst
Normal file
53
README.rst
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
MPW: Manage your passwords!
|
||||||
|
*******************************************************
|
||||||
|
|
||||||
|
mpw is a little software which stores your passwords in `GnuPG <http://www.gnupg.org/>` encrypted files.
|
||||||
|
|
||||||
|
Features
|
||||||
|
========
|
||||||
|
|
||||||
|
* generate OTP code
|
||||||
|
* synchronize your passwords with SSH or FTP.
|
||||||
|
* copy your login, password or otp in clipboard
|
||||||
|
|
||||||
|
Install
|
||||||
|
=======
|
||||||
|
|
||||||
|
On debian or ubuntu::
|
||||||
|
|
||||||
|
apt install ruby ruby-dev xclip
|
||||||
|
gem install mpw
|
||||||
|
|
||||||
|
|
||||||
|
How to use
|
||||||
|
==========
|
||||||
|
|
||||||
|
A simple mpw usage::
|
||||||
|
|
||||||
|
mpw config --init user@host.com
|
||||||
|
mpw add
|
||||||
|
mpw copy
|
||||||
|
mpw add
|
||||||
|
mpw list
|
||||||
|
|
||||||
|
Output::
|
||||||
|
|
||||||
|
Bank
|
||||||
|
==============================================================================
|
||||||
|
ID | Host | User | Protocol | Port | OTP | Comment
|
||||||
|
==============================================================================
|
||||||
|
1 | bank.com | 1234456 | https | | X |
|
||||||
|
|
||||||
|
Linux
|
||||||
|
==============================================================================
|
||||||
|
ID | Host | User | Protocol | Port | OTP | Comment
|
||||||
|
==============================================================================
|
||||||
|
2 | linuxfr.org | example | https | | | Da Linux French Site
|
||||||
|
|
||||||
|
|
||||||
|
Licence |License|
|
||||||
|
=================
|
||||||
|
|
||||||
|
Full license here: `LICENSE <https://github.com/nishiki/manage-password/blob/master/LICENSE>`
|
||||||
|
|
||||||
|
.. |License| image:: https://img.shields.io/badge/license-GPL--2.0-blue.svg
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
||||||
3.2.1
|
4.0.0-beta
|
||||||
|
|
193
bin/mpw
193
bin/mpw
|
@ -18,13 +18,9 @@
|
||||||
|
|
||||||
$: << File.expand_path('../../lib', __FILE__)
|
$: << File.expand_path('../../lib', __FILE__)
|
||||||
|
|
||||||
require 'optparse'
|
|
||||||
require 'locale'
|
require 'locale'
|
||||||
require 'set'
|
require 'set'
|
||||||
require 'i18n'
|
require 'i18n'
|
||||||
require 'mpw/mpw'
|
|
||||||
require 'mpw/config'
|
|
||||||
require 'mpw/cli'
|
|
||||||
|
|
||||||
# --------------------------------------------------------- #
|
# --------------------------------------------------------- #
|
||||||
# Set local
|
# Set local
|
||||||
|
@ -45,190 +41,9 @@ I18n.locale = lang.to_sym
|
||||||
# Options
|
# Options
|
||||||
# --------------------------------------------------------- #
|
# --------------------------------------------------------- #
|
||||||
|
|
||||||
options_password = {}
|
bin_dir = File.dirname(__FILE__)
|
||||||
options = {}
|
command = "#{bin_dir}/mpw-#{ARGV[0]}"
|
||||||
options[:force] = false
|
|
||||||
options[:otp] = false
|
|
||||||
options[:sync] = true
|
|
||||||
options[:clipboard] = true
|
|
||||||
options[:group] = nil
|
|
||||||
options[:config] = nil
|
|
||||||
options[:wallet] = nil
|
|
||||||
|
|
||||||
OptionParser.new do |opts|
|
if Dir.glob("#{bin_dir}/mpw-*").include?("#{command}")
|
||||||
opts.banner = "#{I18n.t('option.usage')}: mpw [options]"
|
Kernel.load(command)
|
||||||
|
|
||||||
opts.on('-a', '--add', I18n.t('option.add')) do
|
|
||||||
options[:add] = true
|
|
||||||
end
|
|
||||||
|
|
||||||
opts.on('-A', '--show-all', I18n.t('option.show_all')) do
|
|
||||||
options[:type] = nil
|
|
||||||
options[:show] = ''
|
|
||||||
end
|
|
||||||
|
|
||||||
opts.on('-c', '--config CONFIG', I18n.t('option.config')) do |config|
|
|
||||||
options[:config] = config
|
|
||||||
end
|
|
||||||
|
|
||||||
opts.on('-C', '--no-clipboard', I18n.t('option.clipboard')) do
|
|
||||||
options[:clipboard] = false
|
|
||||||
end
|
|
||||||
|
|
||||||
opts.on('-d', '--delete', I18n.t('option.remove')) do
|
|
||||||
options[:delete] = true
|
|
||||||
end
|
|
||||||
|
|
||||||
opts.on('-e', '--export', I18n.t('option.export')) do
|
|
||||||
options[:export] = true
|
|
||||||
end
|
|
||||||
|
|
||||||
opts.on('-f', '--file FILE', I18n.t('option.file')) do |file|
|
|
||||||
options[:file] = file
|
|
||||||
end
|
|
||||||
|
|
||||||
opts.on('-F', '--force', I18n.t('option.force')) do
|
|
||||||
options[:force] = true
|
|
||||||
end
|
|
||||||
|
|
||||||
opts.on('-g', '--group GROUP', I18n.t('option.group')) do |group|
|
|
||||||
options[:group] = group
|
|
||||||
end
|
|
||||||
|
|
||||||
opts.on('-G', '--generate-password [LENGTH]', I18n.t('option.generate_password')) do |length|
|
|
||||||
options_password[:length] = length
|
|
||||||
end
|
|
||||||
|
|
||||||
opts.on('-h', '--help', I18n.t('option.help')) do
|
|
||||||
puts opts
|
|
||||||
exit 0
|
|
||||||
end
|
|
||||||
|
|
||||||
opts.on('-i', '--id ID', I18n.t('option.id')) do |id|
|
|
||||||
options[:id] = id
|
|
||||||
end
|
|
||||||
|
|
||||||
opts.on('-I', '--import', I18n.t('option.import')) do
|
|
||||||
options[:import] = true
|
|
||||||
end
|
|
||||||
|
|
||||||
opts.on('-k', '--key KEY', I18n.t('option.key')) do |key|
|
|
||||||
options[:key] = key
|
|
||||||
end
|
|
||||||
|
|
||||||
opts.on('-n', '--numeric', I18n.t('option.numeric')) do
|
|
||||||
options_password[:numeric] = true
|
|
||||||
end
|
|
||||||
|
|
||||||
opts.on('-N', '--no-sync', I18n.t('option.no_sync')) do
|
|
||||||
options[:sync] = false
|
|
||||||
end
|
|
||||||
|
|
||||||
opts.on('-O', '--otp', I18n.t('option.otp')) do
|
|
||||||
options[:otp] = true
|
|
||||||
end
|
|
||||||
|
|
||||||
opts.on('-s', '--show [SEARCH]', I18n.t('option.show')) do |search|
|
|
||||||
search.nil? ? (options[:show] = '') : (options[:show] = search)
|
|
||||||
end
|
|
||||||
|
|
||||||
opts.on('-S', '--setup', I18n.t('option.setup')) do
|
|
||||||
options[:setup] = true
|
|
||||||
end
|
|
||||||
|
|
||||||
opts.on('-u', '--update', I18n.t('option.update')) do
|
|
||||||
options[:update] = true
|
|
||||||
end
|
|
||||||
|
|
||||||
opts.on('-w', '--wallet WALLET', I18n.t('option.wallet')) do |wallet|
|
|
||||||
options[:wallet] = wallet
|
|
||||||
end
|
|
||||||
|
|
||||||
opts.on('-W', '--setup-wallet', I18n.t('option.setup_wallet')) do
|
|
||||||
options[:setup_wallet] = true
|
|
||||||
end
|
|
||||||
|
|
||||||
opts.on('-x', '--special-chars', I18n.t('option.special_chars')) do
|
|
||||||
options_password[:special] = true
|
|
||||||
end
|
|
||||||
|
|
||||||
opts.on('-y', '--alpha', I18n.t('option.alpha')) do
|
|
||||||
options_password[:alpha] = true
|
|
||||||
end
|
|
||||||
end.parse!
|
|
||||||
|
|
||||||
# --------------------------------------------------------- #
|
|
||||||
# Main
|
|
||||||
# --------------------------------------------------------- #
|
|
||||||
|
|
||||||
# Generate password
|
|
||||||
if not options_password.empty?
|
|
||||||
puts MPW::MPW::password(options_password)
|
|
||||||
exit 0
|
|
||||||
end
|
|
||||||
|
|
||||||
begin
|
|
||||||
config = MPW::Config.new(options[:config])
|
|
||||||
cli = MPW::Cli.new(config, options[:clipboard], options[:sync], options[:otp])
|
|
||||||
|
|
||||||
# Setup a new config
|
|
||||||
if not options[:setup].nil?
|
|
||||||
cli.setup(lang)
|
|
||||||
exit 0
|
|
||||||
end
|
|
||||||
|
|
||||||
cli.setup(lang) if not config.is_valid?
|
|
||||||
cli.setup_gpg_key if not config.check_gpg_key?
|
|
||||||
|
|
||||||
cli.get_wallet(options[:wallet])
|
|
||||||
cli.decrypt
|
|
||||||
|
|
||||||
# Display the item's informations
|
|
||||||
if not options[:show].nil?
|
|
||||||
opts = {search: options[:show],
|
|
||||||
group: options[:group],
|
|
||||||
}
|
|
||||||
|
|
||||||
cli.display(opts)
|
|
||||||
|
|
||||||
# Remove an item
|
|
||||||
elsif not options[:delete].nil? and not options[:id].nil?
|
|
||||||
cli.delete(options[:id], options[:force])
|
|
||||||
|
|
||||||
# Update an item
|
|
||||||
elsif not options[:update].nil? and not options[:id].nil?
|
|
||||||
cli.update(options[:id])
|
|
||||||
|
|
||||||
# Add a new item
|
|
||||||
elsif not options[:add].nil? and options[:key].nil?
|
|
||||||
cli.add
|
|
||||||
|
|
||||||
# Add a new public key in wallet
|
|
||||||
elsif not options[:add].nil? and not options[:key].nil?
|
|
||||||
cli.add_key(options[:key], options[:file])
|
|
||||||
|
|
||||||
# Delete a public key in wallet
|
|
||||||
elsif not options[:delete].nil? and not options[:key].nil?
|
|
||||||
cli.delete_key(options[:key])
|
|
||||||
|
|
||||||
# Export
|
|
||||||
elsif not options[:export].nil? and not options[:file].nil?
|
|
||||||
cli.export(options[:file])
|
|
||||||
|
|
||||||
# Add a new item
|
|
||||||
elsif not options[:import].nil? and not options[:file].nil?
|
|
||||||
cli.import(options[:file])
|
|
||||||
|
|
||||||
# Setup wallet config
|
|
||||||
elsif not options[:setup_wallet].nil?
|
|
||||||
cli.setup_wallet_config
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
cli = nil
|
|
||||||
|
|
||||||
exit 0
|
|
||||||
|
|
||||||
rescue SystemExit, Interrupt
|
|
||||||
exit 3
|
|
||||||
end
|
end
|
||||||
|
|
61
bin/mpw-add
Normal file
61
bin/mpw-add
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
#!/usr/bin/ruby
|
||||||
|
# MPW is a software to crypt and manage your passwords
|
||||||
|
# Copyright (C) 2016 Adrien Waksberg <mpw@yae.im>
|
||||||
|
#
|
||||||
|
# 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 2
|
||||||
|
# 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, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
require 'optparse'
|
||||||
|
require 'mpw/config'
|
||||||
|
require 'mpw/cli'
|
||||||
|
|
||||||
|
# --------------------------------------------------------- #
|
||||||
|
# Options
|
||||||
|
# --------------------------------------------------------- #
|
||||||
|
|
||||||
|
options = {}
|
||||||
|
options[:sync] = true
|
||||||
|
|
||||||
|
OptionParser.new do |opts|
|
||||||
|
opts.banner = "#{I18n.t('option.usage')}: mpw add [options]"
|
||||||
|
|
||||||
|
opts.on('-c', '--config PATH', I18n.t('option.config')) do |config|
|
||||||
|
options[:config] = config
|
||||||
|
end
|
||||||
|
|
||||||
|
opts.on('-h', '--help', I18n.t('option.help')) do
|
||||||
|
puts opts
|
||||||
|
exit 0
|
||||||
|
end
|
||||||
|
|
||||||
|
opts.on('-n', '--no-sync', I18n.t('option.no_sync')) do
|
||||||
|
options[:sync] = false
|
||||||
|
end
|
||||||
|
|
||||||
|
opts.on('-r', '--random', I18n.t('option.random_password')) do
|
||||||
|
options[:password] = true
|
||||||
|
end
|
||||||
|
|
||||||
|
opts.on('-w', '--wallet NAME', I18n.t('option.wallet')) do |wallet|
|
||||||
|
options[:wallet] = wallet
|
||||||
|
end
|
||||||
|
end.parse!
|
||||||
|
|
||||||
|
config = MPW::Config.new(options[:config])
|
||||||
|
cli = MPW::Cli.new(config, options[:sync])
|
||||||
|
|
||||||
|
cli.load_config
|
||||||
|
cli.get_wallet(options[:wallet])
|
||||||
|
cli.decrypt
|
||||||
|
cli.add(options[:password])
|
75
bin/mpw-config
Normal file
75
bin/mpw-config
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
#!/usr/bin/ruby
|
||||||
|
# MPW is a software to crypt and manage your passwords
|
||||||
|
# Copyright (C) 2016 Adrien Waksberg <mpw@yae.im>
|
||||||
|
#
|
||||||
|
# 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 2
|
||||||
|
# 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, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
require 'optparse'
|
||||||
|
require 'mpw/config'
|
||||||
|
require 'mpw/cli'
|
||||||
|
|
||||||
|
# --------------------------------------------------------- #
|
||||||
|
# Options
|
||||||
|
# --------------------------------------------------------- #
|
||||||
|
|
||||||
|
options = {}
|
||||||
|
values = {}
|
||||||
|
|
||||||
|
OptionParser.new do |opts|
|
||||||
|
opts.banner = "#{I18n.t('option.usage')}: mpw config [options]"
|
||||||
|
|
||||||
|
opts.on('-c', '--config PATH', I18n.t('option.config')) do |config|
|
||||||
|
options[:config] = config
|
||||||
|
end
|
||||||
|
|
||||||
|
opts.on('-g', '--gpg-exe PATH', I18n.t('option.gpg_exe')) do |gpg_exe|
|
||||||
|
values[:gpg_exe] = gpg_exe
|
||||||
|
end
|
||||||
|
|
||||||
|
opts.on('-h', '--help', I18n.t('option.help')) do
|
||||||
|
puts opts
|
||||||
|
exit 0
|
||||||
|
end
|
||||||
|
|
||||||
|
opts.on('-i', '--init GPG_KEY', I18n.t('option.init')) do |gpg_key|
|
||||||
|
options[:init] = true
|
||||||
|
values[:gpg_key] = gpg_key
|
||||||
|
end
|
||||||
|
|
||||||
|
opts.on('-k', '--key GPG_KEY', I18n.t('option.gpg_key')) do |gpg_key|
|
||||||
|
values[:gpg_key] = gpg_key
|
||||||
|
end
|
||||||
|
|
||||||
|
opts.on('-l', '--lang LANG', I18n.t('option.lang')) do |lang|
|
||||||
|
values[:lang] = lang
|
||||||
|
end
|
||||||
|
|
||||||
|
opts.on('-w', '--wallet-dir PATH', I18n.t('option.wallet_dir')) do |wallet_dir|
|
||||||
|
values[:wallet_dir] = wallet_dir
|
||||||
|
end
|
||||||
|
end.parse!
|
||||||
|
|
||||||
|
config = MPW::Config.new(options[:config])
|
||||||
|
cli = MPW::Cli.new(config, nil)
|
||||||
|
|
||||||
|
if not options[:init].nil?
|
||||||
|
cli.setup(values)
|
||||||
|
cli.load_config
|
||||||
|
cli.get_wallet
|
||||||
|
cli.setup_gpg_key(options[:init])
|
||||||
|
cli.setup_wallet_config
|
||||||
|
else
|
||||||
|
cli.set_config(values)
|
||||||
|
end
|
71
bin/mpw-copy
Normal file
71
bin/mpw-copy
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
#!/usr/bin/ruby
|
||||||
|
# MPW is a software to crypt and manage your passwords
|
||||||
|
# Copyright (C) 2016 Adrien Waksberg <mpw@yae.im>
|
||||||
|
#
|
||||||
|
# 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 2
|
||||||
|
# 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, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
require 'optparse'
|
||||||
|
require 'mpw/config'
|
||||||
|
require 'mpw/cli'
|
||||||
|
|
||||||
|
# --------------------------------------------------------- #
|
||||||
|
# Options
|
||||||
|
# --------------------------------------------------------- #
|
||||||
|
|
||||||
|
options = {}
|
||||||
|
options[:sync] = true
|
||||||
|
options[:clipboard] = true
|
||||||
|
values = {}
|
||||||
|
|
||||||
|
OptionParser.new do |opts|
|
||||||
|
opts.banner = "#{I18n.t('option.usage')}: mpw copy [options]"
|
||||||
|
|
||||||
|
opts.on('-c', '--config PATH', I18n.t('option.config')) do |config|
|
||||||
|
options[:config] = config
|
||||||
|
end
|
||||||
|
|
||||||
|
opts.on('-d', '--disable-clipboard', I18n.t('option.clipboard')) do
|
||||||
|
options[:clipboard] = false
|
||||||
|
end
|
||||||
|
|
||||||
|
opts.on('-g', '--group NAME', I18n.t('option.group')) do |group|
|
||||||
|
values[:group] = group
|
||||||
|
end
|
||||||
|
|
||||||
|
opts.on('-h', '--help', I18n.t('option.help')) do
|
||||||
|
puts opts
|
||||||
|
exit 0
|
||||||
|
end
|
||||||
|
|
||||||
|
opts.on('-n', '--no-sync', I18n.t('option.no_sync')) do
|
||||||
|
options[:sync] = false
|
||||||
|
end
|
||||||
|
|
||||||
|
opts.on('-p', '--pattern PATTERN', I18n.t('option.pattern')) do |pattern|
|
||||||
|
values[:pattern] = pattern
|
||||||
|
end
|
||||||
|
|
||||||
|
opts.on('-w', '--wallet NAME', I18n.t('option.wallet')) do |wallet|
|
||||||
|
options[:wallet] = wallet
|
||||||
|
end
|
||||||
|
end.parse!
|
||||||
|
|
||||||
|
config = MPW::Config.new(options[:config])
|
||||||
|
cli = MPW::Cli.new(config, options[:sync])
|
||||||
|
|
||||||
|
cli.load_config
|
||||||
|
cli.get_wallet(options[:wallet])
|
||||||
|
cli.decrypt
|
||||||
|
cli.copy(options[:clipboard], values)
|
66
bin/mpw-delete
Normal file
66
bin/mpw-delete
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
#!/usr/bin/ruby
|
||||||
|
# MPW is a software to crypt and manage your passwords
|
||||||
|
# Copyright (C) 2016 Adrien Waksberg <mpw@yae.im>
|
||||||
|
#
|
||||||
|
# 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 2
|
||||||
|
# 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, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
require 'optparse'
|
||||||
|
require 'mpw/config'
|
||||||
|
require 'mpw/cli'
|
||||||
|
|
||||||
|
# --------------------------------------------------------- #
|
||||||
|
# Options
|
||||||
|
# --------------------------------------------------------- #
|
||||||
|
|
||||||
|
options = {}
|
||||||
|
options[:sync] = true
|
||||||
|
values = {}
|
||||||
|
|
||||||
|
OptionParser.new do |opts|
|
||||||
|
opts.banner = "#{I18n.t('option.usage')}: mpw delete [options]"
|
||||||
|
|
||||||
|
opts.on('-c', '--config PATH', I18n.t('option.config')) do |config|
|
||||||
|
options[:config] = config
|
||||||
|
end
|
||||||
|
|
||||||
|
opts.on('-g', '--group NAME', I18n.t('option.group')) do |group|
|
||||||
|
values[:group] = group
|
||||||
|
end
|
||||||
|
|
||||||
|
opts.on('-h', '--help', I18n.t('option.help')) do
|
||||||
|
puts opts
|
||||||
|
exit 0
|
||||||
|
end
|
||||||
|
|
||||||
|
opts.on('-n', '--no-sync', I18n.t('option.no_sync')) do
|
||||||
|
options[:sync] = false
|
||||||
|
end
|
||||||
|
|
||||||
|
opts.on('-p', '--pattern PATTERN', I18n.t('option.pattern')) do |pattern|
|
||||||
|
values[:pattern] = pattern
|
||||||
|
end
|
||||||
|
|
||||||
|
opts.on('-w', '--wallet NAME', I18n.t('option.wallet')) do |wallet|
|
||||||
|
options[:wallet] = wallet
|
||||||
|
end
|
||||||
|
end.parse!
|
||||||
|
|
||||||
|
config = MPW::Config.new(options[:config])
|
||||||
|
cli = MPW::Cli.new(config, options[:sync])
|
||||||
|
|
||||||
|
cli.load_config
|
||||||
|
cli.get_wallet(options[:wallet])
|
||||||
|
cli.decrypt
|
||||||
|
cli.delete(values)
|
70
bin/mpw-export
Normal file
70
bin/mpw-export
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
#!/usr/bin/ruby
|
||||||
|
# MPW is a software to crypt and manage your passwords
|
||||||
|
# Copyright (C) 2016 Adrien Waksberg <mpw@yae.im>
|
||||||
|
#
|
||||||
|
# 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 2
|
||||||
|
# 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, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
require 'optparse'
|
||||||
|
require 'mpw/config'
|
||||||
|
require 'mpw/cli'
|
||||||
|
|
||||||
|
# --------------------------------------------------------- #
|
||||||
|
# Options
|
||||||
|
# --------------------------------------------------------- #
|
||||||
|
|
||||||
|
options = {}
|
||||||
|
options[:sync] = true
|
||||||
|
values = {}
|
||||||
|
|
||||||
|
OptionParser.new do |opts|
|
||||||
|
opts.banner = "#{I18n.t('option.usage')}: mpw wallet [options]"
|
||||||
|
|
||||||
|
opts.on('-c', '--config PATH', I18n.t('option.config')) do |config|
|
||||||
|
options[:config] = config
|
||||||
|
end
|
||||||
|
|
||||||
|
opts.on('-f', '--file PATH', I18n.t('option.file_export')) do |file|
|
||||||
|
options[:file] = file
|
||||||
|
end
|
||||||
|
|
||||||
|
opts.on('-g', '--group GROUP', I18n.t('option.group')) do |group|
|
||||||
|
values[:group] = group
|
||||||
|
end
|
||||||
|
|
||||||
|
opts.on('-h', '--help', I18n.t('option.help')) do
|
||||||
|
puts opts
|
||||||
|
exit 0
|
||||||
|
end
|
||||||
|
|
||||||
|
opts.on('-n', '--no-sync', I18n.t('option.no_sync')) do
|
||||||
|
options[:sync] = false
|
||||||
|
end
|
||||||
|
|
||||||
|
opts.on('-p', '--pattern PATTERN', I18n.t('option.pattern')) do |pattern|
|
||||||
|
values[:pattern] = pattern
|
||||||
|
end
|
||||||
|
|
||||||
|
opts.on('-w', '--wallet NAME', I18n.t('option.wallet')) do |wallet|
|
||||||
|
options[:wallet] = wallet
|
||||||
|
end
|
||||||
|
end.parse!
|
||||||
|
|
||||||
|
config = MPW::Config.new(options[:config])
|
||||||
|
cli = MPW::Cli.new(config, options[:sync])
|
||||||
|
|
||||||
|
cli.load_config
|
||||||
|
cli.get_wallet(options[:wallet])
|
||||||
|
cli.decrypt
|
||||||
|
cli.export(options[:file], values)
|
50
bin/mpw-genpwd
Normal file
50
bin/mpw-genpwd
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
#!/usr/bin/ruby
|
||||||
|
# MPW is a software to crypt and manage your passwords
|
||||||
|
# Copyright (C) 2016 Adrien Waksberg <mpw@yae.im>
|
||||||
|
#
|
||||||
|
# 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 2
|
||||||
|
# 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, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
require 'optparse'
|
||||||
|
require 'mpw/mpw'
|
||||||
|
|
||||||
|
options = {}
|
||||||
|
|
||||||
|
OptionParser.new do |opts|
|
||||||
|
opts.banner = "#{I18n.t('option.usage')}: mpw passwd [options]"
|
||||||
|
|
||||||
|
opts.on('-h', '--help', I18n.t('option.help')) do
|
||||||
|
puts opts
|
||||||
|
exit 0
|
||||||
|
end
|
||||||
|
|
||||||
|
opts.on('-l', '--length NUMBER', I18n.t('option.length')) do |length|
|
||||||
|
options[:length] = length.to_i
|
||||||
|
end
|
||||||
|
|
||||||
|
opts.on('-n', '--numeric', I18n.t('option.numeric')) do
|
||||||
|
options[:numeric] = true
|
||||||
|
end
|
||||||
|
|
||||||
|
opts.on('-s', '--special-chars', I18n.t('option.special_chars')) do
|
||||||
|
options[:special] = true
|
||||||
|
end
|
||||||
|
|
||||||
|
opts.on('-a', '--alpha', I18n.t('option.alpha')) do
|
||||||
|
options[:alpha] = true
|
||||||
|
end
|
||||||
|
end.parse!
|
||||||
|
|
||||||
|
puts MPW::MPW::password(options)
|
||||||
|
exit 0
|
61
bin/mpw-import
Normal file
61
bin/mpw-import
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
#!/usr/bin/ruby
|
||||||
|
# MPW is a software to crypt and manage your passwords
|
||||||
|
# Copyright (C) 2016 Adrien Waksberg <mpw@yae.im>
|
||||||
|
#
|
||||||
|
# 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 2
|
||||||
|
# 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, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
require 'optparse'
|
||||||
|
require 'mpw/config'
|
||||||
|
require 'mpw/cli'
|
||||||
|
|
||||||
|
# --------------------------------------------------------- #
|
||||||
|
# Options
|
||||||
|
# --------------------------------------------------------- #
|
||||||
|
|
||||||
|
options = {}
|
||||||
|
options[:sync] = true
|
||||||
|
|
||||||
|
OptionParser.new do |opts|
|
||||||
|
opts.banner = "#{I18n.t('option.usage')}: mpw import [options]"
|
||||||
|
|
||||||
|
opts.on('-c', '--config PATH', I18n.t('option.config')) do |config|
|
||||||
|
options[:config] = config
|
||||||
|
end
|
||||||
|
|
||||||
|
opts.on('-f', '--file PATH', I18n.t('option.file_import')) do |file|
|
||||||
|
options[:file] = file
|
||||||
|
end
|
||||||
|
|
||||||
|
opts.on('-h', '--help', I18n.t('option.help')) do
|
||||||
|
puts opts
|
||||||
|
exit 0
|
||||||
|
end
|
||||||
|
|
||||||
|
opts.on('-n', '--no-sync', I18n.t('option.no_sync')) do
|
||||||
|
options[:sync] = false
|
||||||
|
end
|
||||||
|
|
||||||
|
opts.on('-w', '--wallet NAME', I18n.t('option.wallet')) do |wallet|
|
||||||
|
options[:wallet] = wallet
|
||||||
|
end
|
||||||
|
end.parse!
|
||||||
|
|
||||||
|
config = MPW::Config.new(options[:config])
|
||||||
|
cli = MPW::Cli.new(config, options[:sync])
|
||||||
|
|
||||||
|
cli.load_config
|
||||||
|
cli.get_wallet(options[:wallet])
|
||||||
|
cli.decrypt
|
||||||
|
cli.import(options[:file])
|
66
bin/mpw-list
Normal file
66
bin/mpw-list
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
#!/usr/bin/ruby
|
||||||
|
# MPW is a software to crypt and manage your passwords
|
||||||
|
# Copyright (C) 2016 Adrien Waksberg <mpw@yae.im>
|
||||||
|
#
|
||||||
|
# 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 2
|
||||||
|
# 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, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
require 'optparse'
|
||||||
|
require 'mpw/config'
|
||||||
|
require 'mpw/cli'
|
||||||
|
|
||||||
|
# --------------------------------------------------------- #
|
||||||
|
# Options
|
||||||
|
# --------------------------------------------------------- #
|
||||||
|
|
||||||
|
options = {}
|
||||||
|
options[:sync] = true
|
||||||
|
values = {}
|
||||||
|
|
||||||
|
OptionParser.new do |opts|
|
||||||
|
opts.banner = "#{I18n.t('option.usage')}: mpw list [options]"
|
||||||
|
|
||||||
|
opts.on('-c', '--config PATH', I18n.t('option.config')) do |config|
|
||||||
|
options[:config] = config
|
||||||
|
end
|
||||||
|
|
||||||
|
opts.on('-g', '--group NAME', I18n.t('option.group')) do |group|
|
||||||
|
values[:group] = group
|
||||||
|
end
|
||||||
|
|
||||||
|
opts.on('-h', '--help', I18n.t('option.help')) do
|
||||||
|
puts opts
|
||||||
|
exit 0
|
||||||
|
end
|
||||||
|
|
||||||
|
opts.on('-p', '--pattern PATTERN', I18n.t('option.pattern')) do |pattern|
|
||||||
|
values[:pattern] = pattern
|
||||||
|
end
|
||||||
|
|
||||||
|
opts.on('-n', '--no-sync', I18n.t('option.no_sync')) do
|
||||||
|
options[:sync] = false
|
||||||
|
end
|
||||||
|
|
||||||
|
opts.on('-w', '--wallet NAME', I18n.t('option.wallet')) do |wallet|
|
||||||
|
options[:wallet] = wallet
|
||||||
|
end
|
||||||
|
end.parse!
|
||||||
|
|
||||||
|
config = MPW::Config.new(options[:config])
|
||||||
|
cli = MPW::Cli.new(config, options[:sync])
|
||||||
|
|
||||||
|
cli.load_config
|
||||||
|
cli.get_wallet(options[:wallet])
|
||||||
|
cli.decrypt
|
||||||
|
cli.list(values)
|
66
bin/mpw-update
Normal file
66
bin/mpw-update
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
#!/usr/bin/ruby
|
||||||
|
# MPW is a software to crypt and manage your passwords
|
||||||
|
# Copyright (C) 2016 Adrien Waksberg <mpw@yae.im>
|
||||||
|
#
|
||||||
|
# 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 2
|
||||||
|
# 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, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
require 'optparse'
|
||||||
|
require 'mpw/config'
|
||||||
|
require 'mpw/cli'
|
||||||
|
|
||||||
|
# --------------------------------------------------------- #
|
||||||
|
# Options
|
||||||
|
# --------------------------------------------------------- #
|
||||||
|
|
||||||
|
options = {}
|
||||||
|
options[:sync] = true
|
||||||
|
values = {}
|
||||||
|
|
||||||
|
OptionParser.new do |opts|
|
||||||
|
opts.banner = "#{I18n.t('option.usage')}: mpw update [options]"
|
||||||
|
|
||||||
|
opts.on('-c', '--config PATH', I18n.t('option.config')) do |config|
|
||||||
|
options[:config] = config
|
||||||
|
end
|
||||||
|
|
||||||
|
opts.on('-g', '--group NAME', I18n.t('option.group')) do |group|
|
||||||
|
values[:group] = group
|
||||||
|
end
|
||||||
|
|
||||||
|
opts.on('-h', '--help', I18n.t('option.help')) do
|
||||||
|
puts opts
|
||||||
|
exit 0
|
||||||
|
end
|
||||||
|
|
||||||
|
opts.on('-n', '--no-sync', I18n.t('option.no_sync')) do
|
||||||
|
options[:sync] = false
|
||||||
|
end
|
||||||
|
|
||||||
|
opts.on('-p', '--pattern PATTERN', I18n.t('option.pattern')) do |pattern|
|
||||||
|
values[:pattern] = pattern
|
||||||
|
end
|
||||||
|
|
||||||
|
opts.on('-w', '--wallet NAME', I18n.t('option.wallet')) do |wallet|
|
||||||
|
options[:wallet] = wallet
|
||||||
|
end
|
||||||
|
end.parse!
|
||||||
|
|
||||||
|
config = MPW::Config.new(options[:config])
|
||||||
|
cli = MPW::Cli.new(config, options[:sync])
|
||||||
|
|
||||||
|
cli.load_config
|
||||||
|
cli.get_wallet(options[:wallet])
|
||||||
|
cli.decrypt
|
||||||
|
cli.update(values)
|
91
bin/mpw-wallet
Normal file
91
bin/mpw-wallet
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
#!/usr/bin/ruby
|
||||||
|
# MPW is a software to crypt and manage your passwords
|
||||||
|
# Copyright (C) 2016 Adrien Waksberg <mpw@yae.im>
|
||||||
|
#
|
||||||
|
# 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 2
|
||||||
|
# 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, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
require 'optparse'
|
||||||
|
require 'mpw/config'
|
||||||
|
require 'mpw/cli'
|
||||||
|
|
||||||
|
# --------------------------------------------------------- #
|
||||||
|
# Options
|
||||||
|
# --------------------------------------------------------- #
|
||||||
|
|
||||||
|
options = {}
|
||||||
|
options[:sync] = {}
|
||||||
|
values = {}
|
||||||
|
|
||||||
|
OptionParser.new do |opts|
|
||||||
|
opts.banner = "#{I18n.t('option.usage')}: mpw wallet [options]"
|
||||||
|
|
||||||
|
opts.on('-c', '--config PATH', I18n.t('option.config')) do |config|
|
||||||
|
options[:config] = config
|
||||||
|
end
|
||||||
|
|
||||||
|
opts.on('-h', '--help', I18n.t('option.help')) do
|
||||||
|
puts opts
|
||||||
|
exit 0
|
||||||
|
end
|
||||||
|
|
||||||
|
opts.on('--host NAME', I18n.t('option.host')) do |host|
|
||||||
|
values[:host] = host
|
||||||
|
end
|
||||||
|
|
||||||
|
opts.on('-l', '--list', I18n.t('option.list')) do |list|
|
||||||
|
options[:list] = true
|
||||||
|
end
|
||||||
|
|
||||||
|
opts.on('-n', '--no-sync', I18n.t('option.no_sync')) do
|
||||||
|
options[:sync] = false
|
||||||
|
end
|
||||||
|
|
||||||
|
opts.on('--password', I18n.t('option.password')) do
|
||||||
|
values[:password] = true
|
||||||
|
end
|
||||||
|
|
||||||
|
opts.on('--path PATH', I18n.t('option.path')) do |path|
|
||||||
|
values[:path] = path
|
||||||
|
end
|
||||||
|
|
||||||
|
opts.on('--port NUMBER', I18n.t('option.port')) do |port|
|
||||||
|
values[:port] = port
|
||||||
|
end
|
||||||
|
|
||||||
|
opts.on('--protocol NAME', I18n.t('option.protocol')) do |protocol|
|
||||||
|
values[:protocol] = protocol
|
||||||
|
end
|
||||||
|
|
||||||
|
opts.on('--user NAME', I18n.t('option.user')) do |user|
|
||||||
|
values[:user] = user
|
||||||
|
end
|
||||||
|
|
||||||
|
opts.on('-w', '--wallet NAME', I18n.t('option.wallet')) do |wallet|
|
||||||
|
options[:wallet] = wallet
|
||||||
|
end
|
||||||
|
end.parse!
|
||||||
|
|
||||||
|
config = MPW::Config.new(options[:config])
|
||||||
|
cli = MPW::Cli.new(config, options[:sync])
|
||||||
|
|
||||||
|
cli.load_config
|
||||||
|
|
||||||
|
if not options[:list].nil?
|
||||||
|
cli.list_wallet
|
||||||
|
else
|
||||||
|
cli.get_wallet(options[:wallet])
|
||||||
|
cli.decrypt
|
||||||
|
cli.setup_wallet_config(values)
|
||||||
|
end
|
69
i18n/en.yml
69
i18n/en.yml
|
@ -3,15 +3,13 @@ en:
|
||||||
error:
|
error:
|
||||||
config:
|
config:
|
||||||
write: "Can't write the config file!"
|
write: "Can't write the config file!"
|
||||||
check: "Checkconfig failed!"
|
load: "Checkconfig failed!"
|
||||||
key_bad_format: "The key string isn't in good format!"
|
key_bad_format: "The key string isn't in good format!"
|
||||||
no_key_public: "You haven't the public key of %{key}!"
|
no_key_public: "You haven't the public key of %{key}!"
|
||||||
genkey_gpg:
|
genkey_gpg:
|
||||||
exception: "Can't create the GPG key!"
|
exception: "Can't create the GPG key!"
|
||||||
name: "You must define a name for your GPG key!"
|
name: "You must define a name for your GPG key!"
|
||||||
password: "You must define a password for your GPG key!"
|
password: "You must define a password for your GPG key!"
|
||||||
delete:
|
|
||||||
id_no_exist: "Can't delete the item %{id}, it doesn't exist!"
|
|
||||||
export: "Can't export, unable to write in %{file}!"
|
export: "Can't export, unable to write in %{file}!"
|
||||||
gpg_file:
|
gpg_file:
|
||||||
decrypt: "Can't decrypt file!"
|
decrypt: "Can't decrypt file!"
|
||||||
|
@ -41,41 +39,51 @@ en:
|
||||||
config: "Specify the configuration file to use"
|
config: "Specify the configuration file to use"
|
||||||
clipboard: "Disable the clipboard feature"
|
clipboard: "Disable the clipboard feature"
|
||||||
export: "Export a wallet in an yaml file"
|
export: "Export a wallet in an yaml file"
|
||||||
file: "Specify a file, to use with the options [--import | --export | --add]"
|
file_export: "Specify the file where export data"
|
||||||
|
file_import: "Specify the file to import"
|
||||||
force: "No ask to confirm when you delete an item"
|
force: "No ask to confirm when you delete an item"
|
||||||
generate_password: "Generate a random password (default 8 characters)"
|
generate_password: "Generate a random password (default 8 characters)"
|
||||||
|
gpg_exe: "Set the gpg binary path to use"
|
||||||
|
gpg_key: "Specify a GPG key (ex: user@example.com)"
|
||||||
group: "Search the items with specified group"
|
group: "Search the items with specified group"
|
||||||
help: "Show this help message"
|
help: "Show this help message"
|
||||||
id: "Specify an id, to use with the options [--delete | --update]"
|
host: "Specify the server for the synchronization"
|
||||||
|
init: "Initialize mpw"
|
||||||
import: "Import item since a yaml file"
|
import: "Import item since a yaml file"
|
||||||
key: "Specify the key name, to use with the options [--add | --delete | --update]"
|
key: "Specify the key name"
|
||||||
|
lang: "Set the software language"
|
||||||
|
list: "List the wallets"
|
||||||
no_sync: "Disable synchronization with the server"
|
no_sync: "Disable synchronization with the server"
|
||||||
numeric: "Use number to generate a password"
|
numeric: "Use number to generate a password"
|
||||||
|
password: "Change the password for the synchronization"
|
||||||
|
path: "Specify the remote path"
|
||||||
|
pattern: "Given search pattern"
|
||||||
|
port: "Specify the connection port"
|
||||||
|
protocol: "Specify the protocol for the connection"
|
||||||
setup: "Create a new configuration file"
|
setup: "Create a new configuration file"
|
||||||
setup_wallet: "Create a new configuration file for a wallet"
|
setup_wallet: "Create a new configuration file for a wallet"
|
||||||
special_chars: "Use special char to generate a password"
|
special_chars: "Use special char to generate a password"
|
||||||
show: "Search and show the items"
|
show: "Search and show the items"
|
||||||
show_all: "List all items"
|
show_all: "List all items"
|
||||||
remove: "Delete an item"
|
|
||||||
update: "Update an item"
|
|
||||||
usage: "Usage"
|
usage: "Usage"
|
||||||
|
user: "Specify the user for the connection"
|
||||||
wallet: "Specify a wallet to use"
|
wallet: "Specify a wallet to use"
|
||||||
|
wallet_dir: "Set the wallets folder"
|
||||||
|
|
||||||
form:
|
form:
|
||||||
select: "Select the item: "
|
select: "Select the item: "
|
||||||
add_key:
|
add_key:
|
||||||
valid: "Key has been added!"
|
valid: "Key has been added!"
|
||||||
add_item:
|
add_item:
|
||||||
title: "Add a new item"
|
name: "The item's name (mandatory"
|
||||||
name: "Enter the name: "
|
group: "The group's name"
|
||||||
group: "Enter the group (optional): "
|
host: "The hostname or ip"
|
||||||
server: "Enter the hostname or ip: "
|
protocol: "The protocol of the connection (ssh, http, ...)"
|
||||||
protocol: "Enter the protocol of the connection (ssh, http, other): "
|
login: "The login of connection"
|
||||||
login: "Enter the login connection: "
|
password: "The password"
|
||||||
password: "Enter the the password: "
|
port: "The connection port"
|
||||||
port: "Enter the connection port (optional): "
|
comment: "A comment"
|
||||||
comment: "Enter a comment (optional): "
|
otp_key: "The OTP secret"
|
||||||
otp_key: "Enter the otp secret (base32 secret key): "
|
|
||||||
valid: "Item has been added!"
|
valid: "Item has been added!"
|
||||||
clipboard:
|
clipboard:
|
||||||
choice: "What do you want to copy ? [q = quit, p = password, l = login]: "
|
choice: "What do you want to copy ? [q = quit, p = password, l = login]: "
|
||||||
|
@ -88,12 +96,12 @@ en:
|
||||||
login: "Press <l> to copy the login"
|
login: "Press <l> to copy the login"
|
||||||
password: "Press <p> to copy the password"
|
password: "Press <p> to copy the password"
|
||||||
otp_code: "Press <o> to copy the otp code"
|
otp_code: "Press <o> to copy the otp code"
|
||||||
|
quit: "Press <q> to quit"
|
||||||
delete_key:
|
delete_key:
|
||||||
valid: "Key has been deleted!"
|
valid: "Key has been deleted!"
|
||||||
delete_item:
|
delete_item:
|
||||||
ask: "Are you sure you want to remove the item %{id} ?"
|
ask: "Are you sure you want to remove the item ?"
|
||||||
valid: "The item %{id} has been removed!"
|
valid: "The item has been removed!"
|
||||||
not_valid: "The item %{id} hasn't been removed, because it doesn't exist!"
|
|
||||||
import:
|
import:
|
||||||
ask: "Are you sure you want to import this file %{file} ?"
|
ask: "Are you sure you want to import this file %{file} ?"
|
||||||
valid: "The import is succesfull!"
|
valid: "The import is succesfull!"
|
||||||
|
@ -127,16 +135,15 @@ en:
|
||||||
wait: "Please waiting during the GPG key generate, this process can take few minutes."
|
wait: "Please waiting during the GPG key generate, this process can take few minutes."
|
||||||
valid: "Your GPG key has been created ;-)"
|
valid: "Your GPG key has been created ;-)"
|
||||||
update_item:
|
update_item:
|
||||||
title: "Update an item"
|
name: "The item's name (mandatory"
|
||||||
name: "Enter the name [%{name}]: "
|
group: "The group's name"
|
||||||
group: "Enter the group [%{group}]: "
|
host: "The hostname or ip"
|
||||||
server: "Enter the hostname or ip [%{server}]: "
|
protocol: "The protocol of the connection (ssh, http, ...)"
|
||||||
protocol: "Enter the protocol of the connection [%{protocol}]: "
|
login: "The login of connection"
|
||||||
login: "Enter the login connection [%{login}]: "
|
password: "The password (leave empty if you don't want change)"
|
||||||
password: "Enter the the password: "
|
port: "The connection port"
|
||||||
port: "Enter the connection port [%{port}]: "
|
comment: "A comment"
|
||||||
comment: "Enter a comment [%{comment}]: "
|
otp_key: "The OTP secret (leave empty if you don't want change"
|
||||||
otp_key: "Enter the otp secret (base32 secret key): "
|
|
||||||
valid: "Item has been updated!"
|
valid: "Item has been updated!"
|
||||||
export:
|
export:
|
||||||
valid: "The export in %{file} is succesfull!"
|
valid: "The export in %{file} is succesfull!"
|
||||||
|
|
69
i18n/fr.yml
69
i18n/fr.yml
|
@ -3,15 +3,13 @@ fr:
|
||||||
error:
|
error:
|
||||||
config:
|
config:
|
||||||
write: "Impossible d'écrire le fichier de configuration!"
|
write: "Impossible d'écrire le fichier de configuration!"
|
||||||
check: "Le fichier de configuration est invalide!"
|
load: "Le fichier de configuration est invalide!"
|
||||||
key_bad_format: "La clé GPG est invalide!"
|
key_bad_format: "La clé GPG est invalide!"
|
||||||
no_key_public: "Vous ne possédez pas la clé publique de %{key}!"
|
no_key_public: "Vous ne possédez pas la clé publique de %{key}!"
|
||||||
genkey_gpg:
|
genkey_gpg:
|
||||||
exception: "La création de la clé GPG n'a pas pu aboutir!"
|
exception: "La création de la clé GPG n'a pas pu aboutir!"
|
||||||
name: "Vous devez définir un nom pour votre clé GPG!"
|
name: "Vous devez définir un nom pour votre clé GPG!"
|
||||||
password: "Vous devez définir un mot de passe pour votre clé GPG!"
|
password: "Vous devez définir un mot de passe pour votre clé GPG!"
|
||||||
delete:
|
|
||||||
id_no_exist: "Impossible de supprimer l'élément %{id}, car il n'existe pas!"
|
|
||||||
export: "Impossible d'exporter les données dans le fichier %{file}!"
|
export: "Impossible d'exporter les données dans le fichier %{file}!"
|
||||||
gpg_file:
|
gpg_file:
|
||||||
decrypt: "Impossible de déchiffrer le fichier GPG!"
|
decrypt: "Impossible de déchiffrer le fichier GPG!"
|
||||||
|
@ -41,41 +39,51 @@ fr:
|
||||||
config: "Spécifie le fichier de configuration à utiliser"
|
config: "Spécifie le fichier de configuration à utiliser"
|
||||||
clipboard: "Désactive la fonction presse papier"
|
clipboard: "Désactive la fonction presse papier"
|
||||||
export: "Exporte un portefeuille dans un fichier yaml"
|
export: "Exporte un portefeuille dans un fichier yaml"
|
||||||
file: "Spécifie un fichier, à utiliser avec les options [--import | --export | --add]"
|
file_export: "Spécifie le fichier où exporter les données"
|
||||||
|
file_import: "Spécifie le fichier à importer"
|
||||||
force: "Ne demande pas de confirmation pour la suppression d'un élément"
|
force: "Ne demande pas de confirmation pour la suppression d'un élément"
|
||||||
generate_password: "Génére un mot de passe aléatoire (défaut 8 caractères)"
|
generate_password: "Génére un mot de passe aléatoire (défaut 8 caractères)"
|
||||||
|
gpg_exe: "Spécifie le chemin du binaire gpg à utiliser"
|
||||||
|
gpg_key: "Spécifie une clé GPG (ex: user@example.com)"
|
||||||
group: "Recherche les éléments appartenant au groupe spécifié"
|
group: "Recherche les éléments appartenant au groupe spécifié"
|
||||||
help: "Affiche ce message d'aide"
|
help: "Affiche ce message d'aide"
|
||||||
id: "Spécifie un identifiant, à utiliser avec les options [--delete | --update]"
|
host: "Spécifie le serveur pour la synchronisation"
|
||||||
import: "Importe des éléments depuis un fichier yaml"
|
import: "Importe des éléments depuis un fichier yaml"
|
||||||
key: "Spécifie le nom d'une clé, à utiliser avec les options [--add | --delete | --update]"
|
init: "Initialise mpw"
|
||||||
|
key: "Spécifie le nom d'une clé"
|
||||||
|
lang: "Spécifie la langue du logiciel (ex: fr)"
|
||||||
|
list: "Liste les portefeuilles"
|
||||||
no_sync: "Désactive la synchronisation avec le serveur"
|
no_sync: "Désactive la synchronisation avec le serveur"
|
||||||
numeric: "Utilise des chiffre dans la génération d'un mot de passe"
|
numeric: "Utilise des chiffre dans la génération d'un mot de passe"
|
||||||
|
password: "Changer le mot de passe de connexion"
|
||||||
|
path: "Spécifie le chemin distant"
|
||||||
|
pattern: "Motif de donnée à chercher"
|
||||||
|
port: "Spécifie le port de connexion"
|
||||||
|
protocol: "Spécifie le protocol utilisé pour la connexion"
|
||||||
setup: "Création d'un nouveau fichier de configuration"
|
setup: "Création d'un nouveau fichier de configuration"
|
||||||
setup_wallet: "Création d'un nouveau fichier de configuration pour un portefeuille"
|
setup_wallet: "Création d'un nouveau fichier de configuration pour un portefeuille"
|
||||||
special_chars: "Utilise des charactères speciaux dans la génération d'un mot de passe"
|
special_chars: "Utilise des charactères speciaux dans la génération d'un mot de passe"
|
||||||
show: "Recherche et affiche les éléments"
|
show: "Recherche et affiche les éléments"
|
||||||
show_all: "Liste tous les éléments"
|
show_all: "Liste tous les éléments"
|
||||||
remove: "Supprime un élément"
|
|
||||||
update: "Met à jour un élément"
|
|
||||||
usage: "Utilisation"
|
usage: "Utilisation"
|
||||||
|
user: "Spécifie l'identifiant de connection"
|
||||||
wallet: "Spécifie le portefeuille à utiliser"
|
wallet: "Spécifie le portefeuille à utiliser"
|
||||||
|
wallet_dir: "Spécifie le répertoire des portefeuilles"
|
||||||
|
|
||||||
form:
|
form:
|
||||||
select: "Sélectionner l'élément: "
|
select: "Sélectionner l'élément: "
|
||||||
add_key:
|
add_key:
|
||||||
valid: "La clé a bien été ajoutée!"
|
valid: "La clé a bien été ajoutée!"
|
||||||
add_item:
|
add_item:
|
||||||
title: "Ajout d'un nouvel élément"
|
name: "Le nom de l'élément (obligatoire)"
|
||||||
name: "Entrez le nom: "
|
group: "Le nom du groupe"
|
||||||
group: "Entrez le groupe (optionnel): "
|
host: "Le nom de domaine ou l'ip"
|
||||||
server: "Entrez le nom de domaine ou l'ip: "
|
protocol: "Le protocole de connexion (ssh, http, ...)"
|
||||||
protocol: "Entrez le protocole de connexion (ssh, http, other): "
|
login: "L'identifiant de connexion"
|
||||||
login: "Entrez l'identifiant de connexion: "
|
password: "Le mot de passe"
|
||||||
password: "Entrez le mot de passe: "
|
port: "Le port de connexion"
|
||||||
port: "Entrez le port de connexion (optionnel): "
|
comment: "Un commentaire"
|
||||||
comment: "Entrez un commentaire (optionnel): "
|
otp_key: "Le secret OTP"
|
||||||
otp_key: "Entrez le secret OTP: "
|
|
||||||
valid: "L'élément a bien été ajouté!"
|
valid: "L'élément a bien été ajouté!"
|
||||||
clipboard:
|
clipboard:
|
||||||
choice: "Que voulez-vous copier ? : "
|
choice: "Que voulez-vous copier ? : "
|
||||||
|
@ -88,12 +96,12 @@ fr:
|
||||||
login: "Pressez <l> pour copier l'identifiant"
|
login: "Pressez <l> pour copier l'identifiant"
|
||||||
password: "Pressez <p> pour copier le mot de passe"
|
password: "Pressez <p> pour copier le mot de passe"
|
||||||
otp_code: "Pressez <o> pour copier le code OTP"
|
otp_code: "Pressez <o> pour copier le code OTP"
|
||||||
|
quit: "Pressez <q> pour quitter"
|
||||||
delete_key:
|
delete_key:
|
||||||
valid: "La clé a bien été supprimée!"
|
valid: "La clé a bien été supprimée!"
|
||||||
delete_item:
|
delete_item:
|
||||||
ask: "Êtes vous sûre de vouloir supprimer l'élément %{id} ?"
|
ask: "Êtes vous sûre de vouloir supprimer l'élément ?"
|
||||||
valid: "L'élément %{id} a bien été supprimé!"
|
valid: "L'élément a bien été supprimé!"
|
||||||
not_valid: "L'élément %{id} n'a pu être supprimé, car il n'existe pas!"
|
|
||||||
import:
|
import:
|
||||||
ask: "Êtes vous sûre de vouloir importer le fichier %{file} ?"
|
ask: "Êtes vous sûre de vouloir importer le fichier %{file} ?"
|
||||||
valid: "L'import est un succès!"
|
valid: "L'import est un succès!"
|
||||||
|
@ -127,16 +135,15 @@ fr:
|
||||||
wait: "Veuillez patienter durant la génération de votre clé GPG, ce processus peut prendre quelques minutes."
|
wait: "Veuillez patienter durant la génération de votre clé GPG, ce processus peut prendre quelques minutes."
|
||||||
valid: "Votre clé GPG a bien été créée ;-)"
|
valid: "Votre clé GPG a bien été créée ;-)"
|
||||||
update_item:
|
update_item:
|
||||||
title: "Mis à jour d'un élément"
|
name: "Le nom de l'élément (obligatoire)"
|
||||||
name: "Entrez le nom [%{name}]: "
|
group: "Le nom du groupe"
|
||||||
group: "Entrez le groupe [%{group}]: "
|
host: "Le nom de domaine ou l'ip"
|
||||||
server: "Entrez le nom de domaine ou l'ip du serveur [%{server}]: "
|
protocol: "Le protocole de connexion (ssh, http, ...)"
|
||||||
protocol: "Entrez le protocole de connexion [%{protocol}]: "
|
login: "L'identifiant de connexion"
|
||||||
login: "Entrez votre identifiant de connexion [%{login}]: "
|
password: "Le mot de passe (laissez vide si vous ne voulez pas le changer)"
|
||||||
password: "Entrez le mot de passe: "
|
port: "Le port de connexion"
|
||||||
port: "Entrez un port de connexion [%{port}]: "
|
comment: "Un commentaire"
|
||||||
comment: "Entrez un commentaire [%{comment}]: "
|
otp_key: "Le secret OTP (laissez vide si vous ne voulez pas le changer)"
|
||||||
otp_key: "Entrez le secret OTP: "
|
|
||||||
valid: "L'élément a bien été mis à jour!"
|
valid: "L'élément a bien été mis à jour!"
|
||||||
export:
|
export:
|
||||||
valid: "L'export dans %{file} est un succès!"
|
valid: "L'export dans %{file} est un succès!"
|
||||||
|
|
484
lib/mpw/cli.rb
484
lib/mpw/cli.rb
|
@ -17,10 +17,12 @@
|
||||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
require 'readline'
|
require 'readline'
|
||||||
|
require 'locale'
|
||||||
require 'i18n'
|
require 'i18n'
|
||||||
require 'colorize'
|
require 'colorize'
|
||||||
require 'highline/import'
|
require 'highline/import'
|
||||||
require 'clipboard'
|
require 'clipboard'
|
||||||
|
require 'tmpdir'
|
||||||
require 'mpw/item'
|
require 'mpw/item'
|
||||||
require 'mpw/mpw'
|
require 'mpw/mpw'
|
||||||
|
|
||||||
|
@ -30,33 +32,35 @@ class Cli
|
||||||
# Constructor
|
# Constructor
|
||||||
# @args: config -> the config
|
# @args: config -> the config
|
||||||
# sync -> boolean for sync or not
|
# sync -> boolean for sync or not
|
||||||
# clipboard -> enable clopboard
|
def initialize(config, sync=true)
|
||||||
# otp -> enable otp
|
|
||||||
def initialize(config, clipboard=true, sync=true, otp=false)
|
|
||||||
@config = config
|
@config = config
|
||||||
@clipboard = clipboard
|
|
||||||
@sync = sync
|
@sync = sync
|
||||||
@otp = otp
|
end
|
||||||
|
|
||||||
|
# Change a parameter int the config after init
|
||||||
|
# @args: options -> param to change
|
||||||
|
def set_config(options)
|
||||||
|
gpg_key = options[:gpg_key] || @config.key
|
||||||
|
lang = options[:lang] || @config.lang
|
||||||
|
wallet_dir = options[:wallet_dir] || @config.wallet_dir
|
||||||
|
gpg_exe = options[:gpg_exe] || @config.gpg_exe
|
||||||
|
|
||||||
|
@config.setup(gpg_key, lang, wallet_dir, gpg_exe)
|
||||||
|
rescue Exception => e
|
||||||
|
puts "#{I18n.t('display.error')} #15: #{e}".red
|
||||||
|
exit 2
|
||||||
end
|
end
|
||||||
|
|
||||||
# Create a new config file
|
# Create a new config file
|
||||||
# @args: lang -> the software language
|
# @args: options -> set param
|
||||||
def setup(lang)
|
def setup(options)
|
||||||
puts I18n.t('form.setup_config.title')
|
lang = options[:lang] || Locale::Tag.parse(ENV['LANG']).to_simple.to_s[0..1]
|
||||||
puts '--------------------'
|
|
||||||
language = ask(I18n.t('form.setup_config.lang', lang: lang)).to_s
|
|
||||||
key = ask(I18n.t('form.setup_config.gpg_key')).to_s
|
|
||||||
wallet_dir = ask(I18n.t('form.setup_config.wallet_dir', home: "#{@config.config_dir}")).to_s
|
|
||||||
gpg_exe = ask(I18n.t('form.setup_config.gpg_exe')).to_s
|
|
||||||
|
|
||||||
if language.nil? or language.empty?
|
I18n.locale = lang.to_sym
|
||||||
language = lang
|
|
||||||
end
|
|
||||||
I18n.locale = language.to_sym
|
|
||||||
|
|
||||||
@config.setup(key, lang, wallet_dir, gpg_exe)
|
@config.setup(options[:gpg_key], lang, options[:wallet_dir], options[:gpg_exe])
|
||||||
|
|
||||||
raise I18n.t('error.config.check') if not @config.is_valid?
|
load_config
|
||||||
|
|
||||||
puts "#{I18n.t('form.setup_config.valid')}".green
|
puts "#{I18n.t('form.setup_config.valid')}".green
|
||||||
rescue Exception => e
|
rescue Exception => e
|
||||||
|
@ -65,16 +69,10 @@ class Cli
|
||||||
end
|
end
|
||||||
|
|
||||||
# Setup a new GPG key
|
# Setup a new GPG key
|
||||||
def setup_gpg_key
|
# @args: gpg_key -> the key name
|
||||||
puts I18n.t('form.setup_gpg_key.title')
|
def setup_gpg_key(gpg_key)
|
||||||
puts '--------------------'
|
return if @config.check_gpg_key?
|
||||||
ask = ask(I18n.t('form.setup_gpg_key.ask')).to_s
|
|
||||||
|
|
||||||
if not ['Y', 'y', 'O', 'o'].include?(ask)
|
|
||||||
raise I18n.t('form.setup_gpg_key.no_create')
|
|
||||||
end
|
|
||||||
|
|
||||||
name = ask(I18n.t('form.setup_gpg_key.name')).to_s
|
|
||||||
password = ask(I18n.t('form.setup_gpg_key.password')) {|q| q.echo = false}
|
password = ask(I18n.t('form.setup_gpg_key.password')) {|q| q.echo = false}
|
||||||
confirm = ask(I18n.t('form.setup_gpg_key.confirm_password')) {|q| q.echo = false}
|
confirm = ask(I18n.t('form.setup_gpg_key.confirm_password')) {|q| q.echo = false}
|
||||||
|
|
||||||
|
@ -82,16 +80,11 @@ class Cli
|
||||||
raise I18n.t('form.setup_gpg_key.error_password')
|
raise I18n.t('form.setup_gpg_key.error_password')
|
||||||
end
|
end
|
||||||
|
|
||||||
length = ask(I18n.t('form.setup_gpg_key.length')).to_s
|
@password = password.to_s
|
||||||
expire = ask(I18n.t('form.setup_gpg_key.expire')).to_s
|
|
||||||
password = password.to_s
|
|
||||||
|
|
||||||
length = length.nil? or length.empty? ? 2048 : length.to_i
|
|
||||||
expire = expire.nil? or expire.empty? ? 0 : expire.to_i
|
|
||||||
|
|
||||||
puts I18n.t('form.setup_gpg_key.wait')
|
puts I18n.t('form.setup_gpg_key.wait')
|
||||||
|
|
||||||
@config.setup_gpg_key(password, name, length, expire)
|
@config.setup_gpg_key(@password, gpg_key)
|
||||||
|
|
||||||
puts "#{I18n.t('form.setup_gpg_key.valid')}".green
|
puts "#{I18n.t('form.setup_gpg_key.valid')}".green
|
||||||
rescue Exception => e
|
rescue Exception => e
|
||||||
|
@ -100,23 +93,17 @@ class Cli
|
||||||
end
|
end
|
||||||
|
|
||||||
# Setup wallet config for sync
|
# Setup wallet config for sync
|
||||||
def setup_wallet_config
|
# @args: options -> value to change
|
||||||
config = {}
|
def setup_wallet_config(options={})
|
||||||
config['sync'] = {}
|
if not options[:password].nil?
|
||||||
|
options[:password] = ask(I18n.t('form.setup_wallet.password')) {|q| q.echo = false}
|
||||||
puts I18n.t('form.setup_wallet.title')
|
|
||||||
puts '--------------------'
|
|
||||||
config['sync']['type'] = ask(I18n.t('form.setup_wallet.sync_type')).to_s
|
|
||||||
|
|
||||||
if ['ftp', 'ssh'].include?(config['sync']['type'].downcase)
|
|
||||||
config['sync']['host'] = ask(I18n.t('form.setup_wallet.sync_host')).to_s
|
|
||||||
config['sync']['port'] = ask(I18n.t('form.setup_wallet.sync_port')).to_s
|
|
||||||
config['sync']['user'] = ask(I18n.t('form.setup_wallet.sync_user')).to_s
|
|
||||||
config['sync']['password'] = ask(I18n.t('form.setup_wallet.sync_pwd')).to_s
|
|
||||||
config['sync']['path'] = ask(I18n.t('form.setup_wallet.sync_path')).to_s
|
|
||||||
end
|
end
|
||||||
|
|
||||||
@mpw.set_config(config)
|
#wallet_file = wallet.nil? ? "#{@config.wallet_dir}/default.mpw" : "#{@config.wallet_dir}/#{wallet}.mpw"
|
||||||
|
|
||||||
|
@mpw = MPW.new(@config.key, @wallet_file, @password, @config.gpg_exe)
|
||||||
|
@mpw.read_data
|
||||||
|
@mpw.set_config(options)
|
||||||
@mpw.write_data
|
@mpw.write_data
|
||||||
|
|
||||||
puts "#{I18n.t('form.setup_wallet.valid')}".green
|
puts "#{I18n.t('form.setup_wallet.valid')}".green
|
||||||
|
@ -125,6 +112,15 @@ class Cli
|
||||||
exit 2
|
exit 2
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Load config
|
||||||
|
def load_config
|
||||||
|
@config.load_config
|
||||||
|
|
||||||
|
rescue Exception => e
|
||||||
|
puts "#{I18n.t('display.error')} #10: #{e}".red
|
||||||
|
exit 2
|
||||||
|
end
|
||||||
|
|
||||||
# Request the GPG password and decrypt the file
|
# Request the GPG password and decrypt the file
|
||||||
def decrypt
|
def decrypt
|
||||||
if not defined?(@mpw)
|
if not defined?(@mpw)
|
||||||
|
@ -139,97 +135,119 @@ class Cli
|
||||||
exit 2
|
exit 2
|
||||||
end
|
end
|
||||||
|
|
||||||
# Display the query's result
|
# Format items on a table
|
||||||
# @args: search -> the string to search
|
def table(items=[])
|
||||||
# protocol -> search from a particular protocol
|
group = '.'
|
||||||
def display(options={})
|
|
||||||
result = @mpw.list(options)
|
|
||||||
|
|
||||||
case result.length
|
|
||||||
when 0
|
|
||||||
puts I18n.t('display.nothing')
|
|
||||||
|
|
||||||
when 1
|
|
||||||
display_item(result.first)
|
|
||||||
|
|
||||||
else
|
|
||||||
group = nil
|
|
||||||
i = 1
|
i = 1
|
||||||
|
length_total = 10
|
||||||
|
data = { id: { length: 3, color: 'cyan' },
|
||||||
|
host: { length: 9, color: 'yellow' },
|
||||||
|
user: { length: 7, color: 'green' },
|
||||||
|
protocol: { length: 9, color: 'white' },
|
||||||
|
port: { length: 5, color: 'white' },
|
||||||
|
otp: { length: 4, color: 'white' },
|
||||||
|
comment: { length: 14, color: 'magenta' },
|
||||||
|
}
|
||||||
|
|
||||||
result.sort! { |a,b| a.group.downcase <=> b.group.downcase }
|
items.each do |item|
|
||||||
|
data.each do |k, v|
|
||||||
|
next if k == :id or k == :otp
|
||||||
|
|
||||||
result.each do |item|
|
v[:length] = item.send(k.to_s).length + 3 if item.send(k.to_s).to_s.length >= v[:length]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
data[:id][:length] = items.length.to_s.length + 2 if items.length.to_s.length > data[:id][:length]
|
||||||
|
|
||||||
|
data.each_value { |v| length_total += v[:length] }
|
||||||
|
items.sort! { |a, b| a.group.to_s.downcase <=> b.group.to_s.downcase }
|
||||||
|
|
||||||
|
items.each do |item|
|
||||||
if group != item.group
|
if group != item.group
|
||||||
group = item.group
|
group = item.group
|
||||||
|
|
||||||
if group.empty?
|
if group.to_s.empty?
|
||||||
puts I18n.t('display.no_group').yellow
|
puts "\n#{I18n.t('display.no_group')}".red
|
||||||
else
|
else
|
||||||
puts "\n#{group}".yellow
|
puts "\n#{group}".red
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
print " |_ ".yellow
|
print ' '
|
||||||
print "#{i}: ".cyan
|
length_total.times { print '=' }
|
||||||
print item.name
|
print "\n "
|
||||||
print " -> #{item.comment}".magenta if not item.comment.to_s.empty?
|
data.each do |k, v|
|
||||||
|
case k
|
||||||
|
when :id
|
||||||
|
print ' ID'
|
||||||
|
when :otp
|
||||||
|
print '| OTP'
|
||||||
|
else
|
||||||
|
print "| #{k.to_s.capitalize}"
|
||||||
|
end
|
||||||
|
|
||||||
|
(v[:length] - k.to_s.length).times { print ' ' }
|
||||||
|
end
|
||||||
|
print "\n "
|
||||||
|
length_total.times { print '=' }
|
||||||
|
print "\n"
|
||||||
|
end
|
||||||
|
|
||||||
|
print " #{i}".send(data[:id][:color])
|
||||||
|
(data[:id][:length] - i.to_s.length).times { print ' ' }
|
||||||
|
data.each do |k, v|
|
||||||
|
next if k == :id
|
||||||
|
|
||||||
|
if k == :otp
|
||||||
|
print '| '
|
||||||
|
if item.otp; print ' X ' else 4.times { print ' ' } end
|
||||||
|
|
||||||
|
next
|
||||||
|
end
|
||||||
|
|
||||||
|
print '| '
|
||||||
|
print "#{item.send(k.to_s)}".send(v[:color])
|
||||||
|
(v[:length] - item.send(k.to_s).to_s.length).times { print ' ' }
|
||||||
|
end
|
||||||
print "\n"
|
print "\n"
|
||||||
|
|
||||||
i += 1
|
i += 1
|
||||||
end
|
end
|
||||||
|
|
||||||
print "\n"
|
print "\n"
|
||||||
|
end
|
||||||
|
|
||||||
|
# Display the query's result
|
||||||
|
# @args: options -> the option to search
|
||||||
|
def list(options={})
|
||||||
|
result = @mpw.list(options)
|
||||||
|
|
||||||
|
if result.length == 0
|
||||||
|
puts I18n.t('display.nothing')
|
||||||
|
|
||||||
|
else
|
||||||
|
table(result)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Get an item when multiple choice
|
||||||
|
# @args: items -> array of items
|
||||||
|
# @rtrn: item
|
||||||
|
def get_item(items)
|
||||||
|
return items[0] if items.length == 1
|
||||||
|
|
||||||
|
items.sort! { |a,b| a.group.to_s.downcase <=> b.group.to_s.downcase }
|
||||||
choice = ask(I18n.t('form.select')).to_i
|
choice = ask(I18n.t('form.select')).to_i
|
||||||
|
|
||||||
if choice >= 1 and choice < i
|
if choice >= 1 and choice <= items.length
|
||||||
display_item(result[choice-1])
|
return items[choice-1]
|
||||||
else
|
else
|
||||||
puts "#{I18n.t('display.warning')}: #{I18n.t('warning.select')}".yellow
|
return nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
# Display an item in the default format
|
|
||||||
# @args: item -> an array with the item information
|
|
||||||
def display_item(item)
|
|
||||||
puts '--------------------'.cyan
|
|
||||||
print 'Id: '.cyan
|
|
||||||
puts item.id
|
|
||||||
print "#{I18n.t('display.name')}: ".cyan
|
|
||||||
puts item.name
|
|
||||||
print "#{I18n.t('display.group')}: ".cyan
|
|
||||||
puts item.group
|
|
||||||
print "#{I18n.t('display.server')}: ".cyan
|
|
||||||
puts item.host
|
|
||||||
print "#{I18n.t('display.protocol')}: ".cyan
|
|
||||||
puts item.protocol
|
|
||||||
print "#{I18n.t('display.login')}: ".cyan
|
|
||||||
puts item.user
|
|
||||||
|
|
||||||
if @clipboard
|
|
||||||
print "#{I18n.t('display.password')}: ".cyan
|
|
||||||
puts '***********'
|
|
||||||
else
|
|
||||||
print "#{I18n.t('display.password')}: ".cyan
|
|
||||||
puts @mpw.get_password(item.id)
|
|
||||||
|
|
||||||
if @mpw.get_otp_code(item.id) > 0
|
|
||||||
print "#{I18n.t('display.otp_code')}: ".cyan
|
|
||||||
puts "#{@mpw.get_otp_code(item.id)} (#{@mpw.get_otp_remaining_time}s)"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
print "#{I18n.t('display.port')}: ".cyan
|
|
||||||
puts item.port
|
|
||||||
print "#{I18n.t('display.comment')}: ".cyan
|
|
||||||
puts item.comment
|
|
||||||
|
|
||||||
clipboard(item) if @clipboard
|
|
||||||
end
|
|
||||||
|
|
||||||
# Copy in clipboard the login and password
|
# Copy in clipboard the login and password
|
||||||
# @args: item -> the item
|
# @args: item -> the item
|
||||||
def clipboard(item)
|
# clipboard -> enable clipboard
|
||||||
|
def clipboard(item, clipboard=true)
|
||||||
pid = nil
|
pid = nil
|
||||||
|
|
||||||
# Security: force quit after 90s
|
# Security: force quit after 90s
|
||||||
|
@ -246,10 +264,15 @@ class Cli
|
||||||
break
|
break
|
||||||
|
|
||||||
when 'l', 'login'
|
when 'l', 'login'
|
||||||
|
if clipboard
|
||||||
Clipboard.copy(item.user)
|
Clipboard.copy(item.user)
|
||||||
puts I18n.t('form.clipboard.login').green
|
puts I18n.t('form.clipboard.login').green
|
||||||
|
else
|
||||||
|
puts item.user
|
||||||
|
end
|
||||||
|
|
||||||
when 'p', 'password'
|
when 'p', 'password'
|
||||||
|
if clipboard
|
||||||
Clipboard.copy(@mpw.get_password(item.id))
|
Clipboard.copy(@mpw.get_password(item.id))
|
||||||
puts I18n.t('form.clipboard.password').yellow
|
puts I18n.t('form.clipboard.password').yellow
|
||||||
|
|
||||||
|
@ -258,9 +281,16 @@ class Cli
|
||||||
|
|
||||||
Clipboard.clear
|
Clipboard.clear
|
||||||
end
|
end
|
||||||
|
else
|
||||||
|
puts @mpw.get_password(item.id)
|
||||||
|
end
|
||||||
|
|
||||||
when 'o', 'otp'
|
when 'o', 'otp'
|
||||||
|
if clipboard
|
||||||
Clipboard.copy(@mpw.get_otp_code(item.id))
|
Clipboard.copy(@mpw.get_otp_code(item.id))
|
||||||
|
else
|
||||||
|
puts @mpw.get_otp_code(item.id)
|
||||||
|
end
|
||||||
puts I18n.t('form.clipboard.otp', time: @mpw.get_otp_remaining_time).yellow
|
puts I18n.t('form.clipboard.otp', time: @mpw.get_otp_remaining_time).yellow
|
||||||
|
|
||||||
else
|
else
|
||||||
|
@ -268,6 +298,7 @@ class Cli
|
||||||
puts I18n.t('form.clipboard.help.login')
|
puts I18n.t('form.clipboard.help.login')
|
||||||
puts I18n.t('form.clipboard.help.password')
|
puts I18n.t('form.clipboard.help.password')
|
||||||
puts I18n.t('form.clipboard.help.otp_code')
|
puts I18n.t('form.clipboard.help.otp_code')
|
||||||
|
puts I18n.t('form.clipboard.help.quit')
|
||||||
next
|
next
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -277,34 +308,25 @@ class Cli
|
||||||
Clipboard.clear
|
Clipboard.clear
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# List all wallets
|
||||||
|
def list_wallet
|
||||||
|
wallets = Dir.glob("#{@config.wallet_dir}/*.mpw")
|
||||||
|
|
||||||
|
wallets.each do |wallet|
|
||||||
|
puts File.basename(wallet, '.mpw')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# Display the wallet
|
# Display the wallet
|
||||||
# @args: wallet -> the wallet name
|
# @args: wallet -> the wallet name
|
||||||
def get_wallet(wallet=nil)
|
def get_wallet(wallet=nil)
|
||||||
if wallet.to_s.empty?
|
if wallet.to_s.empty?
|
||||||
wallets = Dir.glob("#{@config.wallet_dir}/*.mpw")
|
wallets = Dir.glob("#{@config.wallet_dir}/*.mpw")
|
||||||
|
|
||||||
case wallets.length
|
if wallets.length == 1
|
||||||
when 0
|
|
||||||
puts I18n.t('display.nothing')
|
|
||||||
when 1
|
|
||||||
@wallet_file = wallets[0]
|
@wallet_file = wallets[0]
|
||||||
else
|
else
|
||||||
i = 1
|
@wallet_file = "#{@config.wallet_dir}/default.mpw"
|
||||||
wallets.each do |wallet|
|
|
||||||
print "#{i}: ".cyan
|
|
||||||
puts File.basename(wallet, '.mpw')
|
|
||||||
|
|
||||||
i += 1
|
|
||||||
end
|
|
||||||
|
|
||||||
choice = ask(I18n.t('form.select')).to_i
|
|
||||||
|
|
||||||
if choice >= 1 and choice < i
|
|
||||||
@wallet_file = wallets[choice-1]
|
|
||||||
else
|
|
||||||
puts "#{I18n.t('display.warning')}: #{I18n.t('warning.select')}".yellow
|
|
||||||
exit 2
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
@wallet_file = "#{@config.wallet_dir}/#{wallet}.mpw"
|
@wallet_file = "#{@config.wallet_dir}/#{wallet}.mpw"
|
||||||
|
@ -336,111 +358,158 @@ class Cli
|
||||||
puts "#{I18n.t('display.error')} #15: #{e}".red
|
puts "#{I18n.t('display.error')} #15: #{e}".red
|
||||||
end
|
end
|
||||||
|
|
||||||
# Form to add a new item
|
# Text editor interface
|
||||||
def add
|
# @args: template -> template name
|
||||||
|
# item -> the item to edit
|
||||||
|
# password -> disable field password
|
||||||
|
def text_editor(template_name, item=nil, password=false)
|
||||||
|
editor = ENV['EDITOR'] || 'nano'
|
||||||
options = {}
|
options = {}
|
||||||
|
opts = {}
|
||||||
|
template_file = "#{File.expand_path('../../../templates', __FILE__)}/#{template_name}.erb"
|
||||||
|
template = ERB.new(IO.read(template_file))
|
||||||
|
|
||||||
puts I18n.t('form.add_item.title')
|
Dir.mktmpdir do |dir|
|
||||||
puts '--------------------'
|
tmp_file = "#{dir}/#{template_name}.yml"
|
||||||
options[:name] = ask(I18n.t('form.add_item.name')).to_s
|
|
||||||
options[:group] = ask(I18n.t('form.add_item.group')).to_s
|
|
||||||
options[:host] = ask(I18n.t('form.add_item.server')).to_s
|
|
||||||
options[:protocol] = ask(I18n.t('form.add_item.protocol')).to_s
|
|
||||||
options[:user] = ask(I18n.t('form.add_item.login')).to_s
|
|
||||||
password = ask(I18n.t('form.add_item.password')).to_s
|
|
||||||
options[:port] = ask(I18n.t('form.add_item.port')).to_s
|
|
||||||
options[:comment] = ask(I18n.t('form.add_item.comment')).to_s
|
|
||||||
|
|
||||||
if @otp
|
File.open(tmp_file, 'w') do |f|
|
||||||
otp_key = ask(I18n.t('form.add_item.otp_key')).to_s
|
f << template.result(binding)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
system("#{editor} #{tmp_file}")
|
||||||
|
|
||||||
|
opts = YAML::load_file(tmp_file)
|
||||||
|
end
|
||||||
|
|
||||||
|
opts.delete_if { |k,v| v.to_s.empty? }
|
||||||
|
|
||||||
|
opts.each do |k,v|
|
||||||
|
options[k.to_sym] = v
|
||||||
|
end
|
||||||
|
|
||||||
|
return options
|
||||||
|
end
|
||||||
|
|
||||||
|
# Form to add a new item
|
||||||
|
# @args: password -> generate a random password
|
||||||
|
def add(password=false)
|
||||||
|
options = text_editor('add_form', nil, password)
|
||||||
item = Item.new(options)
|
item = Item.new(options)
|
||||||
|
|
||||||
|
if password
|
||||||
|
options[:password] = MPW::password(length: 24)
|
||||||
|
end
|
||||||
|
|
||||||
@mpw.add(item)
|
@mpw.add(item)
|
||||||
@mpw.set_password(item.id, password)
|
@mpw.set_password(item.id, options[:password]) if options.has_key?(:password)
|
||||||
@mpw.set_otp_key(item.id, otp_key)
|
@mpw.set_otp_key(item.id, options[:otp_key]) if options.has_key?(:otp_key)
|
||||||
@mpw.write_data
|
@mpw.write_data
|
||||||
@mpw.sync(true) if @sync
|
@mpw.sync(true) if @sync
|
||||||
|
|
||||||
puts "#{I18n.t('form.add_item.valid')}".green
|
puts "#{I18n.t('form.add_item.valid')}".green
|
||||||
|
rescue Exception => e
|
||||||
|
puts "#{I18n.t('display.error')} #13: #{e}".red
|
||||||
end
|
end
|
||||||
|
|
||||||
# Update an item
|
# Update an item
|
||||||
# @args: id -> the item's id
|
# @args: options -> the option to search
|
||||||
def update(id)
|
def update(options={})
|
||||||
item = @mpw.search_by_id(id)
|
items = @mpw.list(options)
|
||||||
|
|
||||||
if not item.nil?
|
if items.length == 0
|
||||||
options = {}
|
puts "#{I18n.t('display.warning')}: #{I18n.t('warning.select')}".yellow
|
||||||
|
else
|
||||||
|
table(items) if items.length > 1
|
||||||
|
|
||||||
puts I18n.t('form.update_item.title')
|
item = get_item(items)
|
||||||
puts '--------------------'
|
options = text_editor('update_form', item)
|
||||||
options[:name] = ask(I18n.t('form.update_item.name' , name: item.name)).to_s
|
|
||||||
options[:group] = ask(I18n.t('form.update_item.group' , group: item.group)).to_s
|
|
||||||
options[:host] = ask(I18n.t('form.update_item.server' , server: item.host)).to_s
|
|
||||||
options[:protocol] = ask(I18n.t('form.update_item.protocol', protocol: item.protocol)).to_s
|
|
||||||
options[:user] = ask(I18n.t('form.update_item.login' , login: item.user)).to_s
|
|
||||||
password = ask(I18n.t('form.update_item.password')).to_s
|
|
||||||
options[:port] = ask(I18n.t('form.update_item.port' , port: item.port)).to_s
|
|
||||||
options[:comment] = ask(I18n.t('form.update_item.comment' , comment: item.comment)).to_s
|
|
||||||
|
|
||||||
if @otp
|
|
||||||
otp_key = ask(I18n.t('form.update_item.otp_key')).to_s
|
|
||||||
end
|
|
||||||
|
|
||||||
options.delete_if { |k,v| v.empty? }
|
|
||||||
|
|
||||||
item.update(options)
|
item.update(options)
|
||||||
@mpw.set_password(item.id, password) if not password.empty?
|
@mpw.set_password(item.id, options[:password]) if options.has_key?(:password)
|
||||||
@mpw.set_otp_key(item.id, otp_key) if not otp_key.to_s.empty?
|
@mpw.set_otp_key(item.id, options[:otp_key]) if options.has_key?(:otp_key)
|
||||||
@mpw.write_data
|
@mpw.write_data
|
||||||
@mpw.sync(true) if @sync
|
@mpw.sync(true) if @sync
|
||||||
|
|
||||||
puts "#{I18n.t('form.update_item.valid')}".green
|
puts "#{I18n.t('form.update_item.valid')}".green
|
||||||
else
|
|
||||||
puts I18n.t('display.nothing')
|
|
||||||
end
|
end
|
||||||
rescue Exception => e
|
rescue Exception => e
|
||||||
puts "#{I18n.t('display.error')} #14: #{e}".red
|
puts "#{I18n.t('display.error')} #14: #{e}".red
|
||||||
end
|
end
|
||||||
|
|
||||||
# Remove an item
|
# Remove an item
|
||||||
# @args: id -> the item's id
|
# @args: options -> the option to search
|
||||||
# force -> no resquest a validation
|
def delete(options={})
|
||||||
def delete(id, force=false)
|
items = @mpw.list(options)
|
||||||
@clipboard = false
|
|
||||||
item = @mpw.search_by_id(id)
|
|
||||||
|
|
||||||
if item.nil?
|
if items.length == 0
|
||||||
puts I18n.t('form.delete_item.not_valid', id: id)
|
puts "#{I18n.t('display.warning')}: #{I18n.t('warning.select')}".yellow
|
||||||
return
|
else
|
||||||
end
|
table(items)
|
||||||
|
|
||||||
if not force
|
item = get_item(items)
|
||||||
display_item(item)
|
confirm = ask("#{I18n.t('form.delete_item.ask')} (y/N) ").to_s
|
||||||
|
|
||||||
confirm = ask("#{I18n.t('form.delete_item.ask', id: id)} (y/N) ").to_s
|
|
||||||
if not confirm =~ /^(y|yes|YES|Yes|Y)$/
|
if not confirm =~ /^(y|yes|YES|Yes|Y)$/
|
||||||
return
|
return false
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
item.delete
|
item.delete
|
||||||
@mpw.write_data
|
@mpw.write_data
|
||||||
@mpw.sync(true) if @sync
|
@mpw.sync(true) if @sync
|
||||||
|
|
||||||
puts "#{I18n.t('form.delete_item.valid', id: id)}".green
|
puts "#{I18n.t('form.delete_item.valid')}".green
|
||||||
|
end
|
||||||
rescue Exception => e
|
rescue Exception => e
|
||||||
puts "#{I18n.t('display.error')} #16: #{e}".red
|
puts "#{I18n.t('display.error')} #16: #{e}".red
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Copy a password, otp, login
|
||||||
|
# @args: clipboard -> enable clipboard
|
||||||
|
# options -> the option to search
|
||||||
|
def copy(clipboard=true, options={})
|
||||||
|
items = @mpw.list(options)
|
||||||
|
|
||||||
|
if items.length == 0
|
||||||
|
puts "#{I18n.t('display.warning')}: #{I18n.t('warning.select')}".yellow
|
||||||
|
else
|
||||||
|
table(items)
|
||||||
|
|
||||||
|
item = get_item(items)
|
||||||
|
clipboard(item, clipboard)
|
||||||
|
end
|
||||||
|
rescue Exception => e
|
||||||
|
puts "#{I18n.t('display.error')} #14: #{e}".red
|
||||||
|
end
|
||||||
|
|
||||||
# Export the items in a CSV file
|
# Export the items in a CSV file
|
||||||
# @args: file -> the destination file
|
# @args: file -> the destination file
|
||||||
def export(file)
|
# options -> option to search
|
||||||
@mpw.export(file)
|
def export(file, options)
|
||||||
|
file = 'export-mpw.yml' if file.to_s.empty?
|
||||||
|
items = @mpw.list(options)
|
||||||
|
data = {}
|
||||||
|
i = 1
|
||||||
|
|
||||||
puts "#{I18n.t('export.export.valid', file)}".green
|
items.each do |item|
|
||||||
|
data.merge!(i => { 'host' => item.host,
|
||||||
|
'user' => item.user,
|
||||||
|
'group' => item.group,
|
||||||
|
'password' => @mpw.get_password(item.id),
|
||||||
|
'protocol' => item.protocol,
|
||||||
|
'port' => item.port,
|
||||||
|
'otp_key' => @mpw.get_otp_key(item.id),
|
||||||
|
'comment' => item.comment,
|
||||||
|
'last_edit' => item.last_edit,
|
||||||
|
'created' => item.created,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
i += 1
|
||||||
|
end
|
||||||
|
|
||||||
|
File.open(file, 'w') {|f| f << data.to_yaml}
|
||||||
|
|
||||||
|
puts "#{I18n.t('export.valid', file)}".green
|
||||||
rescue Exception => e
|
rescue Exception => e
|
||||||
puts "#{I18n.t('display.error')} #17: #{e}".red
|
puts "#{I18n.t('display.error')} #17: #{e}".red
|
||||||
end
|
end
|
||||||
|
@ -448,7 +517,26 @@ class Cli
|
||||||
# Import items from a YAML file
|
# Import items from a YAML file
|
||||||
# @args: file -> the import file
|
# @args: file -> the import file
|
||||||
def import(file)
|
def import(file)
|
||||||
@mpw.import(file)
|
raise I18n.t('import.file_empty') if file.to_s.empty?
|
||||||
|
raise I18n.t('import.file_not_exist') if not File.exist?(file)
|
||||||
|
|
||||||
|
YAML::load_file(file).each_value do |row|
|
||||||
|
|
||||||
|
item = Item.new(group: row['group'],
|
||||||
|
host: row['host'],
|
||||||
|
protocol: row['protocol'],
|
||||||
|
user: row['user'],
|
||||||
|
port: row['port'],
|
||||||
|
comment: row['comment'],
|
||||||
|
)
|
||||||
|
|
||||||
|
next if item.empty?
|
||||||
|
|
||||||
|
@mpw.add(item)
|
||||||
|
@mpw.set_password(item.id, row['password']) if not row['password'].to_s.empty?
|
||||||
|
@mpw.set_otp_key(item.id, row['otp_key']) if not row['otp_key'].to_s.empty?
|
||||||
|
end
|
||||||
|
|
||||||
@mpw.write_data
|
@mpw.write_data
|
||||||
|
|
||||||
puts "#{I18n.t('form.import.valid')}".green
|
puts "#{I18n.t('form.import.valid')}".green
|
||||||
|
|
|
@ -57,21 +57,19 @@ class Config
|
||||||
# gpg_exe -> the path of gpg executable
|
# gpg_exe -> the path of gpg executable
|
||||||
# @rtrn: true if le config file is create
|
# @rtrn: true if le config file is create
|
||||||
def setup(key, lang, wallet_dir, gpg_exe)
|
def setup(key, lang, wallet_dir, gpg_exe)
|
||||||
|
|
||||||
if not key =~ /[a-zA-Z0-9.-_]+\@[a-zA-Z0-9]+\.[a-zA-Z]+/
|
if not key =~ /[a-zA-Z0-9.-_]+\@[a-zA-Z0-9]+\.[a-zA-Z]+/
|
||||||
raise I18n.t('error.config.key_bad_format')
|
raise I18n.t('error.config.key_bad_format')
|
||||||
end
|
end
|
||||||
|
|
||||||
if wallet_dir.empty?
|
if wallet_dir.to_s.empty?
|
||||||
wallet_dir = "#{@config_dir}/wallets"
|
wallet_dir = "#{@config_dir}/wallets"
|
||||||
end
|
end
|
||||||
|
|
||||||
config = {'config' => {'key' => key,
|
config = { 'key' => key,
|
||||||
'lang' => lang,
|
'lang' => lang,
|
||||||
'wallet_dir' => wallet_dir,
|
'wallet_dir' => wallet_dir,
|
||||||
'gpg_exe' => gpg_exe,
|
'gpg_exe' => gpg_exe,
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
FileUtils.mkdir_p(wallet_dir, mode: 0700)
|
FileUtils.mkdir_p(wallet_dir, mode: 0700)
|
||||||
File.open(@config_file, 'w') do |file|
|
File.open(@config_file, 'w') do |file|
|
||||||
|
@ -89,9 +87,9 @@ class Config
|
||||||
# expire -> the time of expire to GPG key
|
# expire -> the time of expire to GPG key
|
||||||
# @rtrn: true if the GPG key is create, else false
|
# @rtrn: true if the GPG key is create, else false
|
||||||
def setup_gpg_key(password, name, length = 4096, expire = 0)
|
def setup_gpg_key(password, name, length = 4096, expire = 0)
|
||||||
if name.nil? or name.empty?
|
if name.to_s.empty?
|
||||||
raise "#{I18n.t('error.config.genkey_gpg.name')}"
|
raise "#{I18n.t('error.config.genkey_gpg.name')}"
|
||||||
elsif password.nil? or password.empty?
|
elsif password.to_s.empty?
|
||||||
raise "#{I18n.t('error.config.genkey_gpg.password')}"
|
raise "#{I18n.t('error.config.genkey_gpg.password')}"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -114,22 +112,20 @@ class Config
|
||||||
raise "#{I18n.t('error.config.genkey_gpg.exception')}\n#{e}"
|
raise "#{I18n.t('error.config.genkey_gpg.exception')}\n#{e}"
|
||||||
end
|
end
|
||||||
|
|
||||||
# Check the config file
|
# Load the config file
|
||||||
# @rtrn: true if the config file is correct
|
def load_config
|
||||||
def is_valid?
|
|
||||||
config = YAML::load_file(@config_file)
|
config = YAML::load_file(@config_file)
|
||||||
@key = config['config']['key']
|
@key = config['key']
|
||||||
@lang = config['config']['lang']
|
@lang = config['lang']
|
||||||
@wallet_dir = config['config']['wallet_dir']
|
@wallet_dir = config['wallet_dir']
|
||||||
@gpg_exe = config['config']['gpg_exe']
|
@gpg_exe = config['gpg_exe']
|
||||||
|
|
||||||
raise if @key.empty? or @wallet_dir.empty?
|
raise if @key.empty? or @wallet_dir.empty?
|
||||||
|
|
||||||
I18n.locale = @lang.to_sym
|
I18n.locale = @lang.to_sym
|
||||||
|
|
||||||
return true
|
rescue Exception => e
|
||||||
rescue
|
raise "#{I18n.t('error.config.load')}\n#{e}"
|
||||||
return false
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Check if private key exist
|
# Check if private key exist
|
||||||
|
|
|
@ -22,12 +22,12 @@ module MPW
|
||||||
class Item
|
class Item
|
||||||
|
|
||||||
attr_accessor :id
|
attr_accessor :id
|
||||||
attr_accessor :name
|
|
||||||
attr_accessor :group
|
attr_accessor :group
|
||||||
attr_accessor :host
|
attr_accessor :host
|
||||||
attr_accessor :protocol
|
attr_accessor :protocol
|
||||||
attr_accessor :user
|
attr_accessor :user
|
||||||
attr_accessor :port
|
attr_accessor :port
|
||||||
|
attr_accessor :otp
|
||||||
attr_accessor :comment
|
attr_accessor :comment
|
||||||
attr_accessor :last_edit
|
attr_accessor :last_edit
|
||||||
attr_accessor :last_sync
|
attr_accessor :last_sync
|
||||||
|
@ -38,7 +38,7 @@ class Item
|
||||||
# @args: options -> a hash of parameter
|
# @args: options -> a hash of parameter
|
||||||
# raise an error if the hash hasn't the key name
|
# raise an error if the hash hasn't the key name
|
||||||
def initialize(options={})
|
def initialize(options={})
|
||||||
if not options.has_key?(:name) or options[:name].to_s.empty?
|
if not options.has_key?(:host) or options[:host].to_s.empty?
|
||||||
raise I18n.t('error.update.name_empty')
|
raise I18n.t('error.update.name_empty')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -58,16 +58,16 @@ class Item
|
||||||
# Update the item
|
# Update the item
|
||||||
# @args: options -> a hash of parameter
|
# @args: options -> a hash of parameter
|
||||||
def update(options={})
|
def update(options={})
|
||||||
if options.has_key?(:name) and options[:name].to_s.empty?
|
if options.has_key?(:host) and options[:host].to_s.empty?
|
||||||
raise I18n.t('error.update.name_empty')
|
raise I18n.t('error.update.name_empty')
|
||||||
end
|
end
|
||||||
|
|
||||||
@name = options[:name] if options.has_key?(:name)
|
|
||||||
@group = options[:group] if options.has_key?(:group)
|
@group = options[:group] if options.has_key?(:group)
|
||||||
@host = options[:host] if options.has_key?(:host)
|
@host = options[:host] if options.has_key?(:host)
|
||||||
@protocol = options[:protocol] if options.has_key?(:protocol)
|
@protocol = options[:protocol] if options.has_key?(:protocol)
|
||||||
@user = options[:user] if options.has_key?(:user)
|
@user = options[:user] if options.has_key?(:user)
|
||||||
@port = options[:port].to_i if options.has_key?(:port) and not options[:port].to_s.empty?
|
@port = options[:port].to_i if options.has_key?(:port) and not options[:port].to_s.empty?
|
||||||
|
@otp = options[:otp] if options.has_key?(:otp)
|
||||||
@comment = options[:comment] if options.has_key?(:comment)
|
@comment = options[:comment] if options.has_key?(:comment)
|
||||||
@last_edit = Time.now.to_i if not options.has_key?(:no_update_last_edit)
|
@last_edit = Time.now.to_i if not options.has_key?(:no_update_last_edit)
|
||||||
end
|
end
|
||||||
|
@ -80,12 +80,12 @@ class Item
|
||||||
# Delete all data
|
# Delete all data
|
||||||
def delete
|
def delete
|
||||||
@id = nil
|
@id = nil
|
||||||
@name = nil
|
|
||||||
@group = nil
|
@group = nil
|
||||||
@host = nil
|
@host = nil
|
||||||
@protocol = nil
|
@protocol = nil
|
||||||
@user = nil
|
@user = nil
|
||||||
@port = nil
|
@port = nil
|
||||||
|
@otp = nil
|
||||||
@comment = nil
|
@comment = nil
|
||||||
@created = nil
|
@created = nil
|
||||||
@last_edit = nil
|
@last_edit = nil
|
||||||
|
@ -93,7 +93,7 @@ class Item
|
||||||
end
|
end
|
||||||
|
|
||||||
def empty?
|
def empty?
|
||||||
return @name.to_s.empty?
|
return @id.to_s.empty?
|
||||||
end
|
end
|
||||||
|
|
||||||
def nil?
|
def nil?
|
||||||
|
|
119
lib/mpw/mpw.rb
119
lib/mpw/mpw.rb
|
@ -33,7 +33,7 @@ class MPW
|
||||||
@gpg_exe = gpg_exe
|
@gpg_exe = gpg_exe
|
||||||
@wallet_file = wallet_file
|
@wallet_file = wallet_file
|
||||||
|
|
||||||
if @gpg_exe
|
if not @gpg_exe.to_s.empty?
|
||||||
GPGME::Engine.set_info(GPGME::PROTOCOL_OpenPGP, @gpg_exe, "#{Dir.home}/.gnupg")
|
GPGME::Engine.set_info(GPGME::PROTOCOL_OpenPGP, @gpg_exe, "#{Dir.home}/.gnupg")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -83,12 +83,12 @@ class MPW
|
||||||
if not data.nil? and not data.empty?
|
if not data.nil? and not data.empty?
|
||||||
YAML.load(data).each_value do |d|
|
YAML.load(data).each_value do |d|
|
||||||
@data.push(Item.new(id: d['id'],
|
@data.push(Item.new(id: d['id'],
|
||||||
name: d['name'],
|
|
||||||
group: d['group'],
|
group: d['group'],
|
||||||
host: d['host'],
|
host: d['host'],
|
||||||
protocol: d['protocol'],
|
protocol: d['protocol'],
|
||||||
user: d['user'],
|
user: d['user'],
|
||||||
port: d['port'],
|
port: d['port'],
|
||||||
|
otp: @otp_keys.has_key?(d['id']),
|
||||||
comment: d['comment'],
|
comment: d['comment'],
|
||||||
last_edit: d['last_edit'],
|
last_edit: d['last_edit'],
|
||||||
created: d['created'],
|
created: d['created'],
|
||||||
|
@ -110,8 +110,7 @@ class MPW
|
||||||
@data.each do |item|
|
@data.each do |item|
|
||||||
next if item.empty?
|
next if item.empty?
|
||||||
|
|
||||||
data.merge!(item.id => {'id' => item.id,
|
data.merge!(item.id => { 'id' => item.id,
|
||||||
'name' => item.name,
|
|
||||||
'group' => item.group,
|
'group' => item.group,
|
||||||
'host' => item.host,
|
'host' => item.host,
|
||||||
'protocol' => item.protocol,
|
'protocol' => item.protocol,
|
||||||
|
@ -158,7 +157,7 @@ class MPW
|
||||||
|
|
||||||
File.rename(tmp_file, @wallet_file)
|
File.rename(tmp_file, @wallet_file)
|
||||||
rescue Exception => e
|
rescue Exception => e
|
||||||
File.unlink(tmp_file)
|
File.unlink(tmp_file) if File.exist?(tmp_file)
|
||||||
|
|
||||||
raise "#{I18n.t('error.mpw_file.write_data')}\n#{e}"
|
raise "#{I18n.t('error.mpw_file.write_data')}\n#{e}"
|
||||||
end
|
end
|
||||||
|
@ -211,16 +210,16 @@ class MPW
|
||||||
|
|
||||||
# Set config
|
# Set config
|
||||||
# args: config -> a hash with config options
|
# args: config -> a hash with config options
|
||||||
def set_config(config)
|
def set_config(options={})
|
||||||
@config['sync'] = {} if @config['sync'].nil?
|
@config = {} if @config.nil?
|
||||||
|
|
||||||
@config['sync']['type'] = config['sync']['type']
|
@config['protocol'] = options[:protocol] if options.has_key?(:protocol)
|
||||||
@config['sync']['host'] = config['sync']['host']
|
@config['host'] = options[:host] if options.has_key?(:host)
|
||||||
@config['sync']['port'] = config['sync']['port']
|
@config['port'] = options[:port] if options.has_key?(:port)
|
||||||
@config['sync']['user'] = config['sync']['user']
|
@config['user'] = options[:user] if options.has_key?(:user)
|
||||||
@config['sync']['password'] = config['sync']['password']
|
@config['password'] = options[:password] if options.has_key?(:password)
|
||||||
@config['sync']['path'] = config['sync']['path']
|
@config['path'] = options[:path] if options.has_key?(:path)
|
||||||
@config['sync']['last_sync'] = @config['sync']['last_sync'].nil? ? 0 : @config['sync']['last_sync']
|
@config['last_sync'] = @config['last_sync'].nil? ? 0 : @config['last_sync']
|
||||||
end
|
end
|
||||||
|
|
||||||
# Add a new item
|
# Add a new item
|
||||||
|
@ -241,18 +240,17 @@ class MPW
|
||||||
def list(options={})
|
def list(options={})
|
||||||
result = []
|
result = []
|
||||||
|
|
||||||
search = options[:search].to_s.downcase
|
search = options[:pattern].to_s.downcase
|
||||||
group = options[:group].to_s.downcase
|
group = options[:group].to_s.downcase
|
||||||
|
|
||||||
@data.each do |item|
|
@data.each do |item|
|
||||||
next if item.empty?
|
next if item.empty?
|
||||||
next if not group.empty? and not group.eql?(item.group.downcase)
|
next if not group.empty? and not group.eql?(item.group.to_s.downcase)
|
||||||
|
|
||||||
name = item.name.to_s.downcase
|
|
||||||
host = item.host.to_s.downcase
|
host = item.host.to_s.downcase
|
||||||
comment = item.comment.to_s.downcase
|
comment = item.comment.to_s.downcase
|
||||||
|
|
||||||
if not name =~ /^.*#{search}.*$/ and not host =~ /^.*#{search}.*$/ and not comment =~ /^.*#{search}.*$/
|
if not host =~ /^.*#{search}.*$/ and not comment =~ /^.*#{search}.*$/
|
||||||
next
|
next
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -273,56 +271,9 @@ class MPW
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
# Export to yaml
|
|
||||||
# @args: file -> file where you export the data
|
|
||||||
def export(file)
|
|
||||||
data = {}
|
|
||||||
@data.each do |item|
|
|
||||||
data.merge!(item.id => {'id' => item.id,
|
|
||||||
'name' => item.name,
|
|
||||||
'group' => item.group,
|
|
||||||
'host' => item.host,
|
|
||||||
'protocol' => item.protocol,
|
|
||||||
'user' => item.user,
|
|
||||||
'password' => get_password(item.id),
|
|
||||||
'port' => item.port,
|
|
||||||
'comment' => item.comment,
|
|
||||||
'last_edit' => item.last_edit,
|
|
||||||
'created' => item.created,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
File.open(file, 'w') {|f| f << data.to_yaml}
|
|
||||||
rescue Exception => e
|
|
||||||
raise "#{I18n.t('error.export', file: file)}\n#{e}"
|
|
||||||
end
|
|
||||||
|
|
||||||
# Import to yaml
|
|
||||||
# @args: file -> path to file import
|
|
||||||
def import(file)
|
|
||||||
YAML::load_file(file).each_value do |row|
|
|
||||||
item = Item.new(name: row['name'],
|
|
||||||
group: row['group'],
|
|
||||||
host: row['host'],
|
|
||||||
protocol: row['protocol'],
|
|
||||||
user: row['user'],
|
|
||||||
port: row['port'],
|
|
||||||
comment: row['comment'],
|
|
||||||
)
|
|
||||||
|
|
||||||
raise 'Item is empty' if item.empty?
|
|
||||||
|
|
||||||
@data.push(item)
|
|
||||||
set_password(item.id, row['password'])
|
|
||||||
end
|
|
||||||
rescue Exception => e
|
|
||||||
raise "#{I18n.t('error.import', file: file)}\n#{e}"
|
|
||||||
end
|
|
||||||
|
|
||||||
# Get last sync
|
# Get last sync
|
||||||
def get_last_sync
|
def get_last_sync
|
||||||
return @config['sync']['last_sync'].to_i
|
return @config['last_sync'].to_i
|
||||||
rescue
|
rescue
|
||||||
return 0
|
return 0
|
||||||
end
|
end
|
||||||
|
@ -330,18 +281,18 @@ class MPW
|
||||||
# Sync data with remote file
|
# Sync data with remote file
|
||||||
# @args: force -> force the sync
|
# @args: force -> force the sync
|
||||||
def sync(force=false)
|
def sync(force=false)
|
||||||
return if @config.empty? or @config['sync']['type'].to_s.empty?
|
return if @config.empty? or @config['protocol'].to_s.empty?
|
||||||
return if get_last_sync + 300 > Time.now.to_i and not force
|
return if get_last_sync + 300 > Time.now.to_i and not force
|
||||||
|
|
||||||
tmp_file = "#{@wallet_file}.sync"
|
tmp_file = "#{@wallet_file}.sync"
|
||||||
|
|
||||||
case @config['sync']['type']
|
case @config['protocol']
|
||||||
when 'sftp', 'scp', 'ssh'
|
when 'sftp', 'scp', 'ssh'
|
||||||
require "mpw/sync/ssh"
|
require "mpw/sync/ssh"
|
||||||
sync = SyncSSH.new(@config['sync'])
|
sync = SyncSSH.new(@config)
|
||||||
when 'ftp'
|
when 'ftp'
|
||||||
require 'mpw/sync/ftp'
|
require 'mpw/sync/ftp'
|
||||||
sync = SyncFTP.new(@config['sync'])
|
sync = SyncFTP.new(@config)
|
||||||
else
|
else
|
||||||
raise I18n.t('error.sync.unknown_type')
|
raise I18n.t('error.sync.unknown_type')
|
||||||
end
|
end
|
||||||
|
@ -365,8 +316,7 @@ class MPW
|
||||||
|
|
||||||
# Update item
|
# Update item
|
||||||
if item.last_edit < r.last_edit
|
if item.last_edit < r.last_edit
|
||||||
item.update(name: r.name,
|
item.update(group: r.group,
|
||||||
group: r.group,
|
|
||||||
host: r.host,
|
host: r.host,
|
||||||
protocol: r.protocol,
|
protocol: r.protocol,
|
||||||
user: r.user,
|
user: r.user,
|
||||||
|
@ -394,7 +344,6 @@ class MPW
|
||||||
next if r.last_edit <= get_last_sync
|
next if r.last_edit <= get_last_sync
|
||||||
|
|
||||||
item = Item.new(id: r.id,
|
item = Item.new(id: r.id,
|
||||||
name: r.name,
|
|
||||||
group: r.group,
|
group: r.group,
|
||||||
host: r.host,
|
host: r.host,
|
||||||
protocol: r.protocol,
|
protocol: r.protocol,
|
||||||
|
@ -415,7 +364,7 @@ class MPW
|
||||||
item.set_last_sync
|
item.set_last_sync
|
||||||
end
|
end
|
||||||
|
|
||||||
@config['sync']['last_sync'] = Time.now.to_i
|
@config['last_sync'] = Time.now.to_i
|
||||||
|
|
||||||
write_data
|
write_data
|
||||||
sync.update(@wallet_file)
|
sync.update(@wallet_file)
|
||||||
|
@ -429,8 +378,22 @@ class MPW
|
||||||
# args: id -> the item id
|
# args: id -> the item id
|
||||||
# key -> the new key
|
# key -> the new key
|
||||||
def set_otp_key(id, key)
|
def set_otp_key(id, key)
|
||||||
@otp_keys[id] = encrypt(key)
|
if not key.to_s.empty?
|
||||||
|
@otp_keys[id] = encrypt(key.to_s)
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Get an opt key
|
||||||
|
# args: id -> the item id
|
||||||
|
# key -> the new key
|
||||||
|
def get_otp_key(id)
|
||||||
|
if @otp_keys.has_key?(id)
|
||||||
|
return decrypt(@otp_keys[id])
|
||||||
|
else
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
# Get an otp code
|
# Get an otp code
|
||||||
# @args: id -> the item id
|
# @args: id -> the item id
|
||||||
|
@ -481,6 +444,8 @@ class MPW
|
||||||
# @args: data -> string to decrypt
|
# @args: data -> string to decrypt
|
||||||
private
|
private
|
||||||
def decrypt(data)
|
def decrypt(data)
|
||||||
|
return nil if data.to_s.empty?
|
||||||
|
|
||||||
crypto = GPGME::Crypto.new(armor: true)
|
crypto = GPGME::Crypto.new(armor: true)
|
||||||
|
|
||||||
return crypto.decrypt(data, password: @gpg_pass).read.force_encoding('utf-8')
|
return crypto.decrypt(data, password: @gpg_pass).read.force_encoding('utf-8')
|
||||||
|
@ -495,12 +460,12 @@ class MPW
|
||||||
recipients = []
|
recipients = []
|
||||||
crypto = GPGME::Crypto.new(armor: true, always_trust: true)
|
crypto = GPGME::Crypto.new(armor: true, always_trust: true)
|
||||||
|
|
||||||
|
recipients.push(@key)
|
||||||
@keys.each_key do |key|
|
@keys.each_key do |key|
|
||||||
|
next if key == @key
|
||||||
recipients.push(key)
|
recipients.push(key)
|
||||||
end
|
end
|
||||||
|
|
||||||
recipients.push(@key) if not recipients.index(@key).nil?
|
|
||||||
|
|
||||||
return crypto.encrypt(data, recipients: recipients).read
|
return crypto.encrypt(data, recipients: recipients).read
|
||||||
rescue Exception => e
|
rescue Exception => e
|
||||||
raise "#{I18n.t('error.gpg_file.encrypt')}\n#{e}"
|
raise "#{I18n.t('error.gpg_file.encrypt')}\n#{e}"
|
||||||
|
|
|
@ -23,7 +23,7 @@ Gem::Specification.new do |spec|
|
||||||
spec.add_dependency "locale"
|
spec.add_dependency "locale"
|
||||||
spec.add_dependency "colorize"
|
spec.add_dependency "colorize"
|
||||||
spec.add_dependency "net-ssh"
|
spec.add_dependency "net-ssh"
|
||||||
spec.add_dependency "net-scp"
|
spec.add_dependency "net-sftp"
|
||||||
spec.add_dependency "clipboard"
|
spec.add_dependency "clipboard"
|
||||||
spec.add_dependency "rotp"
|
spec.add_dependency "rotp"
|
||||||
end
|
end
|
||||||
|
|
9
templates/add_form.erb
Normal file
9
templates/add_form.erb
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
---
|
||||||
|
host: # <%= I18n.t('form.add_item.host') %>
|
||||||
|
user: # <%= I18n.t('form.add_item.login') %>
|
||||||
|
group: # <%= I18n.t('form.add_item.group') %>
|
||||||
|
protocol: # <%= I18n.t('form.add_item.protocol') %><% if not password %>
|
||||||
|
password: # <%= I18n.t('form.add_item.password') %><% end %>
|
||||||
|
port: # <%= I18n.t('form.add_item.port') %>
|
||||||
|
comment: # <%= I18n.t('form.add_item.comment') %>
|
||||||
|
otp_key: # <%= I18n.t('form.add_item.otp_key') %>
|
9
templates/setup_form.erb
Normal file
9
templates/setup_form.erb
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
---
|
||||||
|
# <%= I18n.t('form.setup_config.lang') %>
|
||||||
|
language: <%= @config.lang %>
|
||||||
|
# <%= I18n.t('form.setup_config.gpg_key') %>
|
||||||
|
gpg_key: <%= @config.key %>
|
||||||
|
# <%= I18n.t('form.setup_config.wallet_dir') %>
|
||||||
|
wallet_dir: <%= @config.config_dir %>
|
||||||
|
# <%= I18n.t('form.setup_config.gpg_exe') %>
|
||||||
|
gpg_exe: <%= @config.gpg_exe %>
|
17
templates/update_form.erb
Normal file
17
templates/update_form.erb
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
---
|
||||||
|
# <%= I18n.t('form.update_item.host') %>
|
||||||
|
host: <%= item.host %>
|
||||||
|
# <%= I18n.t('form.update_item.login') %>
|
||||||
|
user: <%= item.user %>
|
||||||
|
# <%= I18n.t('form.update_item.password') %>
|
||||||
|
password:
|
||||||
|
# <%= I18n.t('form.update_item.group') %>
|
||||||
|
group: <%= item.group %>
|
||||||
|
# <%= I18n.t('form.update_item.protocol') %>
|
||||||
|
protocol: <%= item.protocol %>
|
||||||
|
# <%= I18n.t('form.update_item.port') %>
|
||||||
|
port: <%= item.port %>
|
||||||
|
# <%= I18n.t('form.update_item.otp_key') %>
|
||||||
|
opt_key:
|
||||||
|
# <%= I18n.t('form.update_item.comment') %>
|
||||||
|
comment: <%= item.comment %>
|
Loading…
Add table
Reference in a new issue