class RubeePass::Entry

Attributes

group[RW]
keepass[RW]
notes[RW]
password[RW]
path[RW]
title[RW]
url[RW]
username[RW]
uuid[RW]

Public Class Methods

from_xml(keepass, parent, xml) click to toggle source
# File lib/rubeepass/entry.rb, line 112
def self.from_xml(keepass, parent, xml)
    attrs = Hash.new
    attachs = Hash.new

    uuid = xml.elements["UUID"].text || ""

    xml.elements.each("String") do |elem|
        key = elem.elements["Key"].text
        value = elem.elements["Value"]

        attrs[key] = value.text || ""
        if (value.attributes["Protected"] == "True")
            attrs[key] = handle_protected(keepass, value.text)
        end
    end

    # Handle protected data from history
    xml.elements.each("History/Entry/String/Value") do |value|
        if (value.attributes["Protected"] == "True")
            handle_protected(keepass, value.text)
        end
    end

    xml.elements.each("Binary") do |elem|
        key = elem.elements["Key"].text
        value = elem.elements["Value"].attributes["Ref"]
        attachs[key] = value
    end

    return RubeePass::Entry.new(
        parent,
        keepass,
        attrs,
        attachs,
        uuid
    )
end
handle_protected(keepass, base64) click to toggle source
# File lib/rubeepass/entry.rb, line 150
def self.handle_protected(keepass, base64)
    return nil if (base64.nil?)

    data = nil
    begin
        data = base64.unpack("m*")[0]
        if (data.length != data.bytesize)
            data = data.unpack("H*").pack("H*")
        end
    rescue ArgumentError
        raise RubeePass::Error::InvalidProtectedData.new
    end
    if (data.nil?)
        raise RubeePass::Error::InvalidProtectedData.new
    end

    return keepass.protected_decryptor.add_to_stream(data)
end
new(group, keepass, attributes, attachments, uuid) click to toggle source
# File lib/rubeepass/entry.rb, line 201
def initialize(group, keepass, attributes, attachments, uuid)
    @group = group
    @keepass = keepass
    @attributes = attributes
    @attachments = attachments

    @notes = attribute("Notes")
    @password = attribute("Password")
    @title = attribute("Title")
    @url = attribute("URL")
    @username = attribute("UserName")

    @uuid = uuid

    @path = @title
    @path = "#{@group.path}/#{@title}" if (@group)
    @path.gsub!(%r{^//}, "/")
end

Public Instance Methods

<=>(other) click to toggle source
# File lib/rubeepass/entry.rb, line 24
def <=>(other)
    if (self.title.downcase == other.title.downcase)
        return (self.uuid <=> other.uuid)
    end
    return (self.title.downcase <=> other.title.downcase)
end
==(other) click to toggle source
# File lib/rubeepass/entry.rb, line 20
def ==(other)
    return (self.uuid == other.uuid)
end
additional_attributes() click to toggle source
# File lib/rubeepass/entry.rb, line 31
def additional_attributes
    return attributes.select do |key, value|
        key.match(/^(Notes|Password|Title|URL|UserName)$/).nil?
    end
end
attachment(name) click to toggle source
# File lib/rubeepass/entry.rb, line 37
def attachment(name)
    return nil if (@keepass.nil?)
    return nil if (!has_attachment?(name))
    return @keepass.attachment_decoder.get_attachment(
        @attachments[name]
    )
end
attachments() click to toggle source
# File lib/rubeepass/entry.rb, line 45
def attachments
    attachments = Hash.new

    @attachments.each do |key, value|
        attachments[key] = attachment(key)
    end

    return attachments
end
attribute(attr) click to toggle source
# File lib/rubeepass/entry.rb, line 55
def attribute(attr)
    return nil if (@keepass.nil?)
    return "" if (!has_attribute?(attr))

    begin
        return @keepass.protected_decryptor.decrypt(
            @attributes[attr]
        )
    rescue
        return @attributes[attr]
    end
end
attributes() click to toggle source
# File lib/rubeepass/entry.rb, line 68
def attributes
    return nil if (@keepass.nil?)

    attrs = Hash.new
    @attributes.each do |key, value|
        attrs[key] = attribute(key)
    end

    return attrs
end
details(level = 0, show_passwd = false) click to toggle source
# File lib/rubeepass/entry.rb, line 79
def details(level = 0, show_passwd = false)
    lvl = "  " * level

    r = Array.new
    r.push("#{lvl}#{hilight_attr("Title:")} #{@title}")
    # r.push("#{lvl}#{hilight_attr("UUID:")} #{@uuid}")
    r.push("#{lvl}#{hilight_attr("Username:")} #{@username}")
    if (show_passwd)
        r.push(
            "#{lvl}#{hilight_password("Password:")} #{@password}"
        )
    end
    r.push("#{lvl}#{hilight_attr("URL:")} #{@url}")

    r.push("#{lvl}#{hilight_attr("Notes:")}") if (!@notes.empty?)
    @notes.each_line do |line|
        r.push("#{lvl}  #{line.strip}")
    end

    additional_attributes.each do |k, v|
        r.push("#{lvl}#{hilight_attr("#{k}:")} #{v}")
    end

    if (!@attachments.empty?)
        r.push("#{lvl}#{hilight_attr("Attachments:")}")
    end
    @attachments.keys.each do |name|
        r.push("#{lvl}  #{name}")
    end

    return r.join("\n")
end
has_attachment?(name) click to toggle source
# File lib/rubeepass/entry.rb, line 169
def has_attachment?(name)
    return !@attachments[name].nil?
end
has_attachment_like?(name) click to toggle source
# File lib/rubeepass/entry.rb, line 173
def has_attachment_like?(name)
    return @attachments.any? do |k, v|
        k.downcase == name.downcase
    end
end
has_attribute?(attr) click to toggle source
# File lib/rubeepass/entry.rb, line 179
def has_attribute?(attr)
    return !@attributes[attr].nil?
end
has_attribute_like?(attr) click to toggle source
# File lib/rubeepass/entry.rb, line 183
def has_attribute_like?(attr)
    return @attributes.any? do |k, v|
        k.downcase == attr.downcase
    end
end
is_pwned?() click to toggle source
# File lib/rubeepass/entry.rb, line 220
def is_pwned?
    sha = Digest::SHA1.hexdigest(@password).upcase
    url = URI("https://api.pwnedpasswords.com/range/#{sha[0..4]}")
    http = Net::HTTP.new(url.host, url.port)
    http.use_ssl = true
    res = http.request(Net::HTTP::Get.new(url))

    return true if (res.body.match(/#{sha[5..-1]}/))
    return false
end
method_missing(method_name, *args) click to toggle source
Calls superclass method
# File lib/rubeepass/entry.rb, line 231
def method_missing(method_name, *args)
    super if (@keepass.nil?)

    if (method_name.to_s.match(/^copy_.+_to_clipboard$/))
        method_name = method_name.to_s.gsub(
            /^copy_(.+)_to_clipboard$/,
            "\\1"
        )
        case method_name
        when "password"
            @keepass.copy_to_clipboard(@password)
        when "url"
            @keepass.copy_to_clipboard(@url)
        when "username"
            @keepass.copy_to_clipboard(@username)
        else
            super
        end
    elsif (method_name.match(/^echo_.+$/))
        case method_name.to_s.gsub(/^echo_/, "")
        when "password"
            puts @password
        when "url"
            puts @url
        when "username"
            puts @username
        else
            super
        end
    else
        super
    end
end
to_s() click to toggle source
# File lib/rubeepass/entry.rb, line 265
def to_s
    return details
end

Private Instance Methods

hilight_attr(title) click to toggle source
# File lib/rubeepass/entry.rb, line 189
def hilight_attr(title)
    return title if (!RubeePass.hilight?)
    return title.light_green
end
hilight_password(passwd) click to toggle source
# File lib/rubeepass/entry.rb, line 195
def hilight_password(passwd)
    return passwd if (!RubeePass.hilight?)
    return passwd.light_red
end