From 40240934c555cbfefbe7b010be33366301207e44 Mon Sep 17 00:00:00 2001 From: nishiki Date: Sat, 7 Feb 2015 00:10:39 +0100 Subject: [PATCH] unstable: new sync class --- lib/MPW.rb | 46 +----------- lib/Sync/SSH.rb | 191 +++++++++++++++++++++++------------------------- lib/UI/Cli.rb | 51 ++----------- 3 files changed, 98 insertions(+), 190 deletions(-) diff --git a/lib/MPW.rb b/lib/MPW.rb index 9bb0e1a..fae4e95 100644 --- a/lib/MPW.rb +++ b/lib/MPW.rb @@ -1,7 +1,6 @@ #!/usr/bin/ruby # author: nishiki # mail: nishiki@yaegashi.fr -# info: a simple script who manage your passwords require 'rubygems' require 'gpgme' @@ -276,50 +275,7 @@ module MPW return false end - # Sync remote data and local data - # @args: data_remote -> array with the data remote - # last_update -> last update - # @rtrn: false if data_remote is nil - def sync(data_remote, last_update) - if not data_remote.instance_of?(Array) - @error_msg = I18n.t('error.sync.array') - return false - else not data_remote.to_s.empty? - @data.each_value do |l| - j = 0 - update = false - - # Update item - data_remote.each do |r| - if l['id'] == r['id'] - if l['date'].to_i < r['date'].to_i - update(r['name'], r['group'], r['host'], r['protocol'], r['login'], r['password'], r['port'], r['comment'], l['id']) - end - update = true - data_remote.delete(r['id']) - break - end - j += 1 - end - - # Delete an old item - if not update and l['date'].to_i < last_update - remove(l['id']) - end - end - end - - # Add item - data_remote.each do |r| - if r['date'].to_i > last_update - update(r['name'], r['group'], r['host'], r['protocol'], r['login'], r['password'], r['port'], r['comment'], r['id']) - end - end - - return encrypt - end - - # Generate a random password + # Generate a random password # @args: length -> the length password # @rtrn: a random string def self.password(length=8) diff --git a/lib/Sync/SSH.rb b/lib/Sync/SSH.rb index 9ebca2d..d61531b 100644 --- a/lib/Sync/SSH.rb +++ b/lib/Sync/SSH.rb @@ -1,110 +1,99 @@ #!/usr/bin/ruby # author: nishiki # mail: nishiki@yaegashi.fr -# info: a simple script who manage your passwords -module MPW - - module Sync - - require 'rubygems' - require 'i18n' - require 'net/ssh' - require 'net/scp' - - class SSH - - attr_accessor :error_msg - attr_accessor :enable - - # Constructor - def initialize - @error_msg = nil - @enable = false - end - - # Connect to server - # @args: host -> the server host - # port -> ther connection port - # gpg_key -> the gpg key - # password -> the remote password - # suffix -> the suffix file - # @rtrn: false if the connection fail - def connect(host, user, password, path, port=nil) - @host = host - @user = user - @password = password - @path = path - @port = port.instance_of?(Integer) ? 22 : port - - Net::SSH.start(@host, @user, password: @password, port: @port) do - @enable = true - end - rescue Exception => e - @error_msg = "#{I18n.t('error.sync.connection')}\n#{e}" - @enable = false - else - return @enable - end - - # Get data on server - # @args: gpg_password -> the gpg password - # @rtrn: nil if nothing data or error - def get(gpg_key, gpg_password) - return nil if not @enable - - tmp_file = tmpfile - Net::SCP.start(@host, @user, password: @password, port: @port) do |scp| - scp.download!(@path, tmp_file) - end - - mpw = MPW.new(tmp_file, gpg_key) - if not mpw.decrypt(gpg_password) - @error_msg = mpw.error_msg - return nil - end - - File.unlink(tmp_file) - return mpw.search - rescue Exception => e - @error_msg = "#{I18n.t('error.sync.download')}\n#{e}" - return nil - end - - # Update the remote data - # @args: data -> the data to send on server - # @rtrn: false if there is a problem - def update(data) - return true if not @enable - - tmp_file = tmpfile - File.open(tmp_file, "w") do |file| - file << data - end - - Net::SCP.start(@host, @user, password: @password, port: @port) do |scp| - scp.upload!(tmp_file, @path) - end - - File.unlink(tmp_file) - - return true - rescue Exception => e - @error_msg = "#{I18n.t('error.sync.upload')}\n#{e}" - return false - end - - # Generate a random string - # @rtrn: a random string - def tmpfile - result = '' - result << ([*('A'..'Z'),*('a'..'z'),*('0'..'9')]).sample(6).join - - return "/tmp/mpw-#{result}" - end +require 'rubygems' +require 'i18n' +require 'yaml' +require 'tempfile' +require 'net/ssh' +require 'net/scp' +module MPW + class SyncSSH + + attr_accessor :error_msg + attr_accessor :enable + + # Constructor + # @args: host -> the server host + # port -> ther connection port + # gpg_key -> the gpg key + # password -> the remote password + def initialize(host, user, password, path, port=nil) + @error_msg = nil + @enable = false + + @host = host + @user = user + @password = password + @path = path + @port = port.instance_of?(Integer) ? 22 : port + end + + # Connect to server + # @rtrn: false if the connection fail + def connect + Net::SSH.start(@host, @user, password: @password, port: @port) do + @enable = true + end + rescue Exception => e + @error_msg = "#{I18n.t('error.sync.connection')}\n#{e}" + @enable = false + else + return @enable + end + + # Get data on server + # @args: gpg_password -> the gpg password + # @rtrn: nil if nothing data or error + def get(gpg_key, gpg_password) + return nil if not @enable + + file_tmp = Tempfile.new('mpw') + Net::SCP.start(@host, @user, password: @password, port: @port) do |scp| + scp.download!(@path, file_tmp.path) + end + + mpw = MPW.new(file_tmp, gpg_key) + raise mpw.error_msg if not mpw.decrypt(gpg_password) + + file_tmp.close(true) + + return mpw.list + rescue Exception => e + @error_msg = "#{I18n.t('error.sync.download')}\n#{e}" + file_tmp.close(true) + return nil + end + + # Update the remote data + # @args: items -> the data to send on server + # @rtrn: false if there is a problem + def update(items) + return true if not @enable + + file_tmp = Tempfile.new('mpw') + + mpw = MPW.new(file_tmp, gpg_key) + items.each do |item| + mpw.add(item) + end + + raise(mpw.error_msg) if not mpw.encrypt + + Net::SCP.start(@host, @user, password: @password, port: @port) do |scp| + scp.upload!(file_tmp, @path) + end + + file_tmp.close(true) + + return true + rescue Exception => e + @error_msg = "#{I18n.t('error.sync.upload')}\n#{e}" + file_tmp.close(true) + return false end end - end diff --git a/lib/UI/Cli.rb b/lib/UI/Cli.rb index c0d4f44..b31f426 100644 --- a/lib/UI/Cli.rb +++ b/lib/UI/Cli.rb @@ -11,6 +11,7 @@ require 'i18n' require 'colorize' require "#{APP_ROOT}/lib/MPW" +require "#{APP_ROOT}/lib/Sync" class Cli @@ -24,52 +25,14 @@ class Cli # Sync the data with the server # @rtnr: true if the synchro is finish def sync - if not defined?(@sync) - case @config.sync_type - when 'mpw' - require "#{APP_ROOT}/lib/Sync/MPWSync" - @sync = MPW::Sync::MPWSync.new - when 'sftp', 'scp', 'ssh' - require "#{APP_ROOT}/lib/Sync/SSH" - @sync = MPW::Sync::SSH.new - when 'ftp' - require "#{APP_ROOT}/lib/Sync/FTP" - @sync = MPW::Sync::FTP.new - else - return false - end - end + @sync = MPW::Sync.new(@config, @password, @mpw.list) - if not @config.sync_host.nil? and not @config.sync_port.nil? - if not @sync.connect(@config.sync_host, @config.sync_user, @config.sync_pwd, @config.sync_path, @config.sync_port) - puts "#{I18n.t('display.error')} #1: #{@sync.error_msg}".red - end - end + raise(@sync.error_msg) if not @sync.get_remote + raise(@sync.error_msg) if not @sync.sync - if @sync.enable - if not @mpw.sync(@sync.get(@config.key, @passwd), @config.last_update) - puts "#{I18n.t('display.error')} #2: #{@mpw.error_msg}".red if not @mpw.error_msg.nil? - puts "#{I18n.t('display.error')} #3: #{@sync.error_msg}".red if not @sync.error_msg.nil? - - elsif not @sync.update(File.open(@config.file_gpg).read) - puts "#{I18n.t('display.error')} #4: #{@sync.error_msg}".red - - elsif not @config.set_last_update - puts "#{I18n.t('display.error')} #5: #{@config.error_msg}".red - - elsif not @mpw.encrypt - puts "#{I18n.t('display.error')} #6: #{@mpw.error_msg}".red - - else - return true - end - end + return true rescue Exception => e puts "#{I18n.t('display.error')} #7: #{e}".red - puts @sync.error_msg if not @sync.error_msg.nil? - puts @config.error_msg if not @config.error_msg.nil? - puts @mpw.error_msg if not @mpw.error_msg.nil? - else return false end @@ -160,8 +123,8 @@ class Cli @mpw = MPW::MPW.new(@config.file_gpg, @config.key, @config.share_keys) end - @passwd = ask(I18n.t('display.gpg_password')) {|q| q.echo = false} - if not @mpw.decrypt(@passwd) + @password = ask(I18n.t('display.gpg_password')) {|q| q.echo = false} + if not @mpw.decrypt(@password) puts "#{I18n.t('display.error')} #11: #{@mpw.error_msg}".red exit 2 end