Class: WePay::Signer

Inherits:
Object
  • Object
show all
Defined in:
lib/wepay-signer.rb

Overview

The Signer class is designed for those who are signing data on behalf of a public-private keypair.

In principle, the "client party" has public key (i.e., client_id) has a matching private key (i.e., client_secret) that can be verified by both the signer, as well as the client, but by nobody else as we don't want to make forgeries possible.

The "signing party" has a simple an identifier which acts as an additional piece of entropy in the algorithm, and can help differentiate between multiple signing parties if the client party does something like try to use the same public-private keypair independently of a signing party (as is common with GPG signing).

For example, in the original AWS implementation, the "self key" for AWS was "AWS4".

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(client_id, client_secret, options = {}) ⇒ Signer

Constructs a new instance of this class.

Parameters:

  • client_id (String)

    A string which is the public portion of the keypair identifying the client party. The pairing of the public and private portions of the keypair should only be known to the client party and the signing party.

  • client_secret (String)

    A string which is the private portion of the keypair identifying the client party. The pairing of the public and private portions of the keypair should only be known to the client party and the signing party.

  • options (Hash) (defaults to: {})

    a customizable set of options

Options Hash (options):

  • self_key (String) — default: WePay

    A string which identifies the signing party and adds additional entropy.

  • hash_algo (String) — default: sha512

    The hash algorithm to use for signing.



49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/wepay-signer.rb', line 49

def initialize(client_id, client_secret, options = {})
  @client_id = client_id.to_s
  @client_secret = client_secret.to_s

  options = {
    :self_key  => 'WePay',
    :hash_algo => 'sha512',
  }.merge(options)

  @self_key = options[:self_key].to_s
  @hash_algo = options[:hash_algo].to_s
end

Instance Attribute Details

#client_idObject (readonly)

Returns the value of attribute client_id



33
34
35
# File 'lib/wepay-signer.rb', line 33

def client_id
  @client_id
end

#client_secretObject (readonly)

Returns the value of attribute client_secret



34
35
36
# File 'lib/wepay-signer.rb', line 34

def client_secret
  @client_secret
end

#hash_algoObject (readonly)

Returns the value of attribute hash_algo



35
36
37
# File 'lib/wepay-signer.rb', line 35

def hash_algo
  @hash_algo
end

#self_keyObject (readonly)

Returns the value of attribute self_key



32
33
34
# File 'lib/wepay-signer.rb', line 32

def self_key
  @self_key
end

Instance Method Details

#generate_query_string_params(payload) ⇒ String

Signs and generates the query string URL parameters to use when making a request.

If the client_secret key is provided, then it will be automatically excluded from the result.

Parameters:

  • payload (Hash)

    The data to generate a signature for.

Options Hash (payload):

  • token (required, String)

    The one-time-use token.

  • page (required, String)

    The WePay URL to access.

  • redirect_uri (required, String)

    The partner URL to return to once the action is completed.

Returns:

  • (String)

    The query string parameters to append to the end of a URL.



95
96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/wepay-signer.rb', line 95

def generate_query_string_params(payload)
  payload.delete(:client_secret) if payload.has_key? :client_secret

  signed_token = sign(payload)
  payload[:client_id] = @client_id
  payload[:stoken] = signed_token
  qsa = []

  payload.keys.sort.each do | key |
    qsa.push sprintf("%s=%s", key, payload[key])
  end

  qsa.join("&")
end

#sign(payload) ⇒ String

Sign the payload to produce a signature for its contents.

Parameters:

  • payload (Hash)

    The data to generate a signature for.

Options Hash (payload):

  • token (required, String)

    The one-time-use token.

  • page (required, String)

    The WePay URL to access.

  • redirect_uri (required, String)

    The partner URL to return to once the action is completed.

Returns:

  • (String)

    The signature for the payload contents.



71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/wepay-signer.rb', line 71

def sign(payload)
  payload = payload.merge({
    :client_id     => @client_id,
    :client_secret => @client_secret,
  })

  scope = create_scope
  context = create_context(payload)
  s2s = create_string_to_sign(scope, context)
  signing_key = get_signing_salt
  OpenSSL::HMAC.hexdigest(@hash_algo, signing_key, s2s)
end