Class: SecureDataBag::Item
- Inherits:
-
Chef::DataBagItem
- Object
- Chef::DataBagItem
- SecureDataBag::Item
- 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
Class Method Summary collapse
-
.from_hash(h, key = nil) ⇒ Object
Transitions.
- .from_item(h, key = nil) ⇒ Object
- .load_secret(path = nil) ⇒ Object
Instance Method Summary collapse
-
#decode_data! ⇒ Object
Encoder / Decoder.
- #decoded_data ⇒ Object
- #encode_data! ⇒ Object
-
#encode_fields(arg = nil) ⇒ Object
Fields we wish to encode - this differs from encryption and will get merged into the latter upon an encode.
-
#encoded? ⇒ Boolean
Determine whether the data is encoded or not - yeah, it’s pretty naive.
- #encoded_data ⇒ Object
-
#encryption(arg = nil) ⇒ Object
Wrapper for raw_data encryption settings - always ensure that encryption hash is present - always ensure encryption settings have defaults.
-
#initialize(key = nil) ⇒ Item
constructor
A new instance of Item.
- #key(arg = nil) ⇒ Object
- #load_key ⇒ Object
-
#raw_data=(data) ⇒ Object
Setter for @raw_data - ensure the data we receive is a Mash to support symbols - pass it to DataBagItem for additional validation - ensure the data has the encryption hash - decode the data.
-
#secret(arg = nil) ⇒ Object
Methods for encryption key.
- #to_hash(encoded = true) ⇒ Object
- #to_json(*a) ⇒ Object
Constructor Details
Class Method Details
.from_hash(h, key = nil) ⇒ Object
Transitions
162 163 164 165 166 |
# File 'lib/secure_data_bag/secure_data_bag_item.rb', line 162 def self.from_hash(h, key=nil) item = new(key) item.raw_data = h item end |
.from_item(h, key = nil) ⇒ Object
168 169 170 171 172 |
# File 'lib/secure_data_bag/secure_data_bag_item.rb', line 168 def self.from_item(h, key=nil) item = self.from_hash(h.to_hash, key) item.data_bag h.data_bag item end |
.load_secret(path = nil) ⇒ Object
41 42 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 69 |
# File 'lib/secure_data_bag/secure_data_bag_item.rb', line 41 def self.load_secret(path=nil) path ||= Chef::Config[:encrypted_data_bag_secret] unless path raise ArgumentError, "No secret specified and no secret found." end key = case path when /^\w+:\/\// # Remove key begin Kernel.open(path).read.strip rescue Errno::ECONNREFUSED raise ArgumentError, "Remove key not available from '#{path}'" rescue OpenURI::HTTPError raise ArgumentError, "Remove key not found at '#{path}'" end else unless File.exist?(path) raise Errno::ENOENT, "file not found '#{path}'" end IO.read(path).strip end if key.size < 1 raise ArgumentError, "invalid zero length path in '#{path}'" end key end |
Instance Method Details
#decode_data! ⇒ Object
Encoder / Decoder
126 127 128 129 130 131 132 133 134 |
# File 'lib/secure_data_bag/secure_data_bag_item.rb', line 126 def decode_data! # # Ensure that we save previously encoded fields into our list of fields # we wish to encode next time # encode_fields.concat(encryption[:encoded_fields]).uniq! @raw_data = decoded_data if encoded? @raw_data end |
#decoded_data ⇒ Object
136 137 138 139 140 |
# File 'lib/secure_data_bag/secure_data_bag_item.rb', line 136 def decoded_data data = Decryptor.new(raw_data, encryption, key).for_decrypted_item data[:encryption][:encoded_fields] = [] data end |
#encode_data! ⇒ Object
142 143 144 |
# File 'lib/secure_data_bag/secure_data_bag_item.rb', line 142 def encode_data! @raw_data = encoded_data end |
#encode_fields(arg = nil) ⇒ Object
Fields we wish to encode
-
this differs from encryption and will get merged into the latter upon an encode
117 118 119 120 |
# File 'lib/secure_data_bag/secure_data_bag_item.rb', line 117 def encode_fields(arg=nil) arg = Array(arg).uniq if arg set_or_return(:encode_fields, arg, kind_of: Array).uniq end |
#encoded? ⇒ Boolean
Determine whether the data is encoded or not
-
yeah, it’s pretty naive
107 108 109 |
# File 'lib/secure_data_bag/secure_data_bag_item.rb', line 107 def encoded? not encryption[:encoded_fields].empty? end |
#encoded_data ⇒ Object
146 147 148 149 150 151 152 153 154 155 156 |
# File 'lib/secure_data_bag/secure_data_bag_item.rb', line 146 def encoded_data # # When encoding data we'll merge those fields already encoded during # the previous state, found in encryption[:encoded_fields] with those # which we wish to encode # encryption = self.encryption.dup encryption[:encoded_fields] = @encode_fields. concat(encryption[:encoded_fields]).uniq Encryptor.new(raw_data, encryption, key).for_encrypted_item end |
#encryption(arg = nil) ⇒ Object
Wrapper for raw_data encryption settings
-
always ensure that encryption hash is present
-
always ensure encryption settings have defaults
77 78 79 80 81 82 83 84 85 |
# File 'lib/secure_data_bag/secure_data_bag_item.rb', line 77 def encryption(arg=nil) @raw_data[:encryption] ||= {} @raw_data[:encryption] = arg unless arg.nil? encryption = @raw_data[:encryption] encryption[:iv] = nil if encryption[:iv].nil? encryption[:cipher] = "aes-256-cbc" if encryption[:cipher].nil? encryption[:encoded_fields] = [] if encryption[:encoded_fields].nil? encryption end |
#key(arg = nil) ⇒ Object
32 33 34 35 |
# File 'lib/secure_data_bag/secure_data_bag_item.rb', line 32 def key(arg=nil) @key = arg unless arg.nil? @key ||= load_key end |
#load_key ⇒ Object
37 38 39 |
# File 'lib/secure_data_bag/secure_data_bag_item.rb', line 37 def load_key @key = self.class.load_secret(secret) end |
#raw_data=(data) ⇒ Object
Setter for @raw_data
-
ensure the data we receive is a Mash to support symbols
-
pass it to DataBagItem for additional validation
-
ensure the data has the encryption hash
-
decode the data
95 96 97 98 99 100 |
# File 'lib/secure_data_bag/secure_data_bag_item.rb', line 95 def raw_data=(data) data = Mash.new(data) super data encryption decode_data! end |
#secret(arg = nil) ⇒ Object
Methods for encryption key
28 29 30 |
# File 'lib/secure_data_bag/secure_data_bag_item.rb', line 28 def secret(arg=nil) set_or_return(:secret, arg, kind_of: String) end |
#to_hash(encoded = true) ⇒ Object
174 175 176 177 178 179 |
# File 'lib/secure_data_bag/secure_data_bag_item.rb', line 174 def to_hash(encoded = true) result = encoded ? encoded_data : decoded_data result["chef_type"] = "data_bag_item" result["data_bag"] = self.data_bag result end |
#to_json(*a) ⇒ Object
181 182 183 184 185 186 187 188 189 190 |
# File 'lib/secure_data_bag/secure_data_bag_item.rb', line 181 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: encoded_data } result.to_json(*a) end |