1
0
Fork 0
mirror of https://github.com/nishiki/manage-password.git synced 2024-11-23 05:47:53 +00:00
This commit is contained in:
adrien 2013-12-25 18:51:41 +01:00
parent d989050cd9
commit 3806362dbc
5 changed files with 273 additions and 77 deletions

82
i18n/en_US.yml Normal file
View file

@ -0,0 +1,82 @@
---
en_US:
error:
add:
name_empty: "You must define a name!"
config:
write: "Can't write the config file!"
check: "Checkconfig failed!"
key_bad_format: "The key string isn't in good format!"
delete:
id_no_exist: "Can't delete the item, the item %{id} doesn't exist!"
export:
write: "Can't export, impossible to write in %{file}!"
gpg_file:
decrypt: "Can't decrypt file!"
encrypt: "Can't encrypt the GPG file!"
import:
bad_format: "Can't import, the file is bad format!"
read: "Can't import, impossible to read %{file}!"
update:
id_no_exist: "Can't update the item, the item %{id} doesn't exist!"
cli:
form:
add:
title: "Add a new item"
name: "Enter the name: "
group: "Enter the group [default=NoGroup]: "
server: "Enter the hostname or ip: "
protocol: "Enter the protocol of the connection (ssh, http, other): "
login: "Enter the login connection: "
password: "Enter the the password: "
port: "Enter the connection port (optinal): "
comment: "Enter a comment (optinal): "
valid: "Item has been added!"
delete:
ask: "Are you sure to remove the item: %{id} ?"
valid: "The item %{id} has been removed!"
not_valid: "The item %{id} hasn't been removed, because it doesn't exist!"
import:
ask: "Are you sure to import this file: %{file} ?"
valid: "The import is succesfull!"
not_valid: "No data to import!"
setup:
title: "Setup a new config file"
lang: "Choose your language (en, fr, ...): "
gpg_key: "Enter the GPG key: "
gpg_file: "Enter the path to encrypt file [default=%{home}/.mpw.gpg]: "
timeout: "Enter the timeout (in seconde) to GPG password [default=60]: "
valid: "The config file has been created!"
update:
title: "Update an item"
name: "Enter the name [%{name}]: "
group: "Enter the group [%{group}]: "
server: "Enter the hostname or ip [%{server}]: "
protocol: "Enter the protocol of the connection [%{protocol}]: "
login: "Enter the login connection [%{login}]: "
password: "Enter the the password: "
port: "Enter the connection port [%{port}]: "
comment: "Enter a comment [%{comment}]: "
valid: "Item has been updated!"
interactive:
ask_password: "Password GPG: "
bad_password: "Bad password!"
goodbye: "Goodbye!"
unknown_command: "Unknown command!"
display:
comment: "Comment"
error: "ERROR"
gpg_password: "Password GPG: "
group: "Group"
login: "Login"
name: "Name"
nothing: "Nothing result!"
password: "Password"
port: "Port"
protocol: "Protocol"
server: "Server"
formats:
default: ! '%Y-%m-%d'
long: ! '%B %d, %Y'
short: ! '%b %d'
custom: ! '%A, %M %B, %Y @ %l:%M%P'

82
i18n/fr_FR.yml Normal file
View file

@ -0,0 +1,82 @@
---
fr_FR:
error:
add:
name_empty: "Vous devez définir un nom!"
config:
write: "Impossible d'écrire le fichier de configuration!"
check: "Le fichier de configuration est invalide!"
key_bad_format: "La clé GPG est invalide!"
delete:
id_no_exist: "Impossible de supprimer l'élément %{id}, car il n'existe pas!"
export:
write: "Impossible d'exporter les données dans le fichier %{file}!"
gpg_file:
decrypt: "Impossible de déchiffrer le fichier GPG!"
encrypt: "Impossible de chiffrer le fichier GPG!"
import:
bad_format: "Impossible d'importer le fichier car son format est incorrect!"
read: "Impossible d'importer le fichier %{file}, car il n'est pas lisible!"
update:
id_no_exist: "Impossible de mettre à jour l'élément %{id}, car il n'existe pas!"
cli:
form:
add:
title: "Ajout d'un nouvel élément"
name: "Entrez le nom: "
group: "Entrez le groupe [défaut=NoGroup]: "
server: "Entrez the hostname or ip: "
protocol: "Entrez le protocole de connexion (ssh, http, other): "
login: "Entrez l'identifiant de connexion: "
password: "Entrez le mot de passe: "
port: "Entrez le port de connexion (optionnel): "
comment: "Entrez un commentaire (optionnel): "
valid: "L'élément a bien été ajouté!"
delete:
ask: "Êtes vous sûre de vouloir supprimer l'élément %{id} ?"
valid: "L'élément %{id} a bien été supprimé!"
not_valid: "L'élément %{id} n'a pu être supprimé, car il n'existe pas!"
import:
ask: "Êtes vous sûre de vouloir importer le fichier %{file} ?"
valid: "L'import est un succès!"
not_valid: "Aucune donnée à importer!"
setup:
title: "Création d'un nouveau fichier de configuration"
lang: "Choisissez votre langue (en_US, fr_FR, ...) [défaut=%{lang}]: "
gpg_key: "Entrez la clé GPG: "
gpg_file: "Entrez le chemin du fichier qui sera chiffré [défaut=%{home}/.mpw.gpg]: "
timeout: "Entrez le temps (en seconde) du mot de passe GPG [défaut=60]: "
valid: "Le fichier de configuration a bien été créé!"
update:
title: "Mis à jour d'un élément"
name: "Entrez le nom [%{name}]: "
group: "Entrez le groupe [%{group}]: "
server: "Entrez le nom de domaine ou l'ip du serveur [%{server}]: "
protocol: "Entrez le protocole de connexion [%{protocol}]: "
login: "Entrez votre identifiant de connexion [%{login}]: "
password: "Entrez le mot de passe: "
port: "Entrez un port de connexion [%{port}]: "
comment: "Entrez un commentaire [%{comment}]: "
valid: "L'élément a bien été mis à jour!"
interactive:
ask_password: "Mot de passe GPG: "
bad_password: "Mauvais mot de passe!"
goodbye: "Au revoir!"
unknown_command: "Commande inconnue!"
display:
comment: "Commentaire"
error: "ERREUR"
gpg_password: "Mot de passe GPG: "
group: "Groupe"
login: "Identifiant"
name: "Nom"
nothing: "Aucun résultat!"
password: "Mot de passe"
port: "Port"
protocol: "Protocol"
server: "Serveur"
formats:
default: ! '%Y-%m-%d'
long: ! '%B %d, %Y'
short: ! '%b %d'
custom: ! '%A, %M %B, %Y @ %l:%M%P'

View file

@ -7,43 +7,52 @@ require 'rubygems'
require 'highline/import'
require 'pathname'
require 'readline'
require 'i18n'
require "#{APP_ROOT}/lib/MPW.rb"
class Cli
# Constructor
def initialize()
def initialize(lang)
@m = MPW.new()
if not @m.checkconfig()
self.setup()
self.setup(lang)
end
if not self.decrypt()
puts "ERROR: #{@m.error_msg}"
puts "#{I18n.t('cli.display.error')}: #{@m.error_msg}"
exit 2
end
end
# Create a new config file
def setup()
puts "# Setup a new config file"
# @args: lang -> the software language
def setup(lang)
puts "# #{I18n.t('cli.form.setup.title')}"
puts "# --------------------"
key = ask("Enter the GPG key: ")
file_gpg = ask("Enter the path to encrypt file [default=#{Dir.home()}/.mpw.gpg]: ")
timeout_pwd = ask("Enter the timeout (in seconde) to GPG password [default=60]: ")
language = ask(I18n.t('cli.form.setup.lang', :lang => lang))
key = ask(I18n.t('cli.form.setup.gpg_key'))
file_gpg = ask(I18n.t('cli.form.setup.gpg_file', :home => Dir.home()))
timeout_pwd = ask(I18n.t('cli.form.setup.timeout'))
if @m.setup(key, file_gpg, timeout_pwd)
puts "The config file has been created!"
if !File.exist?("#{APP_ROOT}/i18n/#{language}.yml")
language= 'en_US'
end
I18n.load_path = Dir["#{APP_ROOT}/i18n/#{language}.yml"]
I18n.locale = language.to_sym
if @m.setup(key, language, file_gpg, timeout_pwd)
puts I18n.t('cli.form.setup.valid')
else
puts "ERROR: #{@m.error_msg}"
puts "#{I18n.t('cli.display.error')}: #{@m.error_msg}"
end
end
# Request the GPG password and decrypt the file
def decrypt()
@passwd = ask("Password GPG: ") {|q| q.echo = false}
@passwd = ask(I18n.t('cli.display.gpg_password')) {|q| q.echo = false}
return @m.decrypt(@passwd)
end
@ -62,7 +71,7 @@ class Cli
end
end
else
puts "Nothing result!"
puts I18n.t('cli.display.nothing')
end
end
@ -71,14 +80,14 @@ class Cli
def displayFormat(item)
puts "# --------------------"
puts "# Id: #{item[MPW::ID]}"
puts "# Name: #{item[MPW::NAME]}"
puts "# Group: #{item[MPW::GROUP]}"
puts "# Server: #{item[MPW::SERVER]}"
puts "# Protocol: #{item[MPW::PROTOCOL]}"
puts "# Login: #{item[MPW::LOGIN]}"
puts "# Password: #{item[MPW::PASSWORD]}"
puts "# Port: #{item[MPW::PORT]}"
puts "# Comment: #{item[MPW::COMMENT]}"
puts "# #{I18n.t('cli.display.name')}: #{item[MPW::NAME]}"
puts "# #{I18n.t('cli.display.group')}: #{item[MPW::GROUP]}"
puts "# #{I18n.t('cli.display.server')}: #{item[MPW::SERVER]}"
puts "# #{I18n.t('cli.display.protocol')}: #{item[MPW::PROTOCOL]}"
puts "# #{I18n.t('cli.display.login')}: #{item[MPW::LOGIN]}"
puts "# #{I18n.t('cli.display.password')}: #{item[MPW::PASSWORD]}"
puts "# #{I18n.t('cli.display.port')}: #{item[MPW::PORT]}"
puts "# #{I18n.t('cli.display.comment')}: #{item[MPW::COMMENT]}"
end
# Display an item in the alternative format
@ -100,25 +109,25 @@ class Cli
# Form to add a new item
def add()
row = Array.new()
puts "# Add a new item"
puts "# #{I18n.t('cli.form.add.title')}"
puts "# --------------------"
name = ask("Enter the name: ")
group = ask("Enter the group [default=NoGroup]: ")
server = ask("Enter the hostname or ip: ")
protocol = ask("Enter the protocol of the connection (ssh, http, other): ")
login = ask("Enter the login connection: ")
passwd = ask("Enter the the password: ")
port = ask("Enter the connection port (optinal): ")
comment = ask("Enter a comment (optinal): ")
name = ask(I18n.t('cli.form.add.name'))
group = ask(I18n.t('cli.form.add.group'))
server = ask(I18n.t('cli.form.add.server'))
protocol = ask(I18n.t('cli.form.add.protocol'))
login = ask(I18n.t('cli.form.add.login'))
passwd = ask(I18n.t('cli.form.add.password'))
port = ask(I18n.t('cli.form.add.port'))
comment = ask(I18n.t('cli.form.add.comment'))
if @m.add(name, group, server, protocol, login, passwd, port, comment)
if @m.encrypt()
puts "Item has been added!"
puts I18n.t('cli.form.add.valid')
else
puts "ERROR: #{@m.error_msg}"
puts "#{I18n.t('cli.display.error')}: #{@m.error_msg}"
end
else
puts "ERROR: #{@m.error_msg}"
puts "#{I18n.t('cli.display.error')}: #{@m.error_msg}"
end
end
@ -128,28 +137,28 @@ class Cli
row = @m.searchById(id)
if not row.empty?
puts "# Update an item"
puts "# #{I18n.t('cli.form.update.title')}"
puts "# --------------------"
name = ask("Enter the name [#{row[MPW::NAME]}]: ")
group = ask("Enter the group [#{row[MPW::GROUP]}]: ")
server = ask("Enter the hostname or ip [#{row[MPW::SERVER]}]: ")
protocol = ask("Enter the protocol of the connection [#{row[MPW::PROTOCOL]}]: ")
login = ask("Enter the login connection [#{row[MPW::LOGIN]}]: ")
passwd = ask("Enter the the password: ")
port = ask("Enter the connection port [#{row[MPW::PORT]}]: ")
comment = ask("Enter a comment [#{row[MPW::COMMENT]}]: ")
name = ask(I18n.t('cli.form.update.name' , :name => row[MPW::NAME]))
group = ask(I18n.t('cli.form.update.group' , :group => row[MPW::GROUP]))
server = ask(I18n.t('cli.form.update.server' , :server => row[MPW::SERVER]))
protocol = ask(I18n.t('cli.form.update.protocol', :protocol => row[MPW::PROTOCOL]))
login = ask(I18n.t('cli.form.update.login' , :login => row[MPW::LOGIN]))
passwd = ask(I18n.t('cli.form.update.password'))
port = ask(I18n.t('cli.form.update.port' , :port => row[MPW::PORT]))
comment = ask(I18n.t('cli.form.update.comment' , :comment => row[MPW::COMMENT]))
if @m.update(id, name, group, server, protocol, login, passwd, port, comment)
if @m.encrypt()
puts "Item has been updated!"
puts I18n.t('cli.form.update.valid')
else
puts "ERROR: #{@m.error_msg}"
puts "#{I18n.t('cli.display.error')}: #{@m.error_msg}"
end
else
puts "ERROR: #{@m.error_msg}"
puts "#{I18n.t('cli.display.error')}: #{@m.error_msg}"
end
else
puts "Nothing result!"
puts I18n.t('cli.display.nothing')
end
end
@ -163,24 +172,24 @@ class Cli
if result.length > 0
self.displayFormat(result)
confirm = ask("Are you sure to remove the item: #{id} ? (y/N) ")
confirm = ask("#{I18n.t('cli.form.delete.ask', :id => id)} (y/N) ")
if confirm =~ /^(y|yes|YES|Yes|Y)$/
force = true
end
else
puts "Nothing result!"
puts I18n.t('cli.display.nothing')
end
end
if force
if @m.remove(id)
if @m.encrypt()
puts "The item #{id} has been removed!"
puts I18n.t('cli.form.delete.valid', :id => id)
else
puts "ERROR: #{@m.error_msg}"
puts "#{I18n.t('cli.display.error')}: #{@m.error_msg}"
end
else
puts "Nothing item has been removed!"
puts I18n.t('cli.form.delete.not_valid')
end
end
end
@ -191,7 +200,7 @@ class Cli
if @m.export(file)
puts "The export in #{file} is succesfull!"
else
puts "ERROR: #{@m.error_msg}"
puts "#{I18n.t('cli.display.error')}: #{@m.error_msg}"
end
end
@ -208,20 +217,20 @@ class Cli
self.displayFormat(r)
end
confirm = ask("Are you sure to import this file: #{file} ? (y/N) ")
confirm = ask("#{I18n.t('cli.form.import.ask', :file => file)} (y/N) ")
if confirm =~ /^(y|yes|YES|Yes|Y)$/
force = true
end
else
puts "No data to import!"
puts I18n.t('cli.form.import.not_valid')
end
end
if force
if @m.import(file) && @m.encrypt()
puts "The import is succesfull!"
puts I18n.t('cli.form.import.valid')
else
puts "ERROR: #{@m.error_msg}"
puts "#{I18n.t('cli.display.error')}: #{@m.error_msg}"
end
end
end
@ -231,15 +240,15 @@ class Cli
group = nil
last_access = Time.now.to_i
while buf = Readline.readline("<mpw> ", true)
while buf = Readline.readline('<mpw> ', true)
if @m.timeout_pwd < Time.now.to_i - last_access
passwd_confirm = ask("Password GPG: ") {|q| q.echo = false}
passwd_confirm = ask(I18n.t('cli.interactive.ask_password')) {|q| q.echo = false}
if @passwd.eql?(passwd_confirm)
last_access = Time.now.to_i
else
puts 'Bad password!'
puts I18n.t('cli.interactive.bad_password')
next
end
else
@ -293,11 +302,11 @@ class Cli
puts '# exit'
puts '# q'
when 'quit', 'exit', 'q'
puts 'Goodbye!'
puts I18n.t('cli.interactive.goodbye')
break
else
if !command[0].nil? && !command[0].empty?
puts 'Unknow command!'
puts I18n.t('cli.interactive.unknown_command')
end
end

View file

@ -7,6 +7,7 @@ require 'rubygems'
require 'gpgme'
require 'csv'
require 'yaml'
require 'i18n'
class MPW
@ -31,14 +32,15 @@ class MPW
# Create a new config file
# @args: key -> the gpg key to encrypt
# lang -> the software language
# file_gpg -> the file who is encrypted
# file_pwd -> the file who stock the password
# timeout_pwd -> time to save the password
# @rtrn: true if le config file is create
def setup(key, file_gpg, timeout_pwd)
def setup(key, lang, file_gpg, timeout_pwd)
if not key =~ /[a-zA-Z0-9.-_]+\@[a-zA-Z0-9]+\.[a-zA-Z]+/
@error_msg = "The key string isn't in good format!"
@error_msg = I18n.t('error.config.key_bad_format')
return false
end
@ -49,6 +51,7 @@ class MPW
timeout_pwd.empty? ? (timeout_pwd = 60) : (timeout_pwd = timeout_pwd.to_i)
config = {'config' => {'key' => key,
'lang' => lang,
'file_gpg' => file_gpg,
'timeout_pwd' => timeout_pwd}}
@ -57,7 +60,7 @@ class MPW
file << config.to_yaml
end
rescue Exception => e
@error_msg = "Can't write the config file!\n#{e}"
@error_msg = "#{I18n.t('error.config.write')}\n#{e}"
return false
end
@ -70,16 +73,25 @@ class MPW
begin
config = YAML::load_file(@file_config)
@key = config['config']['key']
@lang = config['config']['lang']
@file_gpg = config['config']['file_gpg']
@timeout_pwd = config['config']['timeout_pwd'].to_i
if @key.empty? || @file_gpg.empty?
@error_msg = "Checkconfig failed!"
@error_msg = I18n.t('error.config.check')
return false
end
if !@lang.nil? && !@lang.empty?
if !File.exist?("#{APP_ROOT}/i18n/#{@lang}.yml")
language= 'en_US'
end
I18n.load_path = Dir["#{APP_ROOT}/i18n/#{@lang}.yml"]
I18n.locale = @lang.to_sym
end
rescue Exception => e
@error_msg = "Checkconfig failed!\n#{e}"
@error_msg = "#{I18n.t('error.config.check')}\n#{e}"
return false
end
@ -110,7 +122,7 @@ class MPW
File.delete(@file_pwd)
end
@error_msg = "Can't decrypt file!\n#{e}"
@error_msg = "#{I18n.t('error.gpg_file.decrypt')}\n#{e}"
return false
end
end
@ -133,7 +145,7 @@ class MPW
return true
rescue Exception => e
@error_msg = "Can't encrypt the GPG file!\n#{e}"
@error_msg = "#{I18n.t('error.gpg_file.encrypt')}\n#{e}"
return false
end
end
@ -191,7 +203,7 @@ class MPW
row = Array.new()
if name.nil? || name.empty?
@error_msg = "You must define a name!"
@error_msg = I18n.t('error.add.name_empty')
return false
end
@ -257,7 +269,7 @@ class MPW
return true
else
@error_msg = "Can't update the item, the item #{id} doesn't exist!"
@error_msg = I18n.t('error.update.id_no_exist', :id => id)
return false
end
end
@ -269,7 +281,7 @@ class MPW
if not @data.delete_at(id.to_i).nil?
return true
else
@error_msg = "Can't delete the item, the item #{id} doesn't exist!"
@error_msg = I18n.t('error.delete.id_no_exist', :id => id)
return false
end
end
@ -288,7 +300,7 @@ class MPW
return true
rescue Exception => e
@error_msg = "Can't export, impossible to write in #{file}!\n#{e}"
@error_msg = "#{I18n.t('error.export.write', :file => file)}\n#{e}"
return false
end
end
@ -301,7 +313,7 @@ class MPW
data_new = IO.read(file)
data_new.lines do |line|
if not line =~ /(.*,){6}/
@error_msg = "Can't import, the file is bad format!"
@error_msg = I18n.t('error.import.bad_format')
return false
else
row = line.parse_csv.unshift(0)
@ -313,7 +325,7 @@ class MPW
return true
rescue Exception => e
@error_msg = "Can't import, impossible to read #{file}!\n#{e}"
@error_msg = "#{I18n.t('error.import.read', :file => file)}\n#{e}"
return false
end
end
@ -329,7 +341,7 @@ class MPW
data = IO.read(file)
data.lines do |line|
if not line =~ /(.*,){6}/
@error_msg = "Can't import, the file is bad format!"
@error_msg = I18n.t('error.import.bad_format')
return false
else
result.push(line.parse_csv.unshift(id))
@ -340,7 +352,7 @@ class MPW
return result
rescue Exception => e
@error_msg = "Can't import, impossible to read #{file}!\n#{e}"
@error_msg = "#{I18n.t('error.import.read', :file => file)}\n#{e}"
return false
end
end

13
mpw
View file

@ -6,10 +6,21 @@
require 'rubygems'
require 'optparse'
require 'pathname'
require 'locale'
require 'i18n'
APP_ROOT = File.dirname(Pathname.new(__FILE__).realpath)
require "#{APP_ROOT}/lib/Cli.rb"
lang = Locale::Tag.parse(ENV['LANG']).to_simple.to_s
if !File.exist?("#{APP_ROOT}/i18n/#{lang}.yml")
lang = 'en_US'
end
I18n.load_path = Dir["#{APP_ROOT}/i18n/#{lang}.yml"]
I18n.locale = lang.to_sym
options = {}
options[:force] = false
options[:format] = false
@ -74,7 +85,7 @@ OptionParser.new do |opts|
end.parse!
cli = Cli.new()
cli = Cli.new(lang)
# Display the item's informations
if not options[:setup].nil?