Class: SK::SDK::SignedRequest

Inherits:
Object
  • Object
show all
Defined in:
lib/sk_sdk/signed_request.rb

Overview

Decode and validate signed requests which Salesking sends to canvas pages and PubSub subscribers

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(signed_request, app_secret) ⇒ SignedRequest

Returns a new instance of SignedRequest.



12
13
14
15
16
# File 'lib/sk_sdk/signed_request.rb', line 12

def initialize(signed_request, app_secret)
  @signed_request = signed_request
  @app_secret = app_secret
  decode_payload
end

Instance Attribute Details

#app_secretObject (readonly)

Returns the value of attribute app_secret.



10
11
12
# File 'lib/sk_sdk/signed_request.rb', line 10

def app_secret
  @app_secret
end

#dataObject (readonly)

Returns the value of attribute data.



10
11
12
# File 'lib/sk_sdk/signed_request.rb', line 10

def data
  @data
end

#payloadObject (readonly)

Returns the value of attribute payload.



10
11
12
# File 'lib/sk_sdk/signed_request.rb', line 10

def payload
  @payload
end

#signObject (readonly)

Returns the value of attribute sign.



10
11
12
# File 'lib/sk_sdk/signed_request.rb', line 10

def sign
  @sign
end

#signed_requestObject (readonly)

Returns the value of attribute signed_request.



10
11
12
# File 'lib/sk_sdk/signed_request.rb', line 10

def signed_request
  @signed_request
end

Class Method Details

.base64_url_encode(str) ⇒ String

Base64 url encode a string:

NO padding '=' is stripped

+ is replaced by - / is replaced by _

Parameters:

  • str (String)

    the string to encode

Returns:

  • (String)

    base64url-encoded



63
64
65
# File 'lib/sk_sdk/signed_request.rb', line 63

def self.base64_url_encode(str)
  [str].pack('m').tr('+/','-_').gsub("\n",'').gsub(/=+$/, '' )
end

.signed_param(str, secret) ⇒ String

Base64 url encode a string and sign it using the given secret. The hmac signature and the encoded string are joined by . and returned

Parameters:

  • str (String)

    the string to encode

  • secret (String)

    used to create the signature

Returns:

  • (String)

    hmac-sign.encoded-string



47
48
49
50
51
52
53
54
# File 'lib/sk_sdk/signed_request.rb', line 47

def self.signed_param(str, secret)
  # base65 url encode the json, remove trailing-padding =
  enc_str = base64_url_encode(str)
  # create hmac signature
  hmac_sig = OpenSSL::HMAC.hexdigest('sha256',secret, enc_str)
  # glue together and return
  [hmac_sig, enc_str].join('.')
end

Instance Method Details

#base64_url_decode(str) ⇒ String

Decode a base64URL encoded string: replace - with + and _ with / Also add padding so ruby’s Base64 can decode it

Returns:

  • (String)

    the plain string decoded



28
29
30
31
32
# File 'lib/sk_sdk/signed_request.rb', line 28

def base64_url_decode(str)
  encoded_str = str.tr('-_', '+/')
  encoded_str += '=' while !(encoded_str.size % 4).zero?
  Base64.decode64(encoded_str)
end

#decode_payloadObject

Populate @data and @sign(ature) by splitting and decoding the incoming signed_request



20
21
22
23
# File 'lib/sk_sdk/signed_request.rb', line 20

def decode_payload
  @sign, @payload = @signed_request.split('.')
  @data = ActiveSupport::JSON.decode base64_url_decode(@payload)
end

#valid?Boolean

A request is valid if the new hmac created from the incoming string matches the new one, created with the apps secret

Returns:

  • (Boolean)


36
37
38
39
# File 'lib/sk_sdk/signed_request.rb', line 36

def valid?
  return false if @data['algorithm'].to_s.upcase != 'HMAC-SHA256'
  @sign == OpenSSL::HMAC.hexdigest('sha256', @app_secret, @payload)
end