monkeyhelper-oauth 0.3.1 → 0.3.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.txt +62 -17
- data/Manifest.txt +14 -1
- data/README.rdoc +7 -9
- data/Rakefile +7 -5
- data/TODO +17 -0
- data/bin/oauth +2 -2
- data/examples/yql.rb +44 -0
- data/lib/oauth/cli.rb +267 -31
- data/lib/oauth/client/action_controller_request.rb +14 -12
- data/lib/oauth/client/helper.rb +22 -14
- data/lib/oauth/client/net_http.rb +53 -22
- data/lib/oauth/consumer.rb +217 -111
- data/lib/oauth/errors/error.rb +4 -0
- data/lib/oauth/errors/problem.rb +14 -0
- data/lib/oauth/errors/unauthorized.rb +12 -0
- data/lib/oauth/errors.rb +3 -0
- data/lib/oauth/helper.rb +67 -6
- data/lib/oauth/oauth.rb +11 -0
- data/lib/oauth/oauth_test_helper.rb +12 -13
- data/lib/oauth/request_proxy/action_controller_request.rb +8 -8
- data/lib/oauth/request_proxy/base.rb +102 -44
- data/lib/oauth/request_proxy/jabber_request.rb +1 -2
- data/lib/oauth/request_proxy/mock_request.rb +8 -0
- data/lib/oauth/request_proxy/net_http.rb +2 -2
- data/lib/oauth/request_proxy/rack_request.rb +7 -7
- data/lib/oauth/server.rb +31 -33
- data/lib/oauth/signature/base.rb +23 -21
- data/lib/oauth/signature/hmac/base.rb +1 -1
- data/lib/oauth/signature/hmac/sha1.rb +0 -1
- data/lib/oauth/signature/plaintext.rb +2 -2
- data/lib/oauth/signature/rsa/sha1.rb +5 -4
- data/lib/oauth/signature.rb +9 -0
- data/lib/oauth/token.rb +6 -136
- data/lib/oauth/tokens/access_token.rb +68 -0
- data/lib/oauth/tokens/consumer_token.rb +33 -0
- data/lib/oauth/tokens/request_token.rb +32 -0
- data/lib/oauth/tokens/server_token.rb +9 -0
- data/lib/oauth/tokens/token.rb +17 -0
- data/lib/oauth/version.rb +1 -1
- data/lib/oauth.rb +1 -0
- data/oauth.gemspec +12 -6
- data/test/cases/spec/1_0-final/test_construct_request_url.rb +1 -1
- data/test/test_access_token.rb +28 -0
- data/test/test_action_controller_request_proxy.rb +105 -6
- data/test/test_consumer.rb +41 -5
- data/test/test_helper.rb +0 -5
- data/test/test_net_http_client.rb +38 -20
- data/test/test_net_http_request_proxy.rb +43 -8
- data/test/test_oauth_helper.rb +50 -0
- data/test/test_request_token.rb +53 -0
- data/test/test_server.rb +1 -1
- data/test/test_signature.rb +19 -11
- data/website/index.html +2 -2
- metadata +41 -3
    
        data/lib/oauth/consumer.rb
    CHANGED
    
    | @@ -1,19 +1,32 @@ | |
| 1 1 | 
             
            require 'net/http'
         | 
| 2 2 | 
             
            require 'net/https'
         | 
| 3 | 
            +
            require 'oauth/oauth'
         | 
| 3 4 | 
             
            require 'oauth/client/net_http'
         | 
| 5 | 
            +
            require 'oauth/errors'
         | 
| 6 | 
            +
             | 
| 4 7 | 
             
            module OAuth
         | 
| 5 8 | 
             
              class Consumer
         | 
| 6 | 
            -
                
         | 
| 7 | 
            -
                 | 
| 9 | 
            +
                # determine the certificate authority path to verify SSL certs
         | 
| 10 | 
            +
                CA_FILES = %w(/etc/ssl/certs/ca-certificates.crt /usr/share/curl/curl-ca-bundle.crt)
         | 
| 11 | 
            +
                CA_FILES.each do |ca_file|
         | 
| 12 | 
            +
                  if File.exists?(ca_file)
         | 
| 13 | 
            +
                    CA_FILE = ca_file
         | 
| 14 | 
            +
                    break
         | 
| 15 | 
            +
                  end
         | 
| 16 | 
            +
                end
         | 
| 17 | 
            +
                CA_FILE = nil unless defined?(CA_FILE)
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                @@default_options = {
         | 
| 8 20 | 
             
                  # Signature method used by server. Defaults to HMAC-SHA1
         | 
| 9 | 
            -
                  :signature_method | 
| 10 | 
            -
             | 
| 21 | 
            +
                  :signature_method   => 'HMAC-SHA1',
         | 
| 22 | 
            +
             | 
| 11 23 | 
             
                  # default paths on site. These are the same as the defaults set up by the generators
         | 
| 12 | 
            -
                  :request_token_path=>'/oauth/request_token',
         | 
| 13 | 
            -
                  :authorize_path=>'/oauth/authorize',
         | 
| 14 | 
            -
                  :access_token_path=>'/oauth/access_token',
         | 
| 15 | 
            -
             | 
| 16 | 
            -
                   | 
| 24 | 
            +
                  :request_token_path => '/oauth/request_token',
         | 
| 25 | 
            +
                  :authorize_path     => '/oauth/authorize',
         | 
| 26 | 
            +
                  :access_token_path  => '/oauth/access_token',
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                  :proxy              => nil,
         | 
| 29 | 
            +
                  # How do we send the oauth values to the server see
         | 
| 17 30 | 
             
                  # http://oauth.net/core/1.0/#consumer_req_param for more info
         | 
| 18 31 | 
             
                  #
         | 
| 19 32 | 
             
                  # Possible values:
         | 
| @@ -21,123 +34,179 @@ module OAuth | |
| 21 34 | 
             
                  #   :header - via the Authorize header (Default) ( option 1. in spec)
         | 
| 22 35 | 
             
                  #   :body - url form encoded in body of POST request ( option 2. in spec)
         | 
| 23 36 | 
             
                  #   :query_string - via the query part of the url ( option 3. in spec)
         | 
| 24 | 
            -
                  :scheme | 
| 25 | 
            -
             | 
| 37 | 
            +
                  :scheme        => :header,
         | 
| 38 | 
            +
             | 
| 26 39 | 
             
                  # Default http method used for OAuth Token Requests (defaults to :post)
         | 
| 27 | 
            -
                  :http_method | 
| 28 | 
            -
             | 
| 29 | 
            -
                  :oauth_version=>"1.0"
         | 
| 40 | 
            +
                  :http_method   => :post,
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                  :oauth_version => "1.0"
         | 
| 30 43 | 
             
                }
         | 
| 31 | 
            -
             | 
| 32 | 
            -
                attr_accessor : | 
| 33 | 
            -
                
         | 
| 34 | 
            -
             | 
| 44 | 
            +
             | 
| 45 | 
            +
                attr_accessor :options, :key, :secret
         | 
| 46 | 
            +
                attr_writer   :site, :http
         | 
| 47 | 
            +
             | 
| 35 48 | 
             
                # Create a new consumer instance by passing it a configuration hash:
         | 
| 36 49 | 
             
                #
         | 
| 37 | 
            -
                #   @consumer=OAuth::Consumer.new( | 
| 38 | 
            -
                #     :site=>"http://term.ie",
         | 
| 39 | 
            -
                #     :scheme | 
| 40 | 
            -
                #     :http_method | 
| 41 | 
            -
                #     :request_token_path=>"/oauth/example/request_token.php",
         | 
| 42 | 
            -
                #     :access_token_path=>"/oauth/example/access_token.php",
         | 
| 43 | 
            -
                #     :authorize_path=>"/oauth/example/authorize.php"
         | 
| 50 | 
            +
                #   @consumer = OAuth::Consumer.new(key, secret, {
         | 
| 51 | 
            +
                #     :site               => "http://term.ie",
         | 
| 52 | 
            +
                #     :scheme             => :header,
         | 
| 53 | 
            +
                #     :http_method        => :post,
         | 
| 54 | 
            +
                #     :request_token_path => "/oauth/example/request_token.php",
         | 
| 55 | 
            +
                #     :access_token_path  => "/oauth/example/access_token.php",
         | 
| 56 | 
            +
                #     :authorize_path     => "/oauth/example/authorize.php"
         | 
| 44 57 | 
             
                #    })
         | 
| 45 58 | 
             
                #
         | 
| 46 59 | 
             
                # Start the process by requesting a token
         | 
| 47 60 | 
             
                #
         | 
| 48 | 
            -
                #   @request_token | 
| 49 | 
            -
                #   session[:request_token] | 
| 61 | 
            +
                #   @request_token = @consumer.get_request_token
         | 
| 62 | 
            +
                #   session[:request_token] = @request_token
         | 
| 50 63 | 
             
                #   redirect_to @request_token.authorize_url
         | 
| 51 64 | 
             
                #
         | 
| 52 65 | 
             
                # When user returns create an access_token
         | 
| 53 66 | 
             
                #
         | 
| 54 | 
            -
                #   @access_token | 
| 67 | 
            +
                #   @access_token = @request_token.get_access_token
         | 
| 55 68 | 
             
                #   @photos=@access_token.get('/photos.xml')
         | 
| 56 69 | 
             
                #
         | 
| 57 | 
            -
                 | 
| 58 | 
            -
                
         | 
| 59 | 
            -
             | 
| 70 | 
            +
                def initialize(consumer_key, consumer_secret, options = {})
         | 
| 71 | 
            +
                  @key    = consumer_key
         | 
| 72 | 
            +
                  @secret = consumer_secret
         | 
| 73 | 
            +
             | 
| 60 74 | 
             
                  # ensure that keys are symbols
         | 
| 61 | 
            -
                  @options | 
| 75 | 
            +
                  @options = @@default_options.merge(options.inject({}) { |options, (key, value)|
         | 
| 62 76 | 
             
                    options[key.to_sym] = value
         | 
| 63 77 | 
             
                    options
         | 
| 64 | 
            -
                   | 
| 65 | 
            -
                  @key = consumer_key
         | 
| 66 | 
            -
                  @secret = consumer_secret
         | 
| 78 | 
            +
                  })
         | 
| 67 79 | 
             
                end
         | 
| 68 | 
            -
             | 
| 80 | 
            +
             | 
| 69 81 | 
             
                # The default http method
         | 
| 70 82 | 
             
                def http_method
         | 
| 71 | 
            -
                  @http_method | 
| 83 | 
            +
                  @http_method ||= @options[:http_method] || :post
         | 
| 72 84 | 
             
                end
         | 
| 73 | 
            -
             | 
| 85 | 
            +
             | 
| 74 86 | 
             
                # The HTTP object for the site. The HTTP Object is what you get when you do Net::HTTP.new
         | 
| 75 87 | 
             
                def http
         | 
| 76 88 | 
             
                  @http ||= create_http
         | 
| 77 89 | 
             
                end
         | 
| 78 | 
            -
             | 
| 90 | 
            +
             | 
| 79 91 | 
             
                # Contains the root URI for this site
         | 
| 80 | 
            -
                def uri(custom_uri=nil)
         | 
| 92 | 
            +
                def uri(custom_uri = nil)
         | 
| 81 93 | 
             
                  if custom_uri
         | 
| 82 | 
            -
                    @uri | 
| 94 | 
            +
                    @uri  = custom_uri
         | 
| 83 95 | 
             
                    @http = create_http # yike, oh well. less intrusive this way
         | 
| 84 96 | 
             
                  else  # if no custom passed, we use existing, which, if unset, is set to site uri
         | 
| 85 97 | 
             
                    @uri ||= URI.parse(site)
         | 
| 86 98 | 
             
                  end
         | 
| 87 99 | 
             
                end
         | 
| 88 | 
            -
             | 
| 100 | 
            +
             | 
| 101 | 
            +
                def get_access_token(request_token, request_options = {}, *arguments)
         | 
| 102 | 
            +
                  response = token_request(http_method, (access_token_url? ? access_token_url : access_token_path), request_token, request_options, *arguments)
         | 
| 103 | 
            +
                  OAuth::AccessToken.from_hash(self, response)
         | 
| 104 | 
            +
                end
         | 
| 105 | 
            +
             | 
| 89 106 | 
             
                # Makes a request to the service for a new OAuth::RequestToken
         | 
| 90 | 
            -
                #   
         | 
| 91 | 
            -
                #  @request_token=@consumer.get_request_token
         | 
| 92 107 | 
             
                #
         | 
| 93 | 
            -
                 | 
| 94 | 
            -
             | 
| 95 | 
            -
             | 
| 108 | 
            +
                #  @request_token = @consumer.get_request_token
         | 
| 109 | 
            +
                #
         | 
| 110 | 
            +
                # To include OAuth parameters:
         | 
| 111 | 
            +
                #
         | 
| 112 | 
            +
                #  @request_token = @consumer.get_request_token \
         | 
| 113 | 
            +
                #    :oauth_callback => "http://example.com/cb"
         | 
| 114 | 
            +
                #
         | 
| 115 | 
            +
                # To include application-specific parameters:
         | 
| 116 | 
            +
                #
         | 
| 117 | 
            +
                #  @request_token = @consumer.get_request_token({}, :foo => "bar")
         | 
| 118 | 
            +
                #
         | 
| 119 | 
            +
                # TODO oauth_callback should be a mandatory parameter
         | 
| 120 | 
            +
                def get_request_token(request_options = {}, *arguments)
         | 
| 121 | 
            +
                  # if oauth_callback wasn't provided, it is assumed that oauth_verifiers
         | 
| 122 | 
            +
                  # will be exchanged out of band
         | 
| 123 | 
            +
                  request_options[:oauth_callback] ||= OAuth::OUT_OF_BAND
         | 
| 124 | 
            +
             | 
| 125 | 
            +
                  response = token_request(http_method, (request_token_url? ? request_token_url : request_token_path), nil, request_options, *arguments)
         | 
| 126 | 
            +
                  OAuth::RequestToken.from_hash(self, response)
         | 
| 96 127 | 
             
                end
         | 
| 97 | 
            -
             | 
| 128 | 
            +
             | 
| 98 129 | 
             
                # Creates, signs and performs an http request.
         | 
| 99 130 | 
             
                # It's recommended to use the OAuth::Token classes to set this up correctly.
         | 
| 100 | 
            -
                #  | 
| 101 | 
            -
                # 
         | 
| 102 | 
            -
                # | 
| 103 | 
            -
                #    | 
| 131 | 
            +
                # request_options take precedence over consumer-wide options when signing
         | 
| 132 | 
            +
                #   a request.
         | 
| 133 | 
            +
                # arguments are POST and PUT bodies (a Hash, string-encoded parameters, or
         | 
| 134 | 
            +
                #   absent), followed by additional HTTP headers.
         | 
| 104 135 | 
             
                #
         | 
| 105 | 
            -
                 | 
| 106 | 
            -
             | 
| 107 | 
            -
             | 
| 108 | 
            -
             | 
| 109 | 
            -
             | 
| 110 | 
            -
                     | 
| 111 | 
            -
                     | 
| 136 | 
            +
                #   @consumer.request(:get,  '/people', @token, { :scheme => :query_string })
         | 
| 137 | 
            +
                #   @consumer.request(:post, '/people', @token, {}, @person.to_xml, { 'Content-Type' => 'application/xml' })
         | 
| 138 | 
            +
                #
         | 
| 139 | 
            +
                def request(http_method, path, token = nil, request_options = {}, *arguments)
         | 
| 140 | 
            +
                  if path !~ /^\//
         | 
| 141 | 
            +
                    @http = create_http(path)
         | 
| 142 | 
            +
                    _uri = URI.parse(path)
         | 
| 143 | 
            +
                    path = "#{_uri.path}#{_uri.query ? "?#{_uri.query}" : ""}"
         | 
| 112 144 | 
             
                  end
         | 
| 113 | 
            -
             | 
| 145 | 
            +
             | 
| 146 | 
            +
                  rsp = http.request(create_signed_request(http_method, path, token, request_options, *arguments))
         | 
| 147 | 
            +
             | 
| 148 | 
            +
                  # check for an error reported by the Problem Reporting extension
         | 
| 149 | 
            +
                  # (http://wiki.oauth.net/ProblemReporting)
         | 
| 150 | 
            +
                  # note: a 200 may actually be an error; check for an oauth_problem key to be sure
         | 
| 151 | 
            +
                  if !(headers = rsp.to_hash["www-authenticate"]).nil? &&
         | 
| 152 | 
            +
                    (h = headers.select { |h| h =~ /^OAuth / }).any? &&
         | 
| 153 | 
            +
                    h.first =~ /oauth_problem/
         | 
| 154 | 
            +
             | 
| 155 | 
            +
                    # puts "Header: #{h.first}"
         | 
| 156 | 
            +
             | 
| 157 | 
            +
                    # TODO doesn't handle broken responses from api.login.yahoo.com
         | 
| 158 | 
            +
                    # remove debug code when done
         | 
| 159 | 
            +
                    params = OAuth::Helper.parse_header(h.first)
         | 
| 160 | 
            +
             | 
| 161 | 
            +
                    # puts "Params: #{params.inspect}"
         | 
| 162 | 
            +
                    # puts "Body: #{rsp.body}"
         | 
| 163 | 
            +
             | 
| 164 | 
            +
                    raise OAuth::Problem.new(params.delete("oauth_problem"), rsp, params)
         | 
| 165 | 
            +
                  end
         | 
| 166 | 
            +
             | 
| 167 | 
            +
                  rsp
         | 
| 114 168 | 
             
                end
         | 
| 115 | 
            -
             | 
| 169 | 
            +
             | 
| 116 170 | 
             
                # Creates and signs an http request.
         | 
| 117 171 | 
             
                # It's recommended to use the Token classes to set this up correctly
         | 
| 118 | 
            -
                def create_signed_request(http_method,path, token=nil,request_options={} | 
| 119 | 
            -
                  request=create_http_request(http_method,path | 
| 120 | 
            -
                  sign!(request,token,request_options)
         | 
| 172 | 
            +
                def create_signed_request(http_method, path, token = nil, request_options = {}, *arguments)
         | 
| 173 | 
            +
                  request = create_http_request(http_method, path, *arguments)
         | 
| 174 | 
            +
                  sign!(request, token, request_options)
         | 
| 121 175 | 
             
                  request
         | 
| 122 176 | 
             
                end
         | 
| 123 | 
            -
             | 
| 177 | 
            +
             | 
| 124 178 | 
             
                # Creates a request and parses the result as url_encoded. This is used internally for the RequestToken and AccessToken requests.
         | 
| 125 | 
            -
                def token_request(http_method,path,token=nil,request_options={} | 
| 126 | 
            -
                  response=request(http_method,path,token,request_options | 
| 127 | 
            -
             | 
| 128 | 
            -
             | 
| 129 | 
            -
             | 
| 130 | 
            -
             | 
| 179 | 
            +
                def token_request(http_method, path, token = nil, request_options = {}, *arguments)
         | 
| 180 | 
            +
                  response = request(http_method, path, token, request_options, *arguments)
         | 
| 181 | 
            +
             | 
| 182 | 
            +
                  case response.code.to_i
         | 
| 183 | 
            +
             | 
| 184 | 
            +
                  when (200..299)
         | 
| 185 | 
            +
                    # symbolize keys
         | 
| 186 | 
            +
                    # TODO this could be considered unexpected behavior; symbols or not?
         | 
| 187 | 
            +
                    # TODO this also drops subsequent values from multi-valued keys
         | 
| 188 | 
            +
                    CGI.parse(response.body).inject({}) do |h,(k,v)|
         | 
| 189 | 
            +
                      h[k.to_sym] = v.first
         | 
| 190 | 
            +
                      h[k]        = v.first
         | 
| 191 | 
            +
                      h
         | 
| 192 | 
            +
                    end
         | 
| 193 | 
            +
                  when (300..399)
         | 
| 194 | 
            +
                    # this is a redirect
         | 
| 195 | 
            +
                    response.error!
         | 
| 196 | 
            +
                  when (400..499)
         | 
| 197 | 
            +
                    raise OAuth::Unauthorized, response
         | 
| 198 | 
            +
                  else
         | 
| 199 | 
            +
                    response.error!
         | 
| 131 200 | 
             
                  end
         | 
| 132 201 | 
             
                end
         | 
| 133 202 |  | 
| 134 203 | 
             
                # Sign the Request object. Use this if you have an externally generated http request object you want to sign.
         | 
| 135 | 
            -
                def sign!(request,token=nil, request_options = {})
         | 
| 204 | 
            +
                def sign!(request, token = nil, request_options = {})
         | 
| 136 205 | 
             
                  request.oauth!(http, self, token, options.merge(request_options))
         | 
| 137 206 | 
             
                end
         | 
| 138 | 
            -
             | 
| 207 | 
            +
             | 
| 139 208 | 
             
                # Return the signature_base_string
         | 
| 140 | 
            -
                def signature_base_string(request,token=nil, request_options = {})
         | 
| 209 | 
            +
                def signature_base_string(request, token = nil, request_options = {})
         | 
| 141 210 | 
             
                  request.signature_base_string(http, self, token, options.merge(request_options))
         | 
| 142 211 | 
             
                end
         | 
| 143 212 |  | 
| @@ -148,90 +217,127 @@ module OAuth | |
| 148 217 | 
             
                def scheme
         | 
| 149 218 | 
             
                  @options[:scheme]
         | 
| 150 219 | 
             
                end
         | 
| 151 | 
            -
             | 
| 220 | 
            +
             | 
| 152 221 | 
             
                def request_token_path
         | 
| 153 222 | 
             
                  @options[:request_token_path]
         | 
| 154 223 | 
             
                end
         | 
| 155 | 
            -
             | 
| 224 | 
            +
             | 
| 156 225 | 
             
                def authorize_path
         | 
| 157 226 | 
             
                  @options[:authorize_path]
         | 
| 158 227 | 
             
                end
         | 
| 159 | 
            -
             | 
| 228 | 
            +
             | 
| 160 229 | 
             
                def access_token_path
         | 
| 161 230 | 
             
                  @options[:access_token_path]
         | 
| 162 231 | 
             
                end
         | 
| 163 | 
            -
             | 
| 232 | 
            +
             | 
| 164 233 | 
             
                # TODO this is ugly, rewrite
         | 
| 165 234 | 
             
                def request_token_url
         | 
| 166 | 
            -
                  @options[:request_token_url]||site+request_token_path
         | 
| 235 | 
            +
                  @options[:request_token_url] || site + request_token_path
         | 
| 167 236 | 
             
                end
         | 
| 168 237 |  | 
| 169 238 | 
             
                def request_token_url?
         | 
| 170 | 
            -
                  @options | 
| 239 | 
            +
                  @options.has_key?(:request_token_url)
         | 
| 171 240 | 
             
                end
         | 
| 172 | 
            -
             | 
| 241 | 
            +
             | 
| 173 242 | 
             
                def authorize_url
         | 
| 174 | 
            -
                  @options[:authorize_url]||site+authorize_path
         | 
| 243 | 
            +
                  @options[:authorize_url] || site + authorize_path
         | 
| 175 244 | 
             
                end
         | 
| 176 | 
            -
             | 
| 245 | 
            +
             | 
| 177 246 | 
             
                def authorize_url?
         | 
| 178 | 
            -
                  @options | 
| 247 | 
            +
                  @options.has_key?(:authorize_url)
         | 
| 179 248 | 
             
                end
         | 
| 180 249 |  | 
| 181 250 | 
             
                def access_token_url
         | 
| 182 | 
            -
                  @options[:access_token_url]||site+access_token_path
         | 
| 251 | 
            +
                  @options[:access_token_url] || site + access_token_path
         | 
| 183 252 | 
             
                end
         | 
| 184 253 |  | 
| 185 254 | 
             
                def access_token_url?
         | 
| 186 | 
            -
                  @options | 
| 255 | 
            +
                  @options.has_key?(:access_token_url)
         | 
| 256 | 
            +
                end
         | 
| 257 | 
            +
             | 
| 258 | 
            +
                def proxy
         | 
| 259 | 
            +
                  @options[:proxy]
         | 
| 187 260 | 
             
                end
         | 
| 188 261 |  | 
| 189 | 
            -
             | 
| 190 | 
            -
             | 
| 191 | 
            -
                #Instantiates the http object
         | 
| 192 | 
            -
                def create_http(_url=nil)
         | 
| 193 | 
            -
                  if _url.nil | 
| 194 | 
            -
                    our_uri=URI.parse(site)
         | 
| 262 | 
            +
              protected
         | 
| 263 | 
            +
             | 
| 264 | 
            +
                # Instantiates the http object
         | 
| 265 | 
            +
                def create_http(_url = nil)
         | 
| 266 | 
            +
                  if _url.nil? || _url[0] =~ /^\//
         | 
| 267 | 
            +
                    our_uri = URI.parse(site)
         | 
| 268 | 
            +
                  else
         | 
| 269 | 
            +
                    our_uri = URI.parse(_url)
         | 
| 270 | 
            +
                  end
         | 
| 271 | 
            +
             | 
| 272 | 
            +
                  if proxy.nil?
         | 
| 273 | 
            +
                    http_object = Net::HTTP.new(our_uri.host, our_uri.port)
         | 
| 274 | 
            +
                  else
         | 
| 275 | 
            +
                    proxy_uri = proxy.is_a?(URI) ? proxy : URI.parse(proxy)
         | 
| 276 | 
            +
                    http_object = Net::HTTP.new(our_uri.host, our_uri.port, proxy_uri.host, proxy_uri.port, proxy_uri.user, proxy_uri.password)
         | 
| 277 | 
            +
                  end
         | 
| 278 | 
            +
             | 
| 279 | 
            +
                  http_object.use_ssl = (our_uri.scheme == 'https')
         | 
| 280 | 
            +
             | 
| 281 | 
            +
                  if CA_FILE
         | 
| 282 | 
            +
                    http_object.ca_file = CA_FILE
         | 
| 283 | 
            +
                    http_object.verify_mode = OpenSSL::SSL::VERIFY_PEER
         | 
| 284 | 
            +
                    http_object.verify_depth = 5
         | 
| 195 285 | 
             
                  else
         | 
| 196 | 
            -
                     | 
| 286 | 
            +
                    http_object.verify_mode = OpenSSL::SSL::VERIFY_NONE
         | 
| 197 287 | 
             
                  end
         | 
| 198 | 
            -
             | 
| 199 | 
            -
                  http_object.use_ssl = true if our_uri.scheme=="https"
         | 
| 288 | 
            +
             | 
| 200 289 | 
             
                  http_object
         | 
| 201 290 | 
             
                end
         | 
| 202 | 
            -
             | 
| 291 | 
            +
             | 
| 203 292 | 
             
                # create the http request object for a given http_method and path
         | 
| 204 | 
            -
                def create_http_request(http_method,path | 
| 205 | 
            -
                  http_method=http_method.to_sym
         | 
| 206 | 
            -
             | 
| 207 | 
            -
             | 
| 293 | 
            +
                def create_http_request(http_method, path, *arguments)
         | 
| 294 | 
            +
                  http_method = http_method.to_sym
         | 
| 295 | 
            +
             | 
| 296 | 
            +
                  if [:post, :put].include?(http_method)
         | 
| 297 | 
            +
                    data = arguments.shift
         | 
| 298 | 
            +
                    data = {} if data.nil?
         | 
| 208 299 | 
             
                  end
         | 
| 209 | 
            -
             | 
| 300 | 
            +
             | 
| 301 | 
            +
                  headers = arguments.first.is_a?(Hash) ? arguments.first.reject { |k,v| v.nil? } : {}
         | 
| 302 | 
            +
             | 
| 210 303 | 
             
                  case http_method
         | 
| 211 304 | 
             
                  when :post
         | 
| 212 | 
            -
                    request=Net::HTTP::Post.new(path,headers)
         | 
| 213 | 
            -
                    request["Content-Length"]=0 # Default to 0
         | 
| 305 | 
            +
                    request = Net::HTTP::Post.new(path,headers)
         | 
| 306 | 
            +
                    request["Content-Length"] = 0 # Default to 0
         | 
| 214 307 | 
             
                  when :put
         | 
| 215 | 
            -
                    request=Net::HTTP::Put.new(path,headers)
         | 
| 216 | 
            -
                    request["Content-Length"]=0 # Default to 0
         | 
| 308 | 
            +
                    request = Net::HTTP::Put.new(path,headers)
         | 
| 309 | 
            +
                    request["Content-Length"] = 0 # Default to 0
         | 
| 217 310 | 
             
                  when :get
         | 
| 218 | 
            -
                    request=Net::HTTP::Get.new(path,headers)
         | 
| 311 | 
            +
                    request = Net::HTTP::Get.new(path,headers)
         | 
| 219 312 | 
             
                  when :delete
         | 
| 220 | 
            -
                    request=Net::HTTP::Delete.new(path,headers)
         | 
| 313 | 
            +
                    request =  Net::HTTP::Delete.new(path,headers)
         | 
| 221 314 | 
             
                  when :head
         | 
| 222 | 
            -
                    request=Net::HTTP::Head.new(path,headers)
         | 
| 315 | 
            +
                    request = Net::HTTP::Head.new(path,headers)
         | 
| 223 316 | 
             
                  else
         | 
| 224 317 | 
             
                    raise ArgumentError, "Don't know how to handle http_method: :#{http_method.to_s}"
         | 
| 225 318 | 
             
                  end
         | 
| 319 | 
            +
             | 
| 226 320 | 
             
                  if data.is_a?(Hash)
         | 
| 227 321 | 
             
                    request.set_form_data(data)
         | 
| 228 322 | 
             
                  elsif data
         | 
| 229 | 
            -
                     | 
| 230 | 
            -
             | 
| 323 | 
            +
                    if data.respond_to?(:read)
         | 
| 324 | 
            +
                      request.body_stream = data
         | 
| 325 | 
            +
                      if data.respond_to?(:length)
         | 
| 326 | 
            +
                        request["Content-Length"] = data.length
         | 
| 327 | 
            +
                      elsif data.respond_to?(:stat) && data.stat.respond_to?(:size)
         | 
| 328 | 
            +
                        request["Content-Length"] = data.stat.size
         | 
| 329 | 
            +
                      else
         | 
| 330 | 
            +
                        raise ArgumentError, "Don't know how to send a body_stream that doesn't respond to .length or .stat.size"
         | 
| 331 | 
            +
                      end
         | 
| 332 | 
            +
                    else
         | 
| 333 | 
            +
                      request.body = data.to_s
         | 
| 334 | 
            +
                      request["Content-Length"] = request.body.length
         | 
| 335 | 
            +
                    end
         | 
| 231 336 | 
             
                  end
         | 
| 337 | 
            +
             | 
| 232 338 | 
             
                  request
         | 
| 233 339 | 
             
                end
         | 
| 234 | 
            -
             | 
| 340 | 
            +
             | 
| 235 341 | 
             
                # Unset cached http instance because it cannot be marshalled when
         | 
| 236 342 | 
             
                # it has already been used and use_ssl is set to true
         | 
| 237 343 | 
             
                def marshal_dump(*args)
         | 
    
        data/lib/oauth/errors.rb
    ADDED
    
    
    
        data/lib/oauth/helper.rb
    CHANGED
    
    | @@ -1,17 +1,78 @@ | |
| 1 1 | 
             
            require 'openssl'
         | 
| 2 2 | 
             
            require 'base64'
         | 
| 3 | 
            -
             | 
| 3 | 
            +
             | 
| 4 4 | 
             
            module OAuth
         | 
| 5 5 | 
             
              module Helper
         | 
| 6 6 | 
             
                extend self
         | 
| 7 7 |  | 
| 8 | 
            +
                # Escape +value+ by URL encoding all non-reserved character. 
         | 
| 9 | 
            +
                #
         | 
| 10 | 
            +
                # See Also: {OAuth core spec version 1.0, section 5.1}[http://oauth.net/core/1.0#rfc.section.5.1]
         | 
| 8 11 | 
             
                def escape(value)
         | 
| 9 | 
            -
                   | 
| 12 | 
            +
                  URI::escape(value.to_s, OAuth::RESERVED_CHARACTERS)
         | 
| 10 13 | 
             
                end
         | 
| 11 | 
            -
             | 
| 14 | 
            +
             | 
| 15 | 
            +
                # Generate a random key of up to +size+ bytes. The value returned is Base64 encoded with non-word
         | 
| 16 | 
            +
                # characters removed.
         | 
| 12 17 | 
             
                def generate_key(size=32)
         | 
| 13 | 
            -
                  Base64.encode64(OpenSSL::Random.random_bytes(size)).gsub(/\W/,'')
         | 
| 14 | 
            -
                end | 
| 15 | 
            -
             | 
| 18 | 
            +
                  Base64.encode64(OpenSSL::Random.random_bytes(size)).gsub(/\W/, '')
         | 
| 19 | 
            +
                end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                alias_method :generate_nonce, :generate_key
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                def generate_timestamp #:nodoc:
         | 
| 24 | 
            +
                  Time.now.to_i.to_s
         | 
| 25 | 
            +
                end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                # Normalize a +Hash+ of parameter values. Parameters are sorted by name, using lexicographical
         | 
| 28 | 
            +
                # byte value ordering. If two or more parameters share the same name, they are sorted by their value.
         | 
| 29 | 
            +
                # Parameters are concatenated in their sorted order into a single string. For each parameter, the name
         | 
| 30 | 
            +
                # is separated from the corresponding value by an "=" character, even if the value is empty. Each
         | 
| 31 | 
            +
                # name-value pair is separated by an "&" character.
         | 
| 32 | 
            +
                #
         | 
| 33 | 
            +
                # See Also: {OAuth core spec version 1.0, section 9.1.1}[http://oauth.net/core/1.0#rfc.section.9.1.1]
         | 
| 34 | 
            +
                def normalize(params)
         | 
| 35 | 
            +
                  params.sort.map do |k, values|
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                    if values.is_a?(Array)
         | 
| 38 | 
            +
                      # multiple values were provided for a single key
         | 
| 39 | 
            +
                      values.sort.collect do |v|
         | 
| 40 | 
            +
                        [escape(k),escape(v)] * "="
         | 
| 41 | 
            +
                      end
         | 
| 42 | 
            +
                    else
         | 
| 43 | 
            +
                      [escape(k),escape(values)] * "="
         | 
| 44 | 
            +
                    end
         | 
| 45 | 
            +
                  end * "&"
         | 
| 46 | 
            +
                end
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                # Parse an Authorization / WWW-Authenticate header into a hash. Takes care of unescaping and
         | 
| 49 | 
            +
                # removing surrounding quotes. Raises a OAuth::Problem if the header is not parsable into a
         | 
| 50 | 
            +
                # valid hash. Does not validate the keys or values.
         | 
| 51 | 
            +
                #
         | 
| 52 | 
            +
                #   hash = parse_header(headers['Authorization'] || headers['WWW-Authenticate'])
         | 
| 53 | 
            +
                #   hash['oauth_timestamp']
         | 
| 54 | 
            +
                #     #=>"1234567890"
         | 
| 55 | 
            +
                # 
         | 
| 56 | 
            +
                def parse_header(header)
         | 
| 57 | 
            +
                  # decompose
         | 
| 58 | 
            +
                  params = header[6,header.length].split(/[,=]/)
         | 
| 59 | 
            +
             | 
| 60 | 
            +
                  # odd number of arguments - must be a malformed header.
         | 
| 61 | 
            +
                  raise OAuth::Problem.new("Invalid authorization header") if params.size % 2 != 0
         | 
| 62 | 
            +
             | 
| 63 | 
            +
                  params.map! do |v|
         | 
| 64 | 
            +
                    # strip and unescape
         | 
| 65 | 
            +
                    val = unescape(v.strip)
         | 
| 66 | 
            +
                    # strip quotes
         | 
| 67 | 
            +
                    val.sub(/^\"(.*)\"$/, '\1')
         | 
| 68 | 
            +
                  end
         | 
| 69 | 
            +
             | 
| 70 | 
            +
                  # convert into a Hash
         | 
| 71 | 
            +
                  Hash[*params.flatten]
         | 
| 72 | 
            +
                end
         | 
| 73 | 
            +
             | 
| 74 | 
            +
                def unescape(value)
         | 
| 75 | 
            +
                  URI.unescape(value.gsub('+', '%2B'))
         | 
| 76 | 
            +
                end
         | 
| 16 77 | 
             
              end
         | 
| 17 78 | 
             
            end
         | 
    
        data/lib/oauth/oauth.rb
    ADDED
    
    | @@ -0,0 +1,11 @@ | |
| 1 | 
            +
            module OAuth
         | 
| 2 | 
            +
              # request tokens are passed between the consumer and the provider out of
         | 
| 3 | 
            +
              # band (i.e. callbacks cannot be used), per section 6.1.1
         | 
| 4 | 
            +
              OUT_OF_BAND = "oob"
         | 
| 5 | 
            +
             | 
| 6 | 
            +
              # required parameters, per sections 6.1.1, 6.3.1, and 7
         | 
| 7 | 
            +
              PARAMETERS = %w(oauth_callback oauth_consumer_key oauth_token oauth_signature_method oauth_timestamp oauth_nonce oauth_verifier oauth_version oauth_signature)
         | 
| 8 | 
            +
             | 
| 9 | 
            +
              # reserved character regexp, per section 5.1
         | 
| 10 | 
            +
              RESERVED_CHARACTERS = /[^a-zA-Z0-9\-\.\_\~]/
         | 
| 11 | 
            +
            end
         | 
| @@ -1,26 +1,25 @@ | |
| 1 1 | 
             
            require 'action_controller'
         | 
| 2 2 | 
             
            require 'action_controller/test_process'
         | 
| 3 | 
            +
             | 
| 3 4 | 
             
            module OAuth
         | 
| 4 5 | 
             
              module OAuthTestHelper
         | 
| 5 | 
            -
                
         | 
| 6 6 | 
             
                def mock_incoming_request_with_query(request)
         | 
| 7 | 
            -
                  incoming=ActionController::TestRequest.new(request.to_hash)
         | 
| 8 | 
            -
                  incoming.request_uri=request.path
         | 
| 9 | 
            -
                  incoming. | 
| 10 | 
            -
                  incoming. | 
| 11 | 
            -
                  incoming.env['REQUEST_METHOD']=request.http_method
         | 
| 7 | 
            +
                  incoming = ActionController::TestRequest.new(request.to_hash)
         | 
| 8 | 
            +
                  incoming.request_uri = request.path
         | 
| 9 | 
            +
                  incoming.host = request.uri.host
         | 
| 10 | 
            +
                  incoming.env["SERVER_PORT"] = request.uri.port
         | 
| 11 | 
            +
                  incoming.env['REQUEST_METHOD'] = request.http_method
         | 
| 12 12 | 
             
                  incoming
         | 
| 13 13 | 
             
                end
         | 
| 14 14 |  | 
| 15 15 | 
             
                def mock_incoming_request_with_authorize_header(request)
         | 
| 16 | 
            -
                  incoming=ActionController::TestRequest.new
         | 
| 17 | 
            -
                  incoming. | 
| 18 | 
            -
                  incoming. | 
| 19 | 
            -
                  incoming.env[" | 
| 20 | 
            -
                  incoming. | 
| 21 | 
            -
                  incoming.env['REQUEST_METHOD']=request.http_method
         | 
| 16 | 
            +
                  incoming = ActionController::TestRequest.new
         | 
| 17 | 
            +
                  incoming.request_uri = request.path
         | 
| 18 | 
            +
                  incoming.host = request.uri.host
         | 
| 19 | 
            +
                  incoming.env["HTTP_AUTHORIZATION"] = request.to_auth_string
         | 
| 20 | 
            +
                  incoming.env["SERVER_PORT"] = request.uri.port
         | 
| 21 | 
            +
                  incoming.env['REQUEST_METHOD'] = request.http_method
         | 
| 22 22 | 
             
                  incoming
         | 
| 23 23 | 
             
                end
         | 
| 24 | 
            -
              
         | 
| 25 24 | 
             
              end
         | 
| 26 25 | 
             
            end
         | 
| @@ -1,5 +1,5 @@ | |
| 1 | 
            -
            require 'rubygems'
         | 
| 2 1 | 
             
            require 'active_support'
         | 
| 2 | 
            +
            require 'action_controller'
         | 
| 3 3 | 
             
            require 'action_controller/request'
         | 
| 4 4 | 
             
            require 'oauth/request_proxy/base'
         | 
| 5 5 | 
             
            require 'uri'
         | 
| @@ -25,7 +25,7 @@ module OAuth::RequestProxy | |
| 25 25 | 
             
                    params.merge(options[:parameters] || {})
         | 
| 26 26 | 
             
                  end
         | 
| 27 27 | 
             
                end
         | 
| 28 | 
            -
             | 
| 28 | 
            +
             | 
| 29 29 | 
             
                # Override from OAuth::RequestProxy::Base to avoid roundtrip
         | 
| 30 30 | 
             
                # conversion to Hash or Array and thus preserve the original
         | 
| 31 31 | 
             
                # parameter names
         | 
| @@ -36,19 +36,19 @@ module OAuth::RequestProxy | |
| 36 36 | 
             
                  unless options[:clobber_request]
         | 
| 37 37 | 
             
                    params << header_params.to_query
         | 
| 38 38 | 
             
                    params << request.query_string unless request.query_string.blank?
         | 
| 39 | 
            -
                    if request.content_type == Mime::Type.lookup("application/x-www-form-urlencoded")
         | 
| 40 | 
            -
                      params <<  | 
| 39 | 
            +
                    if request.post? && request.content_type == Mime::Type.lookup("application/x-www-form-urlencoded")
         | 
| 40 | 
            +
                      params << request.raw_post
         | 
| 41 41 | 
             
                    end
         | 
| 42 42 | 
             
                  end
         | 
| 43 | 
            -
             | 
| 43 | 
            +
             | 
| 44 44 | 
             
                  params.
         | 
| 45 45 | 
             
                    join('&').split('&').
         | 
| 46 | 
            -
                    reject { |kv| kv =~ /^oauth_signature=.*/}.
         | 
| 47 46 | 
             
                    reject(&:blank?).
         | 
| 48 | 
            -
                    map { |p| p.split('=') }
         | 
| 47 | 
            +
                    map { |p| p.split('=').map{|esc| CGI.unescape(esc)} }.
         | 
| 48 | 
            +
                    reject { |kv| kv[0] == 'oauth_signature'}
         | 
| 49 49 | 
             
                end
         | 
| 50 50 |  | 
| 51 | 
            -
             | 
| 51 | 
            +
              protected
         | 
| 52 52 |  | 
| 53 53 | 
             
                def query_params
         | 
| 54 54 | 
             
                  request.query_parameters
         |