Class: Signet::OAuth1::Server
- Inherits:
-
Object
- Object
- Signet::OAuth1::Server
- Defined in:
- lib/signet/oauth_1/server.rb
Instance Attribute Summary collapse
-
#client_credential ⇒ Proc
Lookup the value from this Proc.
-
#nonce_timestamp ⇒ Proc
Lookup the value from this Proc.
-
#temporary_credential ⇒ Proc
Lookup the value from this Proc.
-
#token_credential ⇒ Proc
Lookup the value from this Proc.
-
#verifier ⇒ Proc
Lookup the value from this Proc.
Instance Method Summary collapse
-
#authenticate_resource_request(options) ⇒ Hash
Authenticates a request for a protected resource.
-
#authenticate_temporary_credential_request(options) ⇒ String
Authenticates a temporary credential request.
-
#authenticate_token_credential_request(options) ⇒ Hash
Authenticates a token credential request.
-
#call_credential_lookup(credential, key) ⇒ Signet::OAuth1::Credential
Call a credential lookup, and cast the result to a proper Credential.
-
#find_client_credential(key) ⇒ Signet::OAuth1::Credential
Find the appropriate client credential by calling the #client_credential Proc.
-
#find_temporary_credential(key) ⇒ Signet::OAuth1::Credential
Find the appropriate client credential by calling the #temporary_credential Proc.
-
#find_token_credential(key) ⇒ Signet::OAuth1::Credential
Find the appropriate client credential by calling the #token_credential Proc.
-
#find_verifier(verifier) ⇒ Boolean
Determine if the verifier is valid by calling the Proc in #verifier.
-
#initialize(options) ⇒ Server
constructor
Creates an OAuth 1.0 server.
-
#request_realm(options) ⇒ String
The Authorization realm(see RFC 2617) of the request.
-
#validate_nonce_timestamp(nonce, timestamp) ⇒ Boolean
Determine if the supplied nonce/timestamp pair is valid by calling the #nonce_timestamp Proc.
-
#verify_auth_header_components(headers) ⇒ Hash
Validate and normalize the HTTP Authorization header.
-
#verify_request_components(options) ⇒ Hash
Validate and normalize the components from an HTTP request.
Constructor Details
#initialize(options) ⇒ Server
Creates an OAuth 1.0 server.
54 55 56 57 58 59 |
# File 'lib/signet/oauth_1/server.rb', line 54 def initialize(={}) [:nonce_timestamp, :client_credential, :token_credential, :temporary_credential, :verifier].each do |attr| instance_variable_set("@#{attr}", [attr]) end end |
Instance Attribute Details
#client_credential ⇒ Proc
Returns lookup the value from this Proc.
29 30 31 |
# File 'lib/signet/oauth_1/server.rb', line 29 def client_credential @client_credential end |
#nonce_timestamp ⇒ Proc
Returns lookup the value from this Proc.
29 30 31 |
# File 'lib/signet/oauth_1/server.rb', line 29 def @nonce_timestamp end |
#temporary_credential ⇒ Proc
Returns lookup the value from this Proc.
29 30 31 |
# File 'lib/signet/oauth_1/server.rb', line 29 def temporary_credential @temporary_credential end |
#token_credential ⇒ Proc
Returns lookup the value from this Proc.
29 30 31 |
# File 'lib/signet/oauth_1/server.rb', line 29 def token_credential @token_credential end |
#verifier ⇒ Proc
Returns lookup the value from this Proc.
29 30 31 |
# File 'lib/signet/oauth_1/server.rb', line 29 def verifier @verifier end |
Instance Method Details
#authenticate_resource_request(options) ⇒ Hash
Authenticates a request for a protected resource.
389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 |
# File 'lib/signet/oauth_1/server.rb', line 389 def authenticate_resource_request(={}) verifications = { :client_credential => lambda do |x| ::Signet::OAuth1::Credential.new('Client credential key', 'Client credential secret') end } unless([:two_legged] == true) verifications.update( :token_credential => lambda do |x| ::Signet::OAuth1::Credential.new('Token credential key', 'Token credential secret') end ) end # Make sure all required state is set verifications.each do |(key, value)| unless self.send(key) raise ArgumentError, "#{key} was not set." end end if([:request]) request_components = verify_request_components( :request=>[:request], :adapter=>[:adapter] ) else request_components = verify_request_components( :method=>[:method], :uri=>[:uri], :headers=>[:headers], :body=>[:body] ) end method = request_components[:method] uri = request_components[:uri] headers = request_components[:headers] body = request_components[:body] if !body.kind_of?(String) && body.respond_to?(:each) # Just in case we get a chunked body merged_body = StringIO.new body.each do |chunk| merged_body.write(chunk) end body = merged_body.string end if !body.kind_of?(String) raise TypeError, "Expected String, got #{body.class}." end media_type = nil headers.each do |(header, value)| if header.downcase == 'Content-Type'.downcase media_type = value.gsub(/^([^;]+)(;.*?)?$/, '\1') end end auth_hash = verify_auth_header_components(headers) auth_token = auth_hash['oauth_token'] unless([:two_legged]) return nil if(auth_token.nil?) return nil unless(token_credential = find_token_credential(auth_token)) token_credential_secret = token_credential.secret if token_credential end return nil unless(client_credential = find_client_credential(auth_hash['oauth_consumer_key'])) return nil unless (auth_hash['oauth_nonce'], auth_hash['oauth_timestamp']) if(method == ('POST' || 'PUT') && media_type == 'application/x-www-form-urlencoded') request_components[:body] = body post_parameters = Addressable::URI.form_unencode(body) post_parameters.each {|param| param[1] = "" if param[1].nil?} # If the auth header doesn't have the same params as the body, it # can't have been signed correctly(5849#3.4.1.3) unless(post_parameters.sort == auth_hash.reject{|k,v| k.index('oauth_')}.to_a.sort) raise MalformedAuthorizationError.new( 'Request is of type application/x-www-form-urlencoded ' + 'but Authentication header did not include form values' ) end end client_credential_secret = client_credential.secret if client_credential computed_signature = ::Signet::OAuth1.sign_parameters( method, uri, # Realm isn't used, and will throw the signature off. auth_hash.reject{|k,v| k=='realm'}.to_a, client_credential_secret, token_credential_secret ) if(computed_signature == auth_hash['oauth_signature']) {:client_credential=>client_credential, :token_credential=>token_credential, :realm=>auth_hash['realm'] } else nil end end |
#authenticate_temporary_credential_request(options) ⇒ String
Authenticates a temporary credential request. If no oauth_callback is present in the request, oob
will be returned.
245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 |
# File 'lib/signet/oauth_1/server.rb', line 245 def authenticate_temporary_credential_request(={}) verifications = { :client_credential => lambda { |x| ::Signet::OAuth1::Credential.new('Client credential key', 'Client credential secret' ) } } verifications.each do |(key, value)| raise ArgumentError, "#{key} was not set." unless self.send(key) end if([:request]) request_components = verify_request_components( :request=>[:request], :adapter=>[:adapter] ) else request_components = verify_request_components( :method=>[:method], :uri=>[:uri], :headers=>[:headers] ) end # body should be blank; we don't care in any case. method = request_components[:method] uri = request_components[:uri] headers = request_components[:headers] auth_hash = verify_auth_header_components(headers) return false unless(client_credential = find_client_credential( auth_hash['oauth_consumer_key']) ) return false unless (auth_hash['oauth_nonce'], auth_hash['oauth_timestamp']) client_credential_secret = client_credential.secret if client_credential computed_signature = ::Signet::OAuth1.sign_parameters( method, uri, # Realm isn't used, and will throw the signature off. auth_hash.reject{|k,v| k=='realm'}.to_a, client_credential_secret, nil ) if(computed_signature == auth_hash['oauth_signature']) if(auth_hash.fetch('oauth_callback', 'oob').empty?) 'oob' else auth_hash.fetch('oauth_callback') end else false end end |
#authenticate_token_credential_request(options) ⇒ Hash
Authenticates a token credential request.
311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 |
# File 'lib/signet/oauth_1/server.rb', line 311 def authenticate_token_credential_request(={}) verifications = { :client_credential => lambda {|x| ::Signet::OAuth1::Credential.new('Client credential key', 'Client credential secret') }, :temporary_credential => lambda {|x| ::Signet::OAuth1::Credential.new('Temporary credential key', 'Temporary credential secret') }, :verifier => lambda {|x| 'Verifier' } } verifications.each do |(key, value)| unless self.send(key) raise ArgumentError, "#{key} was not set." end end if([:request]) request_components = verify_request_components( :request=>[:request], :adapter=>[:adapter] ) else request_components = verify_request_components( :method=>[:method], :uri=>[:uri], :headers=>[:headers], :body=>[:body] ) end # body should be blank; we don't care in any case. method = request_components[:method] uri = request_components[:uri] headers = request_components[:headers] auth_hash = verify_auth_header_components(headers) return false unless( client_credential = find_client_credential(auth_hash['oauth_consumer_key']) ) return false unless( temporary_credential = find_temporary_credential(auth_hash['oauth_token']) ) return false unless ( auth_hash['oauth_nonce'], auth_hash['oauth_timestamp']) computed_signature = ::Signet::OAuth1.sign_parameters( method, uri, # Realm isn't used, and will throw the signature off. auth_hash.reject{|k,v| k=='realm'}.to_a, client_credential.secret, temporary_credential.secret ) if(computed_signature == auth_hash['oauth_signature']) {:client_credential=>client_credential, :temporary_credential=>temporary_credential, :realm=>auth_hash['realm'] } else nil end end |
#call_credential_lookup(credential, key) ⇒ Signet::OAuth1::Credential
Call a credential lookup, and cast the result to a proper Credential.
112 113 114 115 116 117 118 119 120 121 122 123 124 |
# File 'lib/signet/oauth_1/server.rb', line 112 def call_credential_lookup(credential, key) cred = credential.call(key) if credential.respond_to?(:call) return nil if cred.nil? return nil unless (cred.respond_to?(:to_str) || cred.respond_to?(:to_ary) || cred.respond_to?(:to_hash) ) if(cred.instance_of?(::Signet::OAuth1::Credential)) cred else ::Signet::OAuth1::Credential.new(cred) end end |
#find_client_credential(key) ⇒ Signet::OAuth1::Credential
Find the appropriate client credential by calling the #client_credential Proc.
81 82 83 |
# File 'lib/signet/oauth_1/server.rb', line 81 def find_client_credential(key) call_credential_lookup(@client_credential, key) end |
#find_temporary_credential(key) ⇒ Signet::OAuth1::Credential
Find the appropriate client credential by calling the #temporary_credential Proc.
101 102 103 |
# File 'lib/signet/oauth_1/server.rb', line 101 def find_temporary_credential(key) call_credential_lookup(@temporary_credential, key) end |
#find_token_credential(key) ⇒ Signet::OAuth1::Credential
Find the appropriate client credential by calling the #token_credential Proc.
91 92 93 |
# File 'lib/signet/oauth_1/server.rb', line 91 def find_token_credential(key) call_credential_lookup(@token_credential, key) end |
#find_verifier(verifier) ⇒ Boolean
Determine if the verifier is valid by calling the Proc in #verifier.
132 133 134 135 |
# File 'lib/signet/oauth_1/server.rb', line 132 def find_verifier(verifier) verified = @verifier.call(verifier) if @verifier.respond_to?(:call) verified ? true : false end |
#request_realm(options) ⇒ String
Returns The Authorization realm(see RFC 2617) of the request.
211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 |
# File 'lib/signet/oauth_1/server.rb', line 211 def request_realm(={}) if([:request]) request_components = verify_request_components( :request=>[:request], :adapter=>[:adapter] ) else request_components = verify_request_components( :method=>[:method], :uri=>[:uri], :headers=>[:headers], :body=>[:body] ) end auth_header = request_components[:headers].find{|x| x[0] == 'Authorization'} if(auth_header.nil? || auth_header[1] == '') raise MalformedAuthorizationError.new('Authorization header is missing') end auth_hash = ::Signet::OAuth1.( auth_header[1] ).inject({}) {|acc, (key,val)| acc[key.downcase] = val; acc} auth_hash['realm'] end |
#validate_nonce_timestamp(nonce, timestamp) ⇒ Boolean
Determine if the supplied nonce/timestamp pair is valid by calling the #nonce_timestamp Proc.
68 69 70 71 72 73 |
# File 'lib/signet/oauth_1/server.rb', line 68 def (nonce, ) nonce = @nonce_timestamp.call(nonce, ) if @nonce_timestamp.respond_to?(:call) nonce ? true : false end |
#verify_auth_header_components(headers) ⇒ Hash
Validate and normalize the HTTP Authorization header.
190 191 192 193 194 195 196 197 198 199 |
# File 'lib/signet/oauth_1/server.rb', line 190 def verify_auth_header_components(headers) auth_header = headers.find{|x| x[0] == 'Authorization'} if(auth_header.nil? || auth_header[1] == '') raise MalformedAuthorizationError.new('Authorization header is missing') end auth_hash = ::Signet::OAuth1.( auth_header[1] ).inject({}) {|acc, (key,val)| acc[key.downcase] = val; acc} auth_hash end |
#verify_request_components(options) ⇒ Hash
Validate and normalize the components from an HTTP request.
148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 |
# File 'lib/signet/oauth_1/server.rb', line 148 def verify_request_components(={}) if [:request] if [:request].kind_of?(Faraday::Request) || [:request].kind_of?(Array) request = [:request] elsif [:adapter] request = [:adapter].adapt_request([:request]) end method = request.method uri = request.path headers = request.headers body = request.body else method = [:method] || :get uri = [:uri] headers = [:headers] || [] body = [:body] || '' end headers = headers.to_a if headers.kind_of?(Hash) method = method.to_s.upcase request_components = { :method => method, :uri => uri, :headers => headers } # Verify that we have all the pieces required to validate the HTTP request request_components.each do |(key, value)| unless value raise ArgumentError, "Missing :#{key} parameter." end end request_components[:body] = body request_components end |