Class: HTTPClient::OAuth

Inherits:
AuthBase show all
Includes:
Mutex_m
Defined in:
lib/httpclient/auth.rb

Overview

Authentication filter for handling OAuth negotiation. Used in WWWAuth.

CAUTION: This impl only support '#7 Accessing Protected Resources' in OAuth Core 1.0 spec for now. You need to obtain Access token and Access secret by yourself.

CAUTION: This impl does NOT support OAuth Request Body Hash spec for now. oauth.googlecode.com/svn/spec/ext/body_hash/1.0/oauth-bodyhash.html

Defined Under Namespace

Classes: Config

Instance Attribute Summary

Attributes inherited from AuthBase

#scheme

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from AuthBase

#reset_challenge

Methods included from Util

#argument_to_hash, hash_find_value, #http?, #https?, #keyword_argument, try_require, uri_dirname, uri_part_of, urify, #warning

Constructor Details

#initializeOAuth

Creates new DigestAuth filter.


753
754
755
756
757
758
759
760
761
# File 'lib/httpclient/auth.rb', line 753

def initialize
  super('OAuth')
  @config = nil # common config
  @auth = {} # configs for each site
  @nonce_count = 0
  @signature_handler = {
    'HMAC-SHA1' => method(:sign_hmac_sha1)
  }
end

Class Method Details

.escape(str) ⇒ Object

:nodoc:


736
737
738
739
740
741
742
743
744
745
746
# File 'lib/httpclient/auth.rb', line 736

def self.escape(str) # :nodoc:
  if str.respond_to?(:force_encoding)
    str.dup.force_encoding('BINARY').gsub(/([^a-zA-Z0-9_.~-]+)/) {
      '%' + $1.unpack('H2' * $1.bytesize).join('%').upcase
    }
  else
    str.gsub(/([^a-zA-Z0-9_.~-]+)/n) {
      '%' + $1.unpack('H2' * $1.bytesize).join('%').upcase
    }
  end
end

Instance Method Details

#challenge(uri, param_str = nil) ⇒ Object

Challenge handler: remember URL for response.

challenge() in OAuth handler always returns false to avoid connection retry which should not work in OAuth authentication context. This method just remember URL (nil means 'any') for the next connection. Normally OAuthClient handles this correctly but see how it uses when you need to use this class directly.


816
817
818
819
820
821
822
823
824
825
# File 'lib/httpclient/auth.rb', line 816

def challenge(uri, param_str = nil)
  synchronize {
    if uri.nil?
      @challenge[nil] = true
    else
      @challenge[urify(uri)] = true
    end
    false
  }
end

#escape(str) ⇒ Object


748
749
750
# File 'lib/httpclient/auth.rb', line 748

def escape(str)
  self.class.escape(str)
end

#get(req) ⇒ Object

Response handler: returns credential. It sends cred only when a given uri is;

  • child page of challengeable(got *Authenticate before) uri and,

  • child page of defined credential


797
798
799
800
801
802
803
804
805
806
807
# File 'lib/httpclient/auth.rb', line 797

def get(req)
  target_uri = req.header.request_uri
  synchronize {
    return nil unless @challenge[nil] or @challenge.find { |uri, ok|
      Util.uri_part_of(target_uri, uri) and ok
    }
    config = do_get_config(target_uri) || @config
    return nil unless config
    calc_cred(req, config)
  }
end

#get_config(uri = nil) ⇒ Object

Get authentication credential.


787
788
789
790
791
# File 'lib/httpclient/auth.rb', line 787

def get_config(uri = nil)
  synchronize {
    do_get_config(uri)
  }
end

#set(*args) ⇒ Object

Set authentication credential. You cannot set OAuth config via WWWAuth#set_auth. Use OAuth#config=


765
766
767
# File 'lib/httpclient/auth.rb', line 765

def set(*args)
  # not supported
end

#set?Boolean

Check always (not effective but it works)

Returns:

  • (Boolean)

770
771
772
# File 'lib/httpclient/auth.rb', line 770

def set?
  !@challenge.empty?
end

#set_config(uri, config) ⇒ Object

Set authentication credential.


775
776
777
778
779
780
781
782
783
784
# File 'lib/httpclient/auth.rb', line 775

def set_config(uri, config)
  synchronize do
    if uri.nil?
      @config = config
    else
      uri = Util.uri_dirname(urify(uri))
      @auth[uri] = config
    end
  end
end