Class: OAuthenticator::SignableRequest
- Inherits:
-
Object
- Object
- OAuthenticator::SignableRequest
- Defined in:
- lib/oauthenticator/signable_request.rb
Overview
a request which may be signed with OAuth, generally in order to apply the signature to an outgoing request in the Authorization header.
primarily this is to be used like:
oauthenticator_signable_request = OAuthenticator::SignableRequest.new(
:request_method => my_request_method,
:uri => my_request_uri,
:media_type => my_request_media_type,
:body => my_request_body,
:signature_method => my_oauth_signature_method,
:consumer_key => my_oauth_consumer_key,
:consumer_secret => my_oauth_consumer_secret,
:token => my_oauth_token,
:token_secret => my_oauth_token_secret,
:realm =>
)
my_http_request.headers['Authorization'] = oauthenticator_signable_request.
Constant Summary collapse
- PROTOCOL_PARAM_KEYS =
keys of OAuth protocol parameters which form the Authorization header (with an oauth_ prefix). signature is considered separately.
%w(consumer_key token signature_method timestamp nonce version).map(&:freeze).freeze
Instance Method Summary collapse
-
#authorization ⇒ String
returns the Authorization header generated for this request.
-
#body_hash ⇒ String?
the oauth_body_hash calculated for this request, if applicable, per the OAuth Request Body Hash specification.
-
#form_encoded? ⇒ Boolean
is the media type application/x-www-form-urlencoded.
-
#initialize(attributes) ⇒ SignableRequest
constructor
initialize a signable request with the following attributes (keys may be string or symbol):.
-
#protocol_params ⇒ Hash<String, String>
protocol params for this request as described in section 3.4.1.3 .
-
#signature ⇒ String
the oauth_signature calculated for this request.
-
#signed_protocol_params ⇒ Hash<String, String>
protocol params for this request as described in section 3.4.1.3, including our calculated oauth_signature.
Constructor Details
#initialize(attributes) ⇒ SignableRequest
initialize a signable request with the following attributes (keys may be string or symbol):
- request_method (required) - get, post, etc. may be string or symbol.
- uri (required) - request URI. to_s is called so URI or Addressable::URI or whatever may be passed.
- media_type (required) - the request media type (may be nil if there is no body). note that this may be different than the Content-Type header; other components of that such as encoding must not be included.
- body (required) - the request body. may be a String or an IO, or nil if no body is present.
- hash_body? - whether to add the oauth_body_hash parameter, per the OAuth Request Body Hash specification. defaults to true. not used if the 'authorization' parameter is used.
- signature_method (required*) - oauth signature method (String)
- consumer_key (required*) - oauth consumer key (String)
- consumer_secret (required*) - oauth consumer secret (String)
- token (optional*) - oauth token; may be omitted if only using a consumer key (two-legged)
- token_secret (optional) - must be present if token is present. must be omitted if token is omitted.
- timestamp (optional*) - if omitted, defaults to the current time. if nil is passed, no oauth_timestamp will be present in the generated authorization.
- nonce (optional*) - if omitted, defaults to a random string. if nil is passed, no oauth_nonce will be present in the generated authorization.
- version (optional*) - must be nil or '1.0'. defaults to '1.0' if omitted. if nil is passed, no oauth_version will be present in the generated authorization.
- realm (optional) - authorization realm. if nil is passed, no realm will be present in the generated authorization.
- authorization - a hash of a received Authorization header, the result of a call to OAuthenticator.parse_authorization. it is useful for calculating the signature of a received request, but for fully authenticating a received request it is generally preferable to use OAuthenticator::SignedRequest. specifying this precludes the requirement to specify any of PROTOCOL_PARAM_KEYS.
(*) attributes which are in PROTOCOL_PARAM_KEYS are unused (and not required) when the 'authorization' attribute is given for signature verification. normally, though, they are used and are required or optional as noted.
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
# File 'lib/oauthenticator/signable_request.rb', line 63 def initialize(attributes) raise TypeError, "attributes must be a hash" unless attributes.is_a?(Hash) # stringify symbol keys @attributes = attributes.map { |k,v| {k.is_a?(Symbol) ? k.to_s : k => v} }.inject({}, &:update) # validation - presence required = %w(request_method uri media_type body) required += %w(signature_method consumer_key) unless @attributes['authorization'] missing = required - @attributes.keys raise ArgumentError, "missing required attributes: #{missing.inspect}" if missing.any? other_recognized = PROTOCOL_PARAM_KEYS + %w(authorization consumer_secret token_secret realm hash_body?) extra = @attributes.keys - (required + other_recognized) raise ArgumentError, "received unrecognized attributes: #{extra.inspect}" if extra.any? if @attributes['authorization'] # this means we are signing an existing request to validate the received signature. don't use defaults. unless @attributes['authorization'].is_a?(Hash) raise TypeError, "authorization must be a Hash" end # if authorization is specified, protocol params should not be specified in the regular attributes given_protocol_params = @attributes.reject { |k,v| !(PROTOCOL_PARAM_KEYS.include?(k) && v) } if given_protocol_params.any? raise ArgumentError, "an existing authorization was given, but protocol parameters were also " + "given. protocol parameters should not be specified when verifying an existing authorization. " + "given protocol parameters were: #{given_protocol_params.inspect}" end else # defaults defaults = { 'version' => '1.0', } if @attributes['signature_method'] != 'PLAINTEXT' defaults.update({ 'nonce' => OpenSSL::Random.random_bytes(16).unpack('H*')[0], 'timestamp' => Time.now.to_i.to_s, }) end @attributes['authorization'] = PROTOCOL_PARAM_KEYS.map do |key| {"oauth_#{key}" => @attributes.key?(key) ? @attributes[key] : defaults[key]} end.inject({}, &:update).reject {|k,v| v.nil? } @attributes['authorization']['realm'] = @attributes['realm'] unless @attributes['realm'].nil? hash_body end end |
Instance Method Details
#authorization ⇒ String
returns the Authorization header generated for this request.
113 114 115 |
# File 'lib/oauthenticator/signable_request.rb', line 113 def "OAuth #{normalized_protocol_params_string}" end |
#body_hash ⇒ String?
the oauth_body_hash calculated for this request, if applicable, per the OAuth Request Body Hash specification.
130 131 132 |
# File 'lib/oauthenticator/signable_request.rb', line 130 def body_hash BODY_HASH_METHODS[signature_method] ? BODY_HASH_METHODS[signature_method].bind(self).call : nil end |
#form_encoded? ⇒ Boolean
is the media type application/x-www-form-urlencoded
158 159 160 161 162 163 |
# File 'lib/oauthenticator/signable_request.rb', line 158 def form_encoded? media_type = @attributes['media_type'] # media tye is case insensitive per http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.7 media_type = media_type.downcase if media_type.is_a?(String) media_type == "application/x-www-form-urlencoded" end |
#protocol_params ⇒ Hash<String, String>
protocol params for this request as described in section 3.4.1.3
signature is not calculated for this - use #signed_protocol_params to get protocol params including a signature.
note that if this is a previously-signed request, the oauth_signature attribute returned is the received value, NOT the value calculated by us.
143 144 145 |
# File 'lib/oauthenticator/signable_request.rb', line 143 def protocol_params @attributes['authorization'].dup end |
#signature ⇒ String
the oauth_signature calculated for this request.
120 121 122 123 124 |
# File 'lib/oauthenticator/signable_request.rb', line 120 def signature rbmethod = SIGNATURE_METHODS[signature_method] || raise(ArgumentError, "invalid signature method: #{signature_method}") rbmethod.bind(self).call end |
#signed_protocol_params ⇒ Hash<String, String>
protocol params for this request as described in section 3.4.1.3, including our calculated oauth_signature.
151 152 153 |
# File 'lib/oauthenticator/signable_request.rb', line 151 def signed_protocol_params protocol_params.merge('oauth_signature' => signature) end |