Class: SecureDataBag::SecureDataBagItem

Inherits:
Chef::DataBagItem
  • Object
show all
Defined in:
lib/secure_data_bag/secure_data_bag_item.rb,
lib/secure_data_bag/decryptor.rb,
lib/secure_data_bag/encryptor.rb

Overview

SecureDataBagItem extends the standard DataBagItem by providing it with encryption / decryption capabilities.

Although it does provide methods which may be used to specifically perform crypto functions, it should be used the same way.

Defined Under Namespace

Classes: Decryptor, Encryptor

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeSecureDataBagItem

Returns a new instance of SecureDataBagItem.



15
16
17
18
19
20
21
22
23
24
25
# File 'lib/secure_data_bag/secure_data_bag_item.rb', line 15

def initialize
  super

  @secret = nil
  @key = nil
  @cipher = nil
  @iv = nil
  @algorithm = nil
  @encoded_fields = []
  @default_encoded_fields = ["password"]
end

Instance Attribute Details

#default_encoded_fieldsObject (readonly)

Define attributes for encryption related tasks



31
32
33
# File 'lib/secure_data_bag/secure_data_bag_item.rb', line 31

def default_encoded_fields
  @default_encoded_fields
end

Class Method Details

.from_hash(h) ⇒ Object

Transitions



131
132
133
134
135
136
# File 'lib/secure_data_bag/secure_data_bag_item.rb', line 131

def self.from_hash(h)
  m = Mash.new(h)
  item = new
  item.raw_data = m
  item
end

.from_item(h) ⇒ Object



138
139
140
141
142
# File 'lib/secure_data_bag/secure_data_bag_item.rb', line 138

def self.from_item(h)
  item = self.from_hash(h.to_hash)
  item.data_bag = h.data_bag
  item
end

Instance Method Details

#cipher(arg = nil) ⇒ Object



70
71
72
73
# File 'lib/secure_data_bag/secure_data_bag_item.rb', line 70

def cipher(arg=nil)
  arg ||= "aes-256-cbc" if @cipher.nil?
  set_or_return(:cipher, arg, kind_of: String)
end

#decode_dataObject

Encoder / Decoder



110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/secure_data_bag/secure_data_bag_item.rb', line 110

def decode_data
  if @raw_data.key? :encryption
    encryption = @raw_data.delete(:encryption) || {}

    cipher  encryption[:cipher]
    iv      encryption[:iv]
    encoded_fields  encryption[:encoded_fields]

    @raw_data = decode_data
  end
  @raw_data
end

#encode_dataObject



123
124
125
# File 'lib/secure_data_bag/secure_data_bag_item.rb', line 123

def encode_data
  Encryptor.new(raw_data, encryption, key).for_encrypted_item
end

#encoded_fields(arg = nil) ⇒ Object

These are either the fields which are currently encoded or those that we wish to encode



84
85
86
87
# File 'lib/secure_data_bag/secure_data_bag_item.rb', line 84

def encoded_fields(arg=nil)
  arg = arg.uniq if arg
  set_or_return(:encoded_fields, arg, kind_of: Array)
end

#encryptionObject

The encryption definition



93
94
95
96
97
98
99
# File 'lib/secure_data_bag/secure_data_bag_item.rb', line 93

def encryption
  {
    iv: iv,
    cipher: cipher,
    encoded_fields: encoded_fields + default_encoded_fields
  }
end

#iv(arg = nil) ⇒ Object



75
76
77
# File 'lib/secure_data_bag/secure_data_bag_item.rb', line 75

def iv(arg=nil)
  set_or_return(:iv, arg, kind_of: String)
end

#key(arg = nil) ⇒ Object



38
39
40
41
# File 'lib/secure_data_bag/secure_data_bag_item.rb', line 38

def key(arg=nil)
  @key = arg unless arg.nil?
  @key ||= load_key
end

#load_keyObject



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/secure_data_bag/secure_data_bag_item.rb', line 43

def load_key
  unless secret
    raise ArgumentError, "No secret specified and no secret found."
  end

  key = case secret
  when /^\w+:\/\// # Remove key
    begin
      Kernel.open(path).read.strip
    rescue Errno::ECONNREFUSED
      raise ArgumentError, "Remove key not available from '#{secret}'"
    rescue OpenURI::HTTPError
      raise ArgumentError, "Remove key not found at '#{secret}'"
    end
  else
    unless File.exist?(secret)
      raise Errno::ENOENT, "file not found '#{secret}'"
    end
    IO.read(secret).strip
  end

  if key.size < 1
    raise ArgumentError, "invalid zero length secret in '#{secret}'"
  end
  key
end

#raw_data=(enc_data) ⇒ Object



101
102
103
104
# File 'lib/secure_data_bag/secure_data_bag_item.rb', line 101

def raw_data=(enc_data)
  super enc_data
  decode_data
end

#secret(arg = nil) ⇒ Object



33
34
35
36
# File 'lib/secure_data_bag/secure_data_bag_item.rb', line 33

def secret(arg=nil)
  arg ||= Chef::Config[:encrypted_data_bag_secret] if @secret.nil?
  set_or_return(:secret, arg, kind_of: String)
end

#to_hashObject



144
145
146
147
148
149
# File 'lib/secure_data_bag/secure_data_bag_item.rb', line 144

def to_hash
  result = encode_data
  result["chef_type"] = "data_bag_item"
  result["data_bag"] = self.data_bag
  result
end

#to_json(*a) ⇒ Object



151
152
153
154
155
156
157
158
159
160
# File 'lib/secure_data_bag/secure_data_bag_item.rb', line 151

def to_json(*a)
  result = {
    name: self.object_name,
    json_class: "Chef::DataBagItem",
    chef_type: "data_bag_item",
    data_bag: self.data_bag,
    raw_data: encode_data
  }
  result.to_json(*a)
end