opensocial 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +202 -0
- data/NOTICE +60 -0
- data/README +108 -0
- data/lib/opensocial.rb +29 -0
- data/lib/opensocial/activity.rb +116 -0
- data/lib/opensocial/appdata.rb +117 -0
- data/lib/opensocial/auth/action_controller_request.rb +87 -0
- data/lib/opensocial/auth/base.rb +114 -0
- data/lib/opensocial/base.rb +54 -0
- data/lib/opensocial/connection.rb +146 -0
- data/lib/opensocial/group.rb +83 -0
- data/lib/opensocial/person.rb +198 -0
- data/lib/opensocial/request.rb +273 -0
- data/lib/opensocial/string/merb_string.rb +32 -0
- data/lib/opensocial/string/os_string.rb +23 -0
- data/tests/activity_test.rb +107 -0
- data/tests/appdata_test.rb +59 -0
- data/tests/connection_test.rb +54 -0
- data/tests/fixtures/activities.json +28 -0
- data/tests/fixtures/activity.json +13 -0
- data/tests/fixtures/appdata.json +6 -0
- data/tests/fixtures/appdatum.json +5 -0
- data/tests/fixtures/group.json +7 -0
- data/tests/fixtures/groups.json +16 -0
- data/tests/fixtures/people.json +20 -0
- data/tests/fixtures/person.json +9 -0
- data/tests/fixtures/person_appdata_rpc.json +1 -0
- data/tests/fixtures/person_rpc.json +1 -0
- data/tests/group_test.rb +72 -0
- data/tests/online_test.rb +56 -0
- data/tests/person_test.rb +109 -0
- data/tests/request_test.rb +51 -0
- data/tests/rpcrequest_test.rb +95 -0
- data/tests/test.rb +41 -0
- data/tests/test_helper.rb +39 -0
- metadata +129 -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,87 @@
|
|
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
|
+
|
34
|
+
def method
|
35
|
+
request.method.to_s.upcase
|
36
|
+
end
|
37
|
+
|
38
|
+
def uri
|
39
|
+
uri = URI.parse(request.protocol + request.host + request.port_string + request.path)
|
40
|
+
uri.query = nil
|
41
|
+
uri.to_s
|
42
|
+
end
|
43
|
+
|
44
|
+
def parameters
|
45
|
+
if options[:clobber_request]
|
46
|
+
options[:parameters] || {}
|
47
|
+
else
|
48
|
+
params = request_params.merge(query_params).merge(header_params)
|
49
|
+
params.stringify_keys! if params.respond_to?(:stringify_keys!)
|
50
|
+
params.merge(options[:parameters] || {})
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
# Override from OAuth::RequestProxy::Base to avoid roundtrip
|
55
|
+
# conversion to Hash or Array and thus preserve the original
|
56
|
+
# parameter names
|
57
|
+
def parameters_for_signature
|
58
|
+
params = []
|
59
|
+
params << options[:parameters].to_query if options[:parameters]
|
60
|
+
|
61
|
+
unless options[:clobber_request]
|
62
|
+
params << header_params.to_query
|
63
|
+
params << CGI.unescape(request.query_string) unless request.query_string.blank?
|
64
|
+
if request.content_type == Mime::Type.lookup("application/x-www-form-urlencoded")
|
65
|
+
params << CGI.unescape(request.raw_post)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
params.
|
70
|
+
join('&').split('&').
|
71
|
+
reject { |kv| kv =~ /^oauth_signature=.*/}.
|
72
|
+
reject(&:blank?).
|
73
|
+
map { |p| p.split('=') }
|
74
|
+
end
|
75
|
+
|
76
|
+
protected
|
77
|
+
|
78
|
+
def query_params
|
79
|
+
request.query_parameters
|
80
|
+
end
|
81
|
+
|
82
|
+
def request_params
|
83
|
+
request.request_parameters
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
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,54 @@
|
|
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
|
+
require 'json/add/rails'
|
23
|
+
|
24
|
+
|
25
|
+
module OpenSocial #:nodoc:
|
26
|
+
|
27
|
+
# Provides base functionality for the OpenSocial child classes.
|
28
|
+
#
|
29
|
+
|
30
|
+
|
31
|
+
class Base
|
32
|
+
|
33
|
+
# Creates an attr_accessor for the specified variable name.
|
34
|
+
def add_attr(name)
|
35
|
+
self.class.class_eval "attr_accessor :#{name}"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# Wraps the functionality of an OpenSocial collection as defined by the
|
40
|
+
# specification. In practical uses, a Collection serves as a Hash (usually
|
41
|
+
# index by ID) with the added benefit of being convertable to an Array, when
|
42
|
+
# it's necessary to iterate over all of the values.
|
43
|
+
#
|
44
|
+
|
45
|
+
|
46
|
+
class Collection < Hash
|
47
|
+
|
48
|
+
# Converts the Collection to an Array by returning each of the values from
|
49
|
+
# key/value pairs.
|
50
|
+
def to_array
|
51
|
+
values
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,146 @@
|
|
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
|
+
:content_type => 'application/json',
|
30
|
+
:post_body_signing => false,
|
31
|
+
:use_request_body_hash => true }
|
32
|
+
IGOOGLE = { :endpoint => 'http://www-opensocial-sandbox.googleusercontent.com/api',
|
33
|
+
:rest => '',
|
34
|
+
:rpc => 'rpc',
|
35
|
+
:content_type => 'application/json',
|
36
|
+
:post_body_signing => false,
|
37
|
+
:use_request_body_hash => true }
|
38
|
+
MYSPACE = { :endpoint => 'http://api.myspace.com/v2',
|
39
|
+
:rest => '',
|
40
|
+
:rpc => '',
|
41
|
+
:base_uri => 'http://api.myspace.com',
|
42
|
+
:request_token_path => '/request_token',
|
43
|
+
:authorize_path => '/authorize',
|
44
|
+
:access_token_path => '/access_token',
|
45
|
+
:http_method => :get,
|
46
|
+
:content_type => 'application/x-www-form-urlencoded',
|
47
|
+
:post_body_signing => true,
|
48
|
+
:use_request_body_hash => false }
|
49
|
+
|
50
|
+
AUTH_HMAC = 0
|
51
|
+
AUTH_ST = 1
|
52
|
+
|
53
|
+
DEFAULT_OPTIONS = { :container => ORKUT,
|
54
|
+
:st => '',
|
55
|
+
:consumer_key => '',
|
56
|
+
:consumer_secret => '',
|
57
|
+
:consumer_token => OAuth::Token.new('', ''),
|
58
|
+
:xoauth_requestor_id => '',
|
59
|
+
:auth => AUTH_HMAC }
|
60
|
+
|
61
|
+
# Defines the container that will be used in requests.
|
62
|
+
attr_accessor :container
|
63
|
+
|
64
|
+
# Defines the security token, for when OAuth is not in use.
|
65
|
+
attr_accessor :st
|
66
|
+
|
67
|
+
# Defines the consumer key for OAuth.
|
68
|
+
attr_accessor :consumer_key
|
69
|
+
|
70
|
+
# Defines the consumer secret for OAuth.
|
71
|
+
attr_accessor :consumer_secret
|
72
|
+
|
73
|
+
# Defines the consumer token for OAuth.
|
74
|
+
attr_accessor :consumer_token
|
75
|
+
|
76
|
+
# Defines the ID of the requestor (required by some implementations when
|
77
|
+
# using OAuth).
|
78
|
+
attr_accessor :xoauth_requestor_id
|
79
|
+
|
80
|
+
# Defines the authentication scheme: HMAC or security token.
|
81
|
+
attr_accessor :auth
|
82
|
+
|
83
|
+
# Defines the content-type when sending a request body
|
84
|
+
attr_accessor :content_type
|
85
|
+
|
86
|
+
# Defines whether or not to sign the request body (treating the body as a
|
87
|
+
# large query parameter for the purposes of the signature base string)
|
88
|
+
attr_accessor :post_body_signing
|
89
|
+
|
90
|
+
# Defines whether or not to sign the body using a request body hash
|
91
|
+
attr_accessor :use_request_body_hash
|
92
|
+
|
93
|
+
# Initializes the Connection using the supplied options hash, or the
|
94
|
+
# defaults. Verifies that the supplied authentication type has proper
|
95
|
+
# (ie. non-blank) credentials, and that the authentication type is known.
|
96
|
+
def initialize(options = {})
|
97
|
+
options = DEFAULT_OPTIONS.merge(options)
|
98
|
+
options.each do |key, value|
|
99
|
+
self.send("#{key}=", value)
|
100
|
+
end
|
101
|
+
|
102
|
+
if @auth == AUTH_HMAC && !has_valid_hmac_double?
|
103
|
+
raise ArgumentError.new('Connection authentication is set to ' +
|
104
|
+
'HMAC-SHA1, but a valid consumer_key and' +
|
105
|
+
'secret pair was not supplied.')
|
106
|
+
elsif @auth == AUTH_ST && @st.empty?
|
107
|
+
raise ArgumentError.new('Connection authentication is set to ' +
|
108
|
+
'security token, but a security token was ' +
|
109
|
+
'not supplied.')
|
110
|
+
elsif ![AUTH_HMAC, AUTH_ST].include?(@auth)
|
111
|
+
raise ArgumentError.new('Connection authentication is set to an ' +
|
112
|
+
'unknown value.')
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
# Constructs a URI to the OpenSocial endpoint given a service, guid,
|
117
|
+
# selector, and pid.
|
118
|
+
def service_uri(service, guid, selector, pid)
|
119
|
+
uri = [@container[:endpoint], service, guid, selector, pid].compact.
|
120
|
+
join('/')
|
121
|
+
|
122
|
+
if @auth == AUTH_HMAC && !xoauth_requestor_id.empty?
|
123
|
+
uri << '?xoauth_requestor_id=' + @xoauth_requestor_id
|
124
|
+
elsif @auth == AUTH_ST
|
125
|
+
uri << '?st=' + self.st
|
126
|
+
end
|
127
|
+
URI.parse(uri)
|
128
|
+
end
|
129
|
+
|
130
|
+
# Signs a request using OAuth.
|
131
|
+
def sign!(http, req)
|
132
|
+
if @auth == AUTH_HMAC
|
133
|
+
consumer = OAuth::Consumer.new(@consumer_key, @consumer_secret)
|
134
|
+
req.oauth!(http, consumer, nil, :scheme => 'query_string')
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
private
|
139
|
+
|
140
|
+
# Verifies that the consumer key, consumer secret and requestor id are all
|
141
|
+
# non-blank.
|
142
|
+
def has_valid_hmac_double?
|
143
|
+
return (!@consumer_key.empty? && !@consumer_secret.empty?)
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|