class Keepassx::Fieldable

Attributes

field_descriptor[R]
fields[R]

Public Class Methods

create_fieldable_methods(methods) click to toggle source
# File lib/keepassx/fieldable.rb, line 31
def create_fieldable_methods(methods)
  methods.each do |_, method, _|
    define_method method do
      get method
    end

    define_method "#{method}=" do |v|
      set method, v
    end
  end
end
fields() click to toggle source

Return the list of fields' names

# File lib/keepassx/fieldable.rb, line 45
def fields
  @fields ||= field_descriptor.fields_description.map { |_, name, _| name }
end
new(payload) { || ... } click to toggle source
# File lib/keepassx/fieldable.rb, line 8
def initialize(payload)
  @fields = []

  if payload.is_a?(StringIO)
    @fields = decode_payload(payload)
  elsif payload.is_a?(Hash)
    yield
  else
    raise ArgumentError, "Expected StringIO or Hash, got #{payload.class}"
  end
end
set_field_descriptor(klass) click to toggle source
# File lib/keepassx/fieldable.rb, line 25
def set_field_descriptor(klass)
  @field_descriptor = klass
  create_fieldable_methods(klass.fields_description)
end

Public Instance Methods

encode() click to toggle source
# File lib/keepassx/fieldable.rb, line 71
def encode
  buffer = +''
  fields.each do |field|
    buffer << field.encode
  end
  buffer
end
inspect() click to toggle source
# File lib/keepassx/fieldable.rb, line 80
def inspect
  output = []
  default_fields.each_key do |field_name|
    if field_name == :password
      output << 'password=[FILTERED]'
    else
      output << "#{field_name}=#{send(field_name)}" unless field_name == :terminator
    end
  end
  "<#{self.class} #{output.join(', ')}>"
end
length() click to toggle source
# File lib/keepassx/fieldable.rb, line 52
def length
  fields.map(&:length).reduce(&:+)
end
to_hash(opts = {}) click to toggle source
# File lib/keepassx/fieldable.rb, line 57
def to_hash(opts = {})
  skip_date = opts.fetch(:skip_date, false)

  result = {}
  fields.each do |field|
    next if excluded_field?(field.name)
    next if date_field?(field.name) && skip_date

    result[field.name] = field.data
  end
  result
end

Private Instance Methods

build_payload(payload) click to toggle source
# File lib/keepassx/fieldable.rb, line 109
def build_payload(payload)
  fields = []
  default_fields.merge(payload).each do |k, v|
    fields << self.class.field_descriptor.new(name: k, data: v)
  end
  fields
end
date_field?(field) click to toggle source
# File lib/keepassx/fieldable.rb, line 156
def date_field?(field)
  %w[creation_time last_mod_time last_acc_time expiration_time].include?(field)
end
decode_payload(payload) click to toggle source
# File lib/keepassx/fieldable.rb, line 96
def decode_payload(payload)
  fields = []

  loop do
    field = self.class.field_descriptor.new(payload)
    fields << field
    break if field.terminator?
  end

  fields
end
excluded_field?(field) click to toggle source
# File lib/keepassx/fieldable.rb, line 146
def excluded_field?(field)
  exclusion_list.include?(field)
end
exclusion_list() click to toggle source
# File lib/keepassx/fieldable.rb, line 151
def exclusion_list
  %w[terminator]
end
get(name) click to toggle source
# File lib/keepassx/fieldable.rb, line 128
def get(name)
  field = @fields.find { |f| f.name == name.to_s }
  field&.data
end
set(name, value) click to toggle source
# File lib/keepassx/fieldable.rb, line 134
def set(name, value)
  field = @fields.find { |f| f.name == name.to_s }
  if field.nil?
    field = self.class.field_descriptor.new(name: name, data: value)
    @fields << field
  else
    field.data = value
  end
  field
end
valid_integer?(field) click to toggle source
# File lib/keepassx/fieldable.rb, line 118
def valid_integer?(field)
  field.is_a?(Integer)
end
valid_string?(field) click to toggle source
# File lib/keepassx/fieldable.rb, line 123
def valid_string?(field)
  field.is_a?(String) && !field.empty?
end