Class: OAuth::Consumer

Inherits:
Object
  • Object
show all
Defined in:
lib/oauth/consumer.rb

Constant Summary collapse

CA_FILES =

determine the certificate authority path to verify SSL certs

%w(/etc/ssl/certs/ca-certificates.crt /usr/share/curl/curl-ca-bundle.crt)
CA_FILE =
nil
@@default_options =
{
  # Signature method used by server. Defaults to HMAC-SHA1
  :signature_method   => 'HMAC-SHA1',
   # default paths on site. These are the same as the defaults set up by the generators
  :request_token_path => '/oauth/request_token',
  :authorize_path     => '/oauth/authorize',
  :access_token_path  => '/oauth/access_token',
   :proxy              => nil,
  # How do we send the oauth values to the server see
  # http://oauth.net/core/1.0/#consumer_req_param for more info
  #
  # Possible values:
  #
  #   :header - via the Authorize header (Default) ( option 1. in spec)
  #   :body - url form encoded in body of POST request ( option 2. in spec)
  #   :query_string - via the query part of the url ( option 3. in spec)
  :scheme        => :header,
   # Default http method used for OAuth Token Requests (defaults to :post)
  :http_method   => :post,
  
  # Add a custom ca_file for consumer
  # :ca_file       => '/etc/certs.pem'
   :oauth_version => "1.0"
}

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(consumer_key, consumer_secret, options = {}) ⇒ Consumer

Create a new consumer instance by passing it a configuration hash:

@consumer = OAuth::Consumer.new(key, secret, {
  :site               => "http://term.ie",
  :scheme             => :header,
  :http_method        => :post,
  :request_token_path => "/oauth/example/request_token.php",
  :access_token_path  => "/oauth/example/access_token.php",
  :authorize_path     => "/oauth/example/authorize.php"
 })

Start the process by requesting a token

@request_token = @consumer.get_request_token
session[:request_token] = @request_token
redirect_to @request_token.authorize_url

When user returns create an access_token

@access_token = @request_token.get_access_token
@photos=@access_token.get('/photos.xml')


73
74
75
76
77
78
79
80
81
82
# File 'lib/oauth/consumer.rb', line 73

def initialize(consumer_key, consumer_secret, options = {})
  @key    = consumer_key
  @secret = consumer_secret

  # ensure that keys are symbols
  @options = @@default_options.merge(options.inject({}) { |options, (key, value)|
    options[key.to_sym] = value
    options
  })
end

Instance Attribute Details

#httpObject

The HTTP object for the site. The HTTP Object is what you get when you do Net::HTTP.new



90
91
92
# File 'lib/oauth/consumer.rb', line 90

def http
  @http ||= create_http
end

#keyObject

Returns the value of attribute key.



48
49
50
# File 'lib/oauth/consumer.rb', line 48

def key
  @key
end

#optionsObject

Returns the value of attribute options.



48
49
50
# File 'lib/oauth/consumer.rb', line 48

def options
  @options
end

#secretObject

Returns the value of attribute secret.



48
49
50
# File 'lib/oauth/consumer.rb', line 48

def secret
  @secret
end

#siteObject



216
217
218
# File 'lib/oauth/consumer.rb', line 216

def site
  @options[:site].to_s
end

Instance Method Details

#access_token_pathObject



232
233
234
# File 'lib/oauth/consumer.rb', line 232

def access_token_path
  @options[:access_token_path]
end

#access_token_urlObject



253
254
255
# File 'lib/oauth/consumer.rb', line 253

def access_token_url
  @options[:access_token_url] || site + access_token_path
end

#access_token_url?Boolean

Returns:

  • (Boolean)


257
258
259
# File 'lib/oauth/consumer.rb', line 257

def access_token_url?
  @options.has_key?(:access_token_url)
end

#authorize_pathObject



228
229
230
# File 'lib/oauth/consumer.rb', line 228

def authorize_path
  @options[:authorize_path]
end

#authorize_urlObject



245
246
247
# File 'lib/oauth/consumer.rb', line 245

def authorize_url
  @options[:authorize_url] || site + authorize_path
end

#authorize_url?Boolean

Returns:

  • (Boolean)


249
250
251
# File 'lib/oauth/consumer.rb', line 249

def authorize_url?
  @options.has_key?(:authorize_url)
end

#create_signed_request(http_method, path, token = nil, request_options = {}, *arguments) ⇒ Object

Creates and signs an http request. It’s recommended to use the Token classes to set this up correctly



175
176
177
178
179
# File 'lib/oauth/consumer.rb', line 175

def create_signed_request(http_method, path, token = nil, request_options = {}, *arguments)
  request = create_http_request(http_method, path, *arguments)
  sign!(request, token, request_options)
  request
end

#get_access_token(request_token, request_options = {}, *arguments) ⇒ Object



104
105
106
107
# File 'lib/oauth/consumer.rb', line 104

def get_access_token(request_token, request_options = {}, *arguments)
  response = token_request(http_method, (access_token_url? ? access_token_url : access_token_path), request_token, request_options, *arguments)
  OAuth::AccessToken.from_hash(self, response)
end

#get_request_token(request_options = {}, *arguments) ⇒ Object

Makes a request to the service for a new OAuth::RequestToken

@request_token = @consumer.get_request_token

To include OAuth parameters:

@request_token = @consumer.get_request_token \
  :oauth_callback => "http://example.com/cb"

To include application-specific parameters:

@request_token = @consumer.get_request_token({}, :foo => "bar")

TODO oauth_callback should be a mandatory parameter



123
124
125
126
127
128
129
130
# File 'lib/oauth/consumer.rb', line 123

def get_request_token(request_options = {}, *arguments)
  # if oauth_callback wasn't provided, it is assumed that oauth_verifiers
  # will be exchanged out of band
  request_options[:oauth_callback] ||= OAuth::OUT_OF_BAND

  response = token_request(http_method, (request_token_url? ? request_token_url : request_token_path), nil, request_options, *arguments)
  OAuth::RequestToken.from_hash(self, response)
end

#http_methodObject

The default http method



85
86
87
# File 'lib/oauth/consumer.rb', line 85

def http_method
  @http_method ||= @options[:http_method] || :post
end

#proxyObject



261
262
263
# File 'lib/oauth/consumer.rb', line 261

def proxy
  @options[:proxy]
end

#request(http_method, path, token = nil, request_options = {}, *arguments) ⇒ Object

Creates, signs and performs an http request. It’s recommended to use the OAuth::Token classes to set this up correctly. request_options take precedence over consumer-wide options when signing

a request.

arguments are POST and PUT bodies (a Hash, string-encoded parameters, or

absent), followed by additional HTTP headers.

@consumer.request(:get,  '/people', @token, { :scheme => :query_string })
@consumer.request(:post, '/people', @token, {}, @person.to_xml, { 'Content-Type' => 'application/xml' })


142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
# File 'lib/oauth/consumer.rb', line 142

def request(http_method, path, token = nil, request_options = {}, *arguments)
  if path !~ /^\//
    @http = create_http(path)
    _uri = URI.parse(path)
    path = "#{_uri.path}#{_uri.query ? "?#{_uri.query}" : ""}"
  end

  rsp = http.request(create_signed_request(http_method, path, token, request_options, *arguments))

  # check for an error reported by the Problem Reporting extension
  # (http://wiki.oauth.net/ProblemReporting)
  # note: a 200 may actually be an error; check for an oauth_problem key to be sure
  if !(headers = rsp.to_hash["www-authenticate"]).nil? &&
    (h = headers.select { |h| h =~ /^OAuth / }).any? &&
    h.first =~ /oauth_problem/

    # puts "Header: #{h.first}"

    # TODO doesn't handle broken responses from api.login.yahoo.com
    # remove debug code when done
    params = OAuth::Helper.parse_header(h.first)

    # puts "Params: #{params.inspect}"
    # puts "Body: #{rsp.body}"

    raise OAuth::Problem.new(params.delete("oauth_problem"), rsp, params)
  end

  rsp
end

#request_token_pathObject



224
225
226
# File 'lib/oauth/consumer.rb', line 224

def request_token_path
  @options[:request_token_path]
end

#request_token_urlObject

TODO this is ugly, rewrite



237
238
239
# File 'lib/oauth/consumer.rb', line 237

def request_token_url
  @options[:request_token_url] || site + request_token_path
end

#request_token_url?Boolean

Returns:

  • (Boolean)


241
242
243
# File 'lib/oauth/consumer.rb', line 241

def request_token_url?
  @options.has_key?(:request_token_url)
end

#schemeObject



220
221
222
# File 'lib/oauth/consumer.rb', line 220

def scheme
  @options[:scheme]
end

#sign!(request, token = nil, request_options = {}) ⇒ Object

Sign the Request object. Use this if you have an externally generated http request object you want to sign.



207
208
209
# File 'lib/oauth/consumer.rb', line 207

def sign!(request, token = nil, request_options = {})
  request.oauth!(http, self, token, options.merge(request_options))
end

#signature_base_string(request, token = nil, request_options = {}) ⇒ Object

Return the signature_base_string



212
213
214
# File 'lib/oauth/consumer.rb', line 212

def signature_base_string(request, token = nil, request_options = {})
  request.signature_base_string(http, self, token, options.merge(request_options))
end

#token_request(http_method, path, token = nil, request_options = {}, *arguments) ⇒ Object

Creates a request and parses the result as url_encoded. This is used internally for the RequestToken and AccessToken requests.



182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
# File 'lib/oauth/consumer.rb', line 182

def token_request(http_method, path, token = nil, request_options = {}, *arguments)
  response = request(http_method, path, token, request_options, *arguments)

  case response.code.to_i

  when (200..299)
    # symbolize keys
    # TODO this could be considered unexpected behavior; symbols or not?
    # TODO this also drops subsequent values from multi-valued keys
    CGI.parse(response.body).inject({}) do |h,(k,v)|
      h[k.to_sym] = v.first
      h[k]        = v.first
      h
    end
  when (300..399)
    # this is a redirect
    response.error!
  when (400..499)
    raise OAuth::Unauthorized, response
  else
    response.error!
  end
end

#uri(custom_uri = nil) ⇒ Object

Contains the root URI for this site



95
96
97
98
99
100
101
102
# File 'lib/oauth/consumer.rb', line 95

def uri(custom_uri = nil)
  if custom_uri
    @uri  = custom_uri
    @http = create_http # yike, oh well. less intrusive this way
  else  # if no custom passed, we use existing, which, if unset, is set to site uri
    @uri ||= URI.parse(site)
  end
end