lib/keylime/credential.rb in keylime-0.1.2 vs lib/keylime/credential.rb in keylime-0.2.0

- old
+ new

@@ -1,6 +1,7 @@ require 'userinput' +require 'yaml' module Keylime ENABLED = begin require 'keychain' true @@ -45,11 +46,11 @@ ).ask end def keychain return @keychain if @keychain - @keychain = StubKeychain.new unless Keylime::ENABLED + @keychain = FileKeychain.new(@options[:keychain]) unless Keylime::ENABLED @keychain ||= Keychain.open(@options[:keychain]) if @options[:keychain] @keychain ||= Keychain end def key_type @@ -61,23 +62,101 @@ end end ## # Stub keychain for if keylime is running on a non-Mac - class StubKeychain + class FileKeychain + def initialize(keychain) + @keychain = keychain + end + def segment - StubKeychainSegment.new + @segment ||= FileKeychainSegment.new(@keychain) end alias internet_passwords segment alias generic_passwords segment end ## # Stub segment for if keylime is running on a non-Mac - class StubKeychainSegment - def where(_) - [] + class FileKeychainSegment + def initialize(keychain) + @keychain = keychain || '~/.keylime' end - def create(_) end + def where(fields = {}) + fields = stringify(fields) + entries.select do |x| + fields.all? { |k, v| x[k] == v } + end + end + + def create(fields = {}) + raise('No fields given') if fields.empty? + fields = stringify(fields) + fields['ref'] = self + new = FileKeychainObject.new(fields) + write_file! entries + [new] + new + end + + def delete(fields = {}) + raise('No fields given') if fields.empty? + fields = stringify(fields) + new = entries.select do |x| + fields.any? { |k, v| x[k] != v } + end + write_file! new + end + + private + + def entries + create_file! unless File.exist? file + YAML.safe_load(File.read(file))['credentials'].map do |x| + x['ref'] = self + FileKeychainObject.new(x) + end + end + + def create_file! + write_file!([]) + end + + def write_file!(entries) + File.open(file, 'w') do |fh| + fh << YAML.dump('credentials' => entries.map(&:fields)) + end + end + + def file + @file ||= File.expand_path @keychain + end + + def stringify(fields) + fields.map { |k, v| [k.to_s, v] }.to_h + end + end + + ## + # Object for stub file keychain + class FileKeychainObject + attr_reader :fields + + def initialize(params = {}) + @ref = params.delete('ref') + @fields = params + end + + def delete + @ref.delete(@fields) + end + + def respond_to_missing?(method, _) + @fields.include?(method.to_s) || super + end + + def method_missing(sym, *args, &block) + @fields[sym.to_s] || super + end end end