module WebhookSystem::Encoder

Class in charge of encoding and decoding encrypted payload

Public Class Methods

decode(secret_string, payload_string, headers = {}) click to toggle source

Given a secret string, and an encrypted payload, unwrap it, bas64 decode it decrypt it, and JSON decode it

@param [String] secret_string some secret string @param [String] payload_string String as returned from encode @return [Object] return the JSON decode of the encrypted payload

# File lib/webhook_system/encoder.rb, line 26
def self.decode(secret_string, payload_string, headers = {})
  signature = headers['X-Hub-Signature']
  format = format_for_content_type(headers.fetch('Content-Type'))

  payload_signature = hub_signature(payload_string, secret_string)
  raise DecodingError, 'signature mismatch' if signature && signature != payload_signature

  Payload.decode(payload_string, secret: secret_string, format: format)
end
encode(secret_string, payload, format:) click to toggle source

Given a secret string, encode the passed payload to json encrypt it, base64 encode that, and wrap it in its own json wrapper

@param [String] secret_string some secret string @param [Object#to_json] payload Any object that responds to to_json @return [String] The encoded string payload (its a JSON string)

# File lib/webhook_system/encoder.rb, line 13
def self.encode(secret_string, payload, format:)
  response_hash = Payload.encode(payload, secret: secret_string, format: format)
  payload_string = JSON.generate(response_hash)
  signature = hub_signature(payload_string, secret_string)
  [payload_string, { 'X-Hub-Signature' => signature, 'Content-Type' => content_type_for_format(format) }]
end

Private Class Methods

content_type_for_format(format) click to toggle source
# File lib/webhook_system/encoder.rb, line 50
def content_type_for_format(format)
  content_type_format_map.fetch(format)
end
content_type_format_map() click to toggle source
# File lib/webhook_system/encoder.rb, line 39
def content_type_format_map
  {
    'base64+aes256' => 'application/json; base64+aes256',
    'json' => 'application/json',
  }
end
format_for_content_type(content_type) click to toggle source
# File lib/webhook_system/encoder.rb, line 46
def format_for_content_type(content_type)
  content_type_format_map.invert.fetch(content_type)
end
hub_signature(payload_string, secret) click to toggle source
# File lib/webhook_system/encoder.rb, line 54
def hub_signature(payload_string, secret)
  "sha1=#{OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha1'), secret, payload_string)}"
end