class McAPI::Encryption::FieldLevelEncryption
Performs field level encryption on HTTP payloads.
Public Class Methods
new(config)
click to toggle source
Create a new instance with the provided configuration
@param [Object] config Configuration object
# File lib/mcapi/encryption/field_level_encryption.rb, line 18 def initialize(config) @config = config @crypto = McAPI::Encryption::Crypto.new(config) @is_with_header = config['ivHeaderName'] && config['encryptedKeyHeaderName'] @encryption_response_properties = [@config['ivFieldName'], @config['encryptedKeyFieldName'], @config['publicKeyFingerprintFieldName'], @config['oaepHashingAlgorithmFieldName']] end
Public Instance Methods
decrypt(response)
click to toggle source
Decrypt part of the HTTP response using the given config
@param [Object] response object as obtained from the http client
@return [Object] response object with decrypted fields
# File lib/mcapi/encryption/field_level_encryption.rb, line 62 def decrypt(response) response = JSON.parse(response) config = config?(response['request']['url']) if config if !@is_with_header config['toDecrypt'].each do |v| decrypt_with_body(v, response['body']) end else config['toDecrypt'].each do |v| elem = elem_from_path(v['obj'], response['body']) decrypt_with_header(v, elem, response) if elem[:node][v['element']] end end end JSON.generate(response) end
encrypt(endpoint, header, body)
click to toggle source
Encrypt parts of a HTTP request using the given config
@param [String] endpoint HTTP URL for the current call @param [Object] header HTTP header @param [String,Hash] body HTTP body
@return [Hash] Hash
with two keys:
-
:header header with encrypted value (if configured with header)
-
:body encrypted body
# File lib/mcapi/encryption/field_level_encryption.rb, line 37 def encrypt(endpoint, header, body) body = JSON.parse(body) if body.is_a?(String) config = config?(endpoint) if config if !@is_with_header config['toEncrypt'].each do |v| encrypt_with_body(v, body) end else enc_params = @crypto.new_encryption_params config['toEncrypt'].each do |v| body = encrypt_with_header(v, enc_params, header, body) end end end { header: header, body: body.json } end
Private Instance Methods
config?(endpoint)
click to toggle source
# File lib/mcapi/encryption/field_level_encryption.rb, line 136 def config?(endpoint) return unless endpoint endpoint = endpoint.split('?').shift conf = @config['paths'].select { |e| endpoint.match(e['path']) } conf.empty? ? nil : conf[0] end
decrypt_with_body(path, body)
click to toggle source
# File lib/mcapi/encryption/field_level_encryption.rb, line 99 def decrypt_with_body(path, body) elem = elem_from_path(path['element'], body) return unless elem && elem[:node] decrypted = @crypto.decrypt_data(elem[:node][@config['encryptedValueFieldName']], elem[:node][@config['ivFieldName']], elem[:node][@config['encryptedKeyFieldName']]) begin decrypted = JSON.parse(decrypted) rescue JSON::ParserError # ignored end McAPI::Utils.mutate_obj_prop(path['obj'], decrypted, body, path['element'], @encryption_response_properties) end
decrypt_with_header(path, elem, response)
click to toggle source
# File lib/mcapi/encryption/field_level_encryption.rb, line 114 def decrypt_with_header(path, elem, response) encrypted_data = elem[:node][path['element']][@config['encryptedValueFieldName']] response['body'].clear response['body'] = JSON.parse(@crypto.decrypt_data(encrypted_data, response['headers'][@config['ivHeaderName']][0], response['headers'][@config['encryptedKeyHeaderName']][0])) end
elem_from_path(path, obj)
click to toggle source
# File lib/mcapi/encryption/field_level_encryption.rb, line 122 def elem_from_path(path, obj) parent = nil paths = path.split('.') if path && !paths.empty? paths.each do |e| parent = obj obj = obj[e] end end { node: obj, parent: parent } rescue StandardError nil end
encrypt_with_body(path, body)
click to toggle source
# File lib/mcapi/encryption/field_level_encryption.rb, line 82 def encrypt_with_body(path, body) elem = elem_from_path(path['element'], body) return unless elem && elem[:node] encrypted_data = @crypto.encrypt_data(data: JSON.generate(elem[:node])) McAPI::Utils.mutate_obj_prop(path['obj'], encrypted_data, body) McAPI::Utils.delete_node(path['element'], body) if path['element'] != "#{path['obj']}.#{@config['encryptedValueFieldName']}" end
encrypt_with_header(path, enc_params, header, body)
click to toggle source
# File lib/mcapi/encryption/field_level_encryption.rb, line 90 def encrypt_with_header(path, enc_params, header, body) elem = elem_from_path(path['element'], body) return unless elem && elem[:node] encrypted_data = @crypto.encrypt_data(data: JSON.generate(elem[:node]), encryption_params: enc_params) body = { path['obj'] => { @config['encryptedValueFieldName'] => encrypted_data[@config['encryptedValueFieldName']] } } set_header(header, enc_params) body end
set_header(header, params)
click to toggle source
# File lib/mcapi/encryption/field_level_encryption.rb, line 144 def set_header(header, params) header[@config['encryptedKeyHeaderName']] = params[:encoded][:encryptedKey] header[@config['ivHeaderName']] = params[:encoded][:iv] header[@config['oaepHashingAlgorithmHeaderName']] = params[:oaepHashingAlgorithm].sub('-', '') header[@config['publicKeyFingerprintHeaderName']] = params[:publicKeyFingerprint] end