rails3-opensocial 0.0.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/CHANGELOG.rdoc +1 -0
- data/LICENSE +202 -0
- data/NOTICE +60 -0
- data/README +99 -0
- data/Rakefile +0 -0
- data/lib/opensocial.rb +34 -0
- data/lib/opensocial/activity.rb +116 -0
- data/lib/opensocial/appdata.rb +117 -0
- data/lib/opensocial/auth/action_controller_request.rb +93 -0
- data/lib/opensocial/auth/base.rb +114 -0
- data/lib/opensocial/base.rb +53 -0
- data/lib/opensocial/connection.rb +132 -0
- data/lib/opensocial/group.rb +83 -0
- data/lib/opensocial/person.rb +201 -0
- data/lib/opensocial/request.rb +258 -0
- data/lib/opensocial/string/merb_string.rb +32 -0
- data/lib/opensocial/string/os_string.rb +23 -0
- metadata +113 -0
@@ -0,0 +1,117 @@
|
|
1
|
+
# Copyright (c) 2008 Google Inc.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
|
16
|
+
module OpenSocial #:nodoc:
|
17
|
+
|
18
|
+
# Acts as a wrapper for an OpenSocial appdata entry.
|
19
|
+
#
|
20
|
+
# The AppData class takes a person's ID and input JSON as initialization
|
21
|
+
# parameters, and iterates through each of the key/value pairs of that JSON.
|
22
|
+
# For each key that is found, an attr_accessor is constructed (except for
|
23
|
+
# :id which is preconstructed, and required), allowing direct access to the
|
24
|
+
# value. Each value is stored in the attr_accessor, either as a String,
|
25
|
+
# Fixnum, Hash, or Array.
|
26
|
+
#
|
27
|
+
|
28
|
+
|
29
|
+
class AppData < Base
|
30
|
+
attr_accessor :id
|
31
|
+
|
32
|
+
# Initializes the AppData entry based on the provided id and json fragment.
|
33
|
+
# If no JSON is provided, an empty object (with only an ID) is created.
|
34
|
+
def initialize(id, json)
|
35
|
+
@id = id
|
36
|
+
|
37
|
+
if json
|
38
|
+
json.each do |key, value|
|
39
|
+
begin
|
40
|
+
self.send("#{key}=", value)
|
41
|
+
rescue NoMethodError
|
42
|
+
add_attr(key)
|
43
|
+
self.send("#{key}=", value)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# Provides the ability to request a Collection of AppData for a given
|
51
|
+
# user or set of users.
|
52
|
+
#
|
53
|
+
# The FetchAppData wraps a simple request to an OpenSocial
|
54
|
+
# endpoint for a Collection of AppData. As parameters, it accepts
|
55
|
+
# a user ID and selector. This request may be used, standalone, by calling
|
56
|
+
# send, or bundled into an RpcRequest.
|
57
|
+
#
|
58
|
+
|
59
|
+
|
60
|
+
class FetchAppDataRequest < Request
|
61
|
+
# Defines the service fragment for use in constructing the request URL or
|
62
|
+
# JSON
|
63
|
+
SERVICE = 'appdata'
|
64
|
+
|
65
|
+
# Initializes a request to fetch appdata for the specified user and
|
66
|
+
# group, or the default (@me, @self). A valid Connection is not necessary
|
67
|
+
# if the request is to be used as part of an RpcRequest.
|
68
|
+
def initialize(connection = nil, guid = '@me', selector = '@self',
|
69
|
+
aid = '@app')
|
70
|
+
super(connection, guid, selector, aid)
|
71
|
+
end
|
72
|
+
|
73
|
+
# Sends the request, passing in the appropriate SERVICE and specified
|
74
|
+
# instance variables. Accepts an unescape parameter, defaulting to true,
|
75
|
+
# if the returned data should be unescaped.
|
76
|
+
def send(unescape = true)
|
77
|
+
json = send_request(SERVICE, @guid, @selector, @pid, unescape)
|
78
|
+
|
79
|
+
return parse_response(json['entry'])
|
80
|
+
end
|
81
|
+
|
82
|
+
# Selects the appropriate fragment from the JSON response in order to
|
83
|
+
# create a native object.
|
84
|
+
def parse_rpc_response(response)
|
85
|
+
return parse_response(response['data'])
|
86
|
+
end
|
87
|
+
|
88
|
+
# Converts the request into a JSON fragment that can be used as part of a
|
89
|
+
# larger RpcRequest.
|
90
|
+
def to_json(*a)
|
91
|
+
value = {
|
92
|
+
'method' => SERVICE + GET,
|
93
|
+
'params' => {
|
94
|
+
'userId' => ["#{@guid}"],
|
95
|
+
'groupId' => "#{@selector}",
|
96
|
+
'appId' => "#{@pid}",
|
97
|
+
'fields' => []
|
98
|
+
},
|
99
|
+
'id' => @key
|
100
|
+
}.to_json(*a)
|
101
|
+
end
|
102
|
+
|
103
|
+
private
|
104
|
+
|
105
|
+
# Converts the JSON response into a Collection of AppData entries, indexed
|
106
|
+
# by id.
|
107
|
+
def parse_response(response)
|
108
|
+
appdata = Collection.new
|
109
|
+
response.each do |key, value|
|
110
|
+
data = AppData.new(key, value)
|
111
|
+
appdata[key] = data
|
112
|
+
end
|
113
|
+
|
114
|
+
return appdata
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
# Copyright (c) 2007 Blaine Cook, Larry Halff, Pelle Braendgaard
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
# a copy of this software and associated documentation files (the
|
5
|
+
# "Software"), to deal in the Software without restriction, including
|
6
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
# the following conditions:
|
10
|
+
#
|
11
|
+
# The above copyright notice and this permission notice shall be
|
12
|
+
# included in all copies or substantial portions of the Software.
|
13
|
+
#
|
14
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
21
|
+
#
|
22
|
+
# Includes modifications by Robin Luckey from:
|
23
|
+
# http://github.com/robinluckey/oauth/tree/master/lib%2Foauth%2Frequest_proxy%2Faction_controller_request.rb
|
24
|
+
|
25
|
+
require 'rubygems'
|
26
|
+
require 'active_support'
|
27
|
+
require 'oauth/request_proxy/action_controller_request'
|
28
|
+
require 'uri'
|
29
|
+
|
30
|
+
module OAuth::RequestProxy #:nodoc: all
|
31
|
+
class ActionControllerRequest < OAuth::RequestProxy::Base
|
32
|
+
# proxies ActionController::AbstractRequest
|
33
|
+
if ActionController.const_defined?(:AbstractRequest)
|
34
|
+
proxies ActionController::AbstractRequest
|
35
|
+
else
|
36
|
+
proxies ActionController::Request
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
def method
|
41
|
+
request.method.to_s.upcase
|
42
|
+
end
|
43
|
+
|
44
|
+
def uri
|
45
|
+
uri = URI.parse(request.protocol + request.host + request.port_string + request.path)
|
46
|
+
uri.query = nil
|
47
|
+
uri.to_s
|
48
|
+
end
|
49
|
+
|
50
|
+
def parameters
|
51
|
+
if options[:clobber_request]
|
52
|
+
options[:parameters] || {}
|
53
|
+
else
|
54
|
+
params = request_params.merge(query_params).merge(header_params)
|
55
|
+
params.stringify_keys! if params.respond_to?(:stringify_keys!)
|
56
|
+
params.merge(options[:parameters] || {})
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# Override from OAuth::RequestProxy::Base to avoid roundtrip
|
61
|
+
# conversion to Hash or Array and thus preserve the original
|
62
|
+
# parameter names
|
63
|
+
def parameters_for_signature
|
64
|
+
params = []
|
65
|
+
params << options[:parameters].to_query if options[:parameters]
|
66
|
+
|
67
|
+
unless options[:clobber_request]
|
68
|
+
params << header_params.to_query
|
69
|
+
params << CGI.unescape(request.query_string) unless request.query_string.blank?
|
70
|
+
if request.content_type == Mime::Type.lookup("application/x-www-form-urlencoded")
|
71
|
+
params << CGI.unescape(request.raw_post)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
params.
|
76
|
+
join('&').split('&').
|
77
|
+
reject { |kv| kv =~ /^oauth_signature=.*/}.
|
78
|
+
reject(&:blank?).
|
79
|
+
map { |p| p.split('=') }
|
80
|
+
end
|
81
|
+
|
82
|
+
protected
|
83
|
+
|
84
|
+
def query_params
|
85
|
+
request.query_parameters
|
86
|
+
end
|
87
|
+
|
88
|
+
def request_params
|
89
|
+
request.request_parameters
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,114 @@
|
|
1
|
+
# Copyright (c) 2008 Google Inc.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
require 'rubygems'
|
16
|
+
require 'oauth'
|
17
|
+
require 'oauth/consumer'
|
18
|
+
|
19
|
+
|
20
|
+
module OpenSocial #:nodoc:
|
21
|
+
|
22
|
+
# Provides helper classes to be used in verifying and validating the user.
|
23
|
+
# In particular, support is provided for:
|
24
|
+
#
|
25
|
+
# * Verification of signed makeRequest using OAuth/HMAC-SHA1
|
26
|
+
# class ExampleController < ApplicationController
|
27
|
+
# OpenSocial::Auth::CONSUMER_KEY = '623061448914'
|
28
|
+
# OpenSocial::Auth::CONSUMER_SECRET = 'uynAeXiWTisflWX99KU1D2q5'
|
29
|
+
#
|
30
|
+
# include OpenSocial::Auth
|
31
|
+
#
|
32
|
+
# before_filter :validate
|
33
|
+
#
|
34
|
+
# def return_private_data
|
35
|
+
# end
|
36
|
+
# end
|
37
|
+
#
|
38
|
+
# * Request for an OAuth request token
|
39
|
+
#
|
40
|
+
# * Request for an OAuth access token, when supplied with a request token
|
41
|
+
#
|
42
|
+
|
43
|
+
|
44
|
+
module Auth
|
45
|
+
|
46
|
+
# Validates an incoming request by using the OAuth library and the supplied
|
47
|
+
# key and secret.
|
48
|
+
def validate(key = CONSUMER_KEY, secret = CONSUMER_SECRET)
|
49
|
+
consumer = OAuth::Consumer.new(key, secret)
|
50
|
+
begin
|
51
|
+
signature = OAuth::Signature.build(request) do
|
52
|
+
[nil, consumer.secret]
|
53
|
+
end
|
54
|
+
pass = signature.verify
|
55
|
+
rescue OAuth::Signature::UnknownSignatureMethod => e
|
56
|
+
logger.error 'An unknown signature method was supplied: ' + e.to_s
|
57
|
+
end
|
58
|
+
return pass
|
59
|
+
end
|
60
|
+
|
61
|
+
# Gets an OAuth request token, and redirects the user to authorize the app
|
62
|
+
# to access data on their behalf.
|
63
|
+
def get_oauth_token(key, secret, container, callback)
|
64
|
+
consumer = OAuth::Consumer.new(key, secret, {
|
65
|
+
:site => container[:base_uri],
|
66
|
+
:request_token_path => container[:request_token_path],
|
67
|
+
:authorize_path => container[:authorize_path],
|
68
|
+
:access_token_path => container[:access_token_path],
|
69
|
+
:http_method => container[:http_method]
|
70
|
+
})
|
71
|
+
request_token = consumer.get_request_token
|
72
|
+
|
73
|
+
session[:token] = request_token.token
|
74
|
+
session[:secret] = request_token.secret
|
75
|
+
|
76
|
+
redirect_to request_token.authorize_url + '&oauth_callback=' + CGI.escape(callback)
|
77
|
+
end
|
78
|
+
|
79
|
+
# If neccesary, swaps an existing request token and secret for an access
|
80
|
+
# token, storing it in the Connection class, and returning the access token
|
81
|
+
# and secret for later use.
|
82
|
+
def get_access_token(connection, token, secret)
|
83
|
+
if (token && secret)
|
84
|
+
consumer = OAuth::Consumer.new(connection.consumer_key,
|
85
|
+
connection.consumer_secret,
|
86
|
+
connection.container)
|
87
|
+
|
88
|
+
if connection.consumer_token.token.empty? &&
|
89
|
+
connection.consumer_token.secret.empty?
|
90
|
+
connection.consumer_token = OAuth::Token.new(token, secret)
|
91
|
+
|
92
|
+
uri = URI.parse(connection.container[:base_uri] +
|
93
|
+
connection.container[:access_token_path])
|
94
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
95
|
+
req = Net::HTTP::Get.new(uri.request_uri)
|
96
|
+
connection.sign!(http, req)
|
97
|
+
|
98
|
+
resp = http.get(req.path)
|
99
|
+
|
100
|
+
matches = resp.body.match(/oauth_token=(.*?)&oauth_token_secret=(.*)/)
|
101
|
+
access_token = matches[1]
|
102
|
+
access_secret = matches[2]
|
103
|
+
end
|
104
|
+
|
105
|
+
reusable_token = OAuth::AccessToken.new(consumer, access_token, access_secret)
|
106
|
+
connection.consumer_token = reusable_token
|
107
|
+
|
108
|
+
return access_token, access_secret
|
109
|
+
end
|
110
|
+
|
111
|
+
return nil, nil
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# Copyright (c) 2008 Google Inc.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
require 'net/http'
|
16
|
+
require 'uri'
|
17
|
+
|
18
|
+
# Use json/pure if you opt-out of including the validation code in
|
19
|
+
# opensocial/auth. This gem adds standard to_json behavior for the
|
20
|
+
# request classes, instead of using ActiveSupport.
|
21
|
+
require 'rubygems'
|
22
|
+
|
23
|
+
|
24
|
+
module OpenSocial #:nodoc:
|
25
|
+
|
26
|
+
# Provides base functionality for the OpenSocial child classes.
|
27
|
+
#
|
28
|
+
|
29
|
+
|
30
|
+
class Base
|
31
|
+
|
32
|
+
# Creates an attr_accessor for the specified variable name.
|
33
|
+
def add_attr(name)
|
34
|
+
self.class.class_eval "attr_accessor :#{name}"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# Wraps the functionality of an OpenSocial collection as defined by the
|
39
|
+
# specification. In practical uses, a Collection serves as a Hash (usually
|
40
|
+
# index by ID) with the added benefit of being convertable to an Array, when
|
41
|
+
# it's necessary to iterate over all of the values.
|
42
|
+
#
|
43
|
+
|
44
|
+
|
45
|
+
class Collection < Hash
|
46
|
+
|
47
|
+
# Converts the Collection to an Array by returning each of the values from
|
48
|
+
# key/value pairs.
|
49
|
+
def to_array
|
50
|
+
values
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,132 @@
|
|
1
|
+
# Copyright (c) 2008 Google Inc.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
require 'oauth/consumer'
|
16
|
+
|
17
|
+
|
18
|
+
module OpenSocial #:nodoc:
|
19
|
+
|
20
|
+
# Describes a connection to an OpenSocial container, including the ability to
|
21
|
+
# declare an authorization mechanism and appropriate credentials.
|
22
|
+
#
|
23
|
+
|
24
|
+
|
25
|
+
class Connection
|
26
|
+
ORKUT = { :endpoint => 'http://sandbox.orkut.com/social',
|
27
|
+
:rest => 'rest/',
|
28
|
+
:rpc => 'rpc/' }
|
29
|
+
IGOOGLE = { :endpoint => 'http://gmodules.com/api',
|
30
|
+
:rest => '',
|
31
|
+
:rpc => 'rpc' }
|
32
|
+
MYSPACE = { :endpoint => 'http://api.myspace.com/v2',
|
33
|
+
:rest => '',
|
34
|
+
:rpc => '',
|
35
|
+
:base_uri => 'http://api.myspace.com',
|
36
|
+
:request_token_path => '/request_token',
|
37
|
+
:authorize_path => '/authorize',
|
38
|
+
:access_token_path => '/access_token',
|
39
|
+
:http_method => :get }
|
40
|
+
|
41
|
+
AUTH_HMAC = 0
|
42
|
+
AUTH_ST = 1
|
43
|
+
|
44
|
+
DEFAULT_OPTIONS = { :container => ORKUT,
|
45
|
+
:st => '',
|
46
|
+
:consumer_key => '',
|
47
|
+
:consumer_secret => '',
|
48
|
+
:consumer_token => OAuth::Token.new('', ''),
|
49
|
+
:xoauth_requestor_id => '',
|
50
|
+
:auth => AUTH_HMAC }
|
51
|
+
|
52
|
+
# Defines the container that will be used in requests.
|
53
|
+
attr_accessor :container
|
54
|
+
|
55
|
+
# Defines the security token, for when OAuth is not in use.
|
56
|
+
attr_accessor :st
|
57
|
+
|
58
|
+
# Defines the consumer key for OAuth.
|
59
|
+
attr_accessor :consumer_key
|
60
|
+
|
61
|
+
# Defines the consumer secret for OAuth.
|
62
|
+
attr_accessor :consumer_secret
|
63
|
+
|
64
|
+
# Defines the consumer token for OAuth.
|
65
|
+
attr_accessor :consumer_token
|
66
|
+
|
67
|
+
# Defines the ID of the requestor (required by some implementations when
|
68
|
+
# using OAuth).
|
69
|
+
attr_accessor :xoauth_requestor_id
|
70
|
+
|
71
|
+
# Defines the authentication scheme: HMAC or security token.
|
72
|
+
attr_accessor :auth
|
73
|
+
|
74
|
+
# Initializes the Connection using the supplied options hash, or the
|
75
|
+
# defaults. Verifies that the supplied authentication type has proper
|
76
|
+
# (ie. non-blank) credentials, and that the authentication type is known.
|
77
|
+
def initialize(options = {})
|
78
|
+
options = DEFAULT_OPTIONS.merge(options)
|
79
|
+
options.each do |key, value|
|
80
|
+
self.send("#{key}=", value)
|
81
|
+
end
|
82
|
+
|
83
|
+
if @auth == AUTH_HMAC && !has_valid_hmac_double?
|
84
|
+
raise ArgumentError.new('Connection authentication is set to ' +
|
85
|
+
'HMAC-SHA1, but a valid consumer_key and' +
|
86
|
+
'secret pair was not supplied.')
|
87
|
+
elsif @auth == AUTH_ST && @st.empty?
|
88
|
+
raise ArgumentError.new('Connection authentication is set to ' +
|
89
|
+
'security token, but a security token was ' +
|
90
|
+
'not supplied.')
|
91
|
+
elsif ![AUTH_HMAC, AUTH_ST].include?(@auth)
|
92
|
+
raise ArgumentError.new('Connection authentication is set to an ' +
|
93
|
+
'unknown value.')
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
# Constructs a URI to the OpenSocial endpoint given a service, guid,
|
98
|
+
# selector, and pid.
|
99
|
+
def service_uri(service, guid, selector, pid, extra_fields = {})
|
100
|
+
uri = [@container[:endpoint], service, guid, selector, pid].compact.
|
101
|
+
join('/')
|
102
|
+
|
103
|
+
if @auth == AUTH_HMAC && !xoauth_requestor_id.empty?
|
104
|
+
uri << '?xoauth_requestor_id=' + @xoauth_requestor_id
|
105
|
+
elsif @auth == AUTH_ST
|
106
|
+
uri << '?st=' + self.st
|
107
|
+
end
|
108
|
+
|
109
|
+
extra_fields.each do |name, value|
|
110
|
+
uri << "&#{name}=#{value}"
|
111
|
+
end
|
112
|
+
|
113
|
+
URI.parse(uri)
|
114
|
+
end
|
115
|
+
|
116
|
+
# Signs a request using OAuth.
|
117
|
+
def sign!(http, req)
|
118
|
+
if @auth == AUTH_HMAC
|
119
|
+
consumer = OAuth::Consumer.new(@consumer_key, @consumer_secret)
|
120
|
+
req.oauth!(http, consumer, @consumer_token, :scheme => 'query_string')
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
private
|
125
|
+
|
126
|
+
# Verifies that the consumer key, consumer secret and requestor id are all
|
127
|
+
# non-blank.
|
128
|
+
def has_valid_hmac_double?
|
129
|
+
return (!@consumer_key.empty? && !@consumer_secret.empty?)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|