Module: Jive::SignedRequest
- Defined in:
- lib/jive/signed_request.rb,
lib/jive/signed_request/version.rb
Overview
:nodoc:
Constant Summary collapse
- VERSION =
"0.1.1"
Class Method Summary collapse
-
.authenticate(authorization_header, client_secret) ⇒ Object
Authenticate an authorization header.
-
.sign(string, secret, algorithm = nil) ⇒ Object
Sign a string with a secret.
-
.validate_registration(validationBlock, *args) ⇒ Object
Validates an app registration.
Class Method Details
.authenticate(authorization_header, client_secret) ⇒ Object
Authenticate an authorization header
Authenticates that an authorization header sent by Jive is valid given an apps secret
-
Args :
-
authorization_header-> the entire Authorization header sent by Jive -
client_secret-> the client secret to authenticate the header with
-
-
Returns :
-
the signature
-
-
Raises :
-
ArgumentError-> if the authorization_header does not contain JiveEXTN -
ArgumentError-> if the heauthorization_header does not contain all the required parameters -
ArgumentError-> if the heauthorization_header has expired (more than 5 minutes old)
-
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
# File 'lib/jive/signed_request.rb', line 55 def authenticate(, client_secret) # Validate JiveEXTN part of header if !.match(/^JiveEXTN/) raise ArgumentError, "Jive authorization header is not properly formatted, must start with JiveEXTN" end paramMap = ::CGI.parse .gsub(/^JiveEXTN\s/,'') # Validate all parameters are passed from header if !paramMap.has_key?("algorithm") || !paramMap.has_key?("client_id") || !paramMap.has_key?("jive_url") || !paramMap.has_key?("tenant_id") || !paramMap.has_key?("timestamp") || !paramMap.has_key?("signature") raise ArgumentError, "Jive authorization header is partial" end # Validate timestamp is still valid = Time.at(paramMap["timestamp"].first.to_i/1000) secondsPassed = Time.now - if secondsPassed < 0 || secondsPassed > (5*60) raise ArgumentError, "Jive authorization is rejected since it's #{ secondsPassed } seconds old (max. allowed is 5 minutes)" end self.sign(.gsub(/^JiveEXTN\s/,'').gsub(/\&signature[^$]+/,''), client_secret) === paramMap["signature"].first end |
.sign(string, secret, algorithm = nil) ⇒ Object
Sign a string with a secret
Sign a string with a secret and get the signature
-
Args :
-
string-> the string to sign -
secret-> the secret to use
-
-
Returns :
-
the signature
-
-
Raises :
-
ArgumentError-> if no algorithm passed and algorithm could not be derived from the string
-
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
# File 'lib/jive/signed_request.rb', line 23 def sign(string, secret, algorithm = nil) plain = ::Base64.decode64(secret.gsub(/\.s$/,'')) # if no override algorithm passed try and extract from string if algorithm.nil? paramMap = ::CGI.parse string if !paramMap.has_key?("algorithm") raise ArgumentError, "missing algorithm" end algorithm = paramMap["algorithm"].first.gsub(/^hmac/i,'') end hmac = ::OpenSSL::HMAC.digest(algorithm, plain, string) Base64::encode64(hmac).gsub(/\n$/,'') end |
.validate_registration(validationBlock, *args) ⇒ Object
Validates an app registration
Validates an app registration came from where it claims via jiveSignatureURL
-
Args :
-
validationBlock-> the request body of the registration -
args-> additional arguments
-
-
Returns :
-
boolean
-
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 |
# File 'lib/jive/signed_request.rb', line 94 def validate_registration(validationBlock, *args) = ((args.last.is_a?(Hash)) ? args.pop : {}) require "open-uri" require "net/http" require "openssl" jive_signature_url = validationBlock[:jiveSignatureURL] jive_signature = validationBlock[:jiveSignature] validationBlock.delete(:jiveSignature) if !validationBlock[:clientSecret].nil? validationBlock[:clientSecret] = Digest::SHA256.hexdigest(validationBlock[:clientSecret]) end uri = URI.parse(jive_signature_url) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true http.verify_mode = OpenSSL::SSL::VERIFY_NONE if http.use_ssl? && ![:verify_ssl] buffer = '' validationBlock.sort.to_h.each_pair { |k,v| buffer = "#{buffer}#{k}:#{v}\n" } request = Net::HTTP::Post.new(uri.request_uri) request.body = buffer request["X-Jive-MAC"] = jive_signature request["Content-Type"] = "application/json" response = http.request(request) (response.code.to_i === 204) end |