Class: Keychain::Item

Inherits:
Sec::Base show all
Defined in:
lib/keychain/item.rb

Overview

An individual item from the keychain. Individual accessors are generated for the items attributes

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Sec::Base

register_type

Constructor Details

#initialize(*args) ⇒ Item

Returns a new instance of Item.



51
52
53
54
# File 'lib/keychain/item.rb', line 51

def initialize(*args)
  super
  @attributes = {}
end

Instance Attribute Details

#attributesObject

Returns the value of attribute attributes.



14
15
16
# File 'lib/keychain/item.rb', line 14

def attributes
  @attributes
end

Class Method Details

.from_dictionary_of_attributes(cf_dict) ⇒ Object



112
113
114
# File 'lib/keychain/item.rb', line 112

def self.from_dictionary_of_attributes(cf_dict)
  new(0).tap {|item| item.send :update_self_from_dictionary, cf_dict}
end

.new(attrs_or_pointer) ⇒ Object

Creates a new keychain item either from an FFI::Pointer or a hash of attributes

Parameters:

  • attrs_or_pointer (FFI::Pointer, Hash)

    Either an FFI::Pointer to an existing SecKeychainItemRef to wrap or hash of attributes to create a new, unsaved Keychain::Item from see Scope#create



40
41
42
43
44
45
46
47
48
# File 'lib/keychain/item.rb', line 40

def self.new(attrs_or_pointer)
  if attrs_or_pointer.is_a? Hash
    super(0).tap do |result|
      attrs_or_pointer.each {|k,v| result.send("#{k}=", v)}
    end
  else
    super
  end
end

Instance Method Details

#deleteObject

Removes the item from the associated keychain



58
59
60
61
62
# File 'lib/keychain/item.rb', line 58

def delete
  status = Sec.SecKeychainItemDelete(self)
  Sec.check_osstatus(status)
  self
end

#inspectString

returns a programmer friendly description of the item

Returns:

  • (String)


19
20
21
# File 'lib/keychain/item.rb', line 19

def inspect
  "<SecKeychainItem 0x#{@ptr.address.to_s(16)} #{service ? "service: #{service}" : "server: #{server}"} account: #{}>"
end

#keychainKeychain::Keychain

Returns the keychain the item is in

Returns:



75
76
77
78
79
80
# File 'lib/keychain/item.rb', line 75

def keychain
  out = FFI::MemoryPointer.new :pointer
  status = Sec.SecKeychainItemCopyKeychain(self,out)
  Sec.check_osstatus(status)
  CF::Base.new(out.read_pointer).release_on_gc
end

#passwordString

Fetches the password data associated with the item. This may cause the user to be asked for access

Returns:

  • (String)

    The password data, an ASCII_8BIT encoded string



84
85
86
87
88
89
90
91
92
# File 'lib/keychain/item.rb', line 84

def password
  return @unsaved_password if @unsaved_password
  out_buffer = FFI::MemoryPointer.new(:pointer)
  status = Sec.SecItemCopyMatching({Sec::Query::ITEM_LIST => CF::Array.immutable([self]),
                           Sec::Query::CLASS => klass, 
                           Sec::Query::RETURN_DATA => true}.to_cf, out_buffer)
  Sec.check_osstatus(status)
  CF::Base.typecast(out_buffer.read_pointer).to_s
end

#password=(value) ⇒ String

Note:

The new password is not saved into the keychain until you call #save!

Set a new password for the item

Parameters:

  • value (String)

    The new value for the password

Returns:

  • (String)

    The set value



68
69
70
# File 'lib/keychain/item.rb', line 68

def password=(value)
  @unsaved_password = value
end

#persisted?Boolean

Whether the item has been persisted to the keychain

Returns:

  • (Boolean)


118
119
120
# File 'lib/keychain/item.rb', line 118

def persisted?
  !@ptr.null?
end

#save!(options = {}) ⇒ Keychain::Item

Attempts to update the keychain with any changes made to the item or saves a previously unpersisted item

Parameters:

  • options (optional, Hash) (defaults to: {})

    extra options when saving the item

Options Hash (options):

  • :keychain (Keychain::Keychain)

    when saving an unsaved item, they keychain to save it in

Returns:



99
100
101
102
103
104
105
106
107
108
109
# File 'lib/keychain/item.rb', line 99

def save!(options={})
  if persisted?
    cf_dict = update
  else
    cf_dict = create(options)
  end    
  @unsaved_password = nil
  update_self_from_dictionary(cf_dict)
  cf_dict.release
  self
end