koala 1.2.0beta2 → 1.2.0beta3

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -5,7 +5,9 @@ New methods:
5
5
  -- TestUsers#update lets you update the name or password of an existing test user
6
6
  -- API.get_page_access_token lets you easily fetch the access token for a page you manage (thanks, marcgg!)
7
7
  Updated methods:
8
+ -- OAuth now parses Facebook's new signed cookie format
8
9
  -- API.put_picture now accepts URLs to images (thanks, marcgg!)
10
+ -- Bug fixes to put_picture, parse_signed_request, and the test suite (thanks, johnbhall and Will S.!)
9
11
  Internal improvements:
10
12
  -- Koala now uses Faraday to make requests, replacing the HTTPServices (see wiki)
11
13
  -- Koala::HTTPService.http_options allows specification of default Faraday connection options
data/koala.gemspec CHANGED
@@ -2,8 +2,8 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{koala}
5
- s.version = "1.2.0beta2"
6
- s.date = %q{2011-08-23}
5
+ s.version = "1.2.0beta3"
6
+ s.date = %q{2011-09-12}
7
7
 
8
8
  s.summary = %q{A lightweight, flexible library for Facebook with support for the Graph API, the REST API, realtime updates, and OAuth authentication.}
9
9
  s.description = %q{Koala is a lightweight, flexible Ruby SDK for Facebook. It allows read/write access to the social graph via the Graph and REST APIs, as well as support for realtime updates and OAuth and Facebook Connect authentication. Koala is fully tested and supports Net::HTTP and Typhoeus connections out of the box and can accept custom modules for other services.}
data/lib/koala/oauth.rb CHANGED
@@ -9,31 +9,18 @@ module Koala
9
9
  end
10
10
 
11
11
  def get_user_info_from_cookie(cookie_hash)
12
- # Parses the cookie set by the official Facebook JavaScript SDK.
13
- #
14
- # cookies should be a Hash, like the one Rails provides
12
+ # Parses the cookie set Facebook's JavaScript SDK.
13
+ # You can pass Rack/Rails/Sinatra's cookie hash directly to this method.
15
14
  #
16
15
  # If the user is logged in via Facebook, we return a dictionary with the
17
16
  # keys "uid" and "access_token". The former is the user's Facebook ID,
18
17
  # and the latter can be used to make authenticated requests to the Graph API.
19
18
  # If the user is not logged in, we return None.
20
- #
21
- # Download the official Facebook JavaScript SDK at
22
- # http://github.com/facebook/connect-js/. Read more about Facebook
23
- # authentication at http://developers.facebook.com/docs/authentication/.
24
-
25
- if fb_cookie = cookie_hash["fbs_" + @app_id.to_s]
26
- # remove the opening/closing quote
27
- fb_cookie = fb_cookie.gsub(/\"/, "")
28
-
29
- # since we no longer get individual cookies, we have to separate out the components ourselves
30
- components = {}
31
- fb_cookie.split("&").map {|param| param = param.split("="); components[param[0]] = param[1]}
32
-
33
- # generate the signature and make sure it matches what we expect
34
- auth_string = components.keys.sort.collect {|a| a == "sig" ? nil : "#{a}=#{components[a]}"}.reject {|a| a.nil?}.join("")
35
- sig = Digest::MD5.hexdigest(auth_string + @app_secret)
36
- sig == components["sig"] && (components["expires"] == "0" || Time.now.to_i < components["expires"].to_i) ? components : nil
19
+
20
+ if signed_cookie = cookie_hash["fbsr_#{@app_id}"]
21
+ parse_signed_cookie(signed_cookie)
22
+ elsif unsigned_cookie = cookie_hash["fbs_#{@app_id}"]
23
+ parse_unsigned_cookie(unsigned_cookie)
37
24
  end
38
25
  end
39
26
  alias_method :get_user_info_from_cookies, :get_user_info_from_cookie
@@ -70,7 +57,7 @@ module Koala
70
57
  def get_access_token_info(code, options = {})
71
58
  # convenience method to get a parsed token from Facebook for a given code
72
59
  # should this require an OAuth callback URL?
73
- get_token_from_server({:code => code, :redirect_uri => @oauth_callback_url}, false, options)
60
+ get_token_from_server({:code => code, :redirect_uri => options[:redirect_uri] || @oauth_callback_url}, false, options)
74
61
  end
75
62
 
76
63
  def get_access_token(code, options = {})
@@ -104,7 +91,7 @@ module Koala
104
91
  raise "SignedRequest: Unsupported algorithm #{envelope['algorithm']}" if envelope['algorithm'] != 'HMAC-SHA256'
105
92
 
106
93
  # now see if the signature is valid (digest, key, data)
107
- hmac = OpenSSL::HMAC.hexdigest(OpenSSL::Digest::SHA256.new, @app_secret, encoded_envelope.tr("-_", "+/"))
94
+ hmac = OpenSSL::HMAC.hexdigest(OpenSSL::Digest::SHA256.new, @app_secret, encoded_envelope)
108
95
  raise 'SignedRequest: Invalid signature' if (signature != hmac)
109
96
 
110
97
  return envelope
@@ -162,6 +149,29 @@ module Koala
162
149
  end
163
150
  components
164
151
  end
152
+
153
+ def parse_unsigned_cookie(fb_cookie)
154
+ # remove the opening/closing quote
155
+ fb_cookie = fb_cookie.gsub(/\"/, "")
156
+
157
+ # since we no longer get individual cookies, we have to separate out the components ourselves
158
+ components = {}
159
+ fb_cookie.split("&").map {|param| param = param.split("="); components[param[0]] = param[1]}
160
+
161
+ # generate the signature and make sure it matches what we expect
162
+ auth_string = components.keys.sort.collect {|a| a == "sig" ? nil : "#{a}=#{components[a]}"}.reject {|a| a.nil?}.join("")
163
+ sig = Digest::MD5.hexdigest(auth_string + @app_secret)
164
+ sig == components["sig"] && (components["expires"] == "0" || Time.now.to_i < components["expires"].to_i) ? components : nil
165
+ end
166
+
167
+ def parse_signed_cookie(fb_cookie)
168
+ components = parse_signed_request(fb_cookie)
169
+ if (code = components["code"]) && token_info = get_access_token_info(code, :redirect_uri => '')
170
+ components.merge(token_info)
171
+ else
172
+ nil
173
+ end
174
+ end
165
175
 
166
176
  def fetch_token_string(args, post = false, endpoint = "access_token", options = {})
167
177
  Koala.make_request("/oauth/#{endpoint}", {
@@ -40,7 +40,8 @@ module Koala
40
40
  :parse_rails_3_param,
41
41
  :parse_sinatra_param,
42
42
  :parse_file_object,
43
- :parse_string_path
43
+ :parse_string_path,
44
+ :parse_io
44
45
  ]
45
46
 
46
47
  def parse_init_mixed_param(mixed, content_type = nil)
data/readme.md CHANGED
@@ -25,8 +25,12 @@ Or in Bundler:
25
25
  Graph API
26
26
  ----
27
27
  The Graph API is the simple, slick new interface to Facebook's data. Using it with Koala is quite straightforward:
28
-
28
+
29
+ # 1.2beta and above
29
30
  @graph = Koala::Facebook::API.new(oauth_access_token)
31
+ # 1.1 or earlier
32
+ @graph = Koala::Facebook::GraphAPI.new(oauth_access_token)
33
+
30
34
  profile = @graph.get_object("me")
31
35
  friends = @graph.get_connections("me", "friends")
32
36
  @graph.put_object("me", "feed", :message => "I am writing on my wall!")
@@ -61,13 +65,22 @@ Where the Graph API and the old REST API overlap, you should choose the Graph AP
61
65
 
62
66
  Fortunately, Koala supports the REST API using the very same interface; to use this, instantiate an API:
63
67
 
64
- @rest = Koala::Facebook::API.new(oauth_access_token)
68
+ # 1.2beta and above
69
+ @rest = Koala::Facebook::API.new(oauth_access_token)
70
+ # 1.1 or earlier
71
+ @rest = Koala::Facebook::RestAPI.new(oauth_access_token)
72
+
65
73
  @rest.fql_query(my_fql_query) # convenience method
66
74
  @rest.fql_multiquery(fql_query_hash) # convenience method
67
75
  @rest.rest_call("stream.publish", arguments_hash) # generic version
68
76
 
69
77
  Of course, you can use the Graph API methods on the same object -- the power of two APIs right in the palm of your hand.
70
78
 
79
+ # 1.2beta and above
80
+ @api = Koala::Facebook::API.new(oauth_access_token)
81
+ # 1.1 or earlier
82
+ @api = Koala::Facebook::GraphAndRestAPI.new(oauth_access_token)
83
+
71
84
  @api = Koala::Facebook::API.new(oauth_access_token)
72
85
  fql = @api.fql_query(my_fql_query)
73
86
  @api.put_wall_post(process_result(fql))
@@ -35,14 +35,14 @@ describe "Koala" do
35
35
  end
36
36
  end
37
37
 
38
- define "make_request" do
38
+ describe "make_request" do
39
39
  it "passes all its arguments to the http_service" do
40
- http_service = stub("http_service")
41
40
  path = "foo"
42
41
  args = {:a => 2}
43
42
  verb = "get"
44
43
  options = {:c => :d}
45
- http_service.should_receive(:make_request).with(path, args, verb, options)
44
+
45
+ Koala.http_service.should_receive(:make_request).with(path, args, verb, options)
46
46
  Koala.make_request(path, args, verb, options)
47
47
  end
48
48
  end
@@ -53,40 +53,107 @@ describe "Koala::Facebook::OAuth" do
53
53
 
54
54
  describe "for cookie parsing" do
55
55
  describe "get_user_info_from_cookies" do
56
- it "should properly parse valid cookies" do
57
- result = @oauth.get_user_info_from_cookies(KoalaTest.oauth_test_data["valid_cookies"])
58
- result.should be_a(Hash)
59
- end
56
+ context "for signed cookies" do
57
+ before :each do
58
+ # we don't actually want to make requests to Facebook to redeem the code
59
+ @cookie = KoalaTest.oauth_test_data["valid_signed_cookies"]
60
+ @token = "my token"
61
+ @oauth.stub(:get_access_token_info).and_return("access_token" => @token)
62
+ end
63
+
64
+ it "parses valid cookies" do
65
+ result = @oauth.get_user_info_from_cookies(@cookie)
66
+ result.should be_a(Hash)
67
+ end
60
68
 
61
- it "should return all the cookie components from valid cookie string" do
62
- cookie_data = KoalaTest.oauth_test_data["valid_cookies"]
63
- parsing_results = @oauth.get_user_info_from_cookies(cookie_data)
64
- number_of_components = cookie_data["fbs_#{@app_id.to_s}"].scan(/\=/).length
65
- parsing_results.length.should == number_of_components
66
- end
69
+ it "returns all the components in the signed request" do
70
+ result = @oauth.get_user_info_from_cookies(@cookie)
71
+ @oauth.parse_signed_request(@cookie.values.first).each_pair do |k, v|
72
+ result[k].should == v
73
+ end
74
+ end
75
+
76
+ it "makes a request to Facebook to redeem the code if present" do
77
+ code = "foo"
78
+ @oauth.stub(:parse_signed_request).and_return({"code" => code})
79
+ @oauth.should_receive(:get_access_token_info).with(code, anything)
80
+ @oauth.get_user_info_from_cookies(@cookie)
81
+ end
67
82
 
68
- it "should properly parse valid offline access cookies (e.g. no expiration)" do
69
- result = @oauth.get_user_info_from_cookies(KoalaTest.oauth_test_data["offline_access_cookies"])
70
- result["uid"].should
71
- end
83
+ it "sets the code redemption redirect_uri to ''" do
84
+ @oauth.should_receive(:get_access_token_info).with(anything, :redirect_uri => '')
85
+ @oauth.get_user_info_from_cookies(@cookie)
86
+ end
72
87
 
73
- it "should return all the cookie components from offline access cookies" do
74
- cookie_data = KoalaTest.oauth_test_data["offline_access_cookies"]
75
- parsing_results = @oauth.get_user_info_from_cookies(cookie_data)
76
- number_of_components = cookie_data["fbs_#{@app_id.to_s}"].scan(/\=/).length
77
- parsing_results.length.should == number_of_components
88
+ context "if the code is missing" do
89
+ it "doesn't make a request to Facebook" do
90
+ @oauth.stub(:parse_signed_request).and_return({})
91
+ @oauth.should_receive(:get_access_token_info).never
92
+ @oauth.get_user_info_from_cookies(@cookie)
93
+ end
94
+
95
+ it "returns nil" do
96
+ @oauth.stub(:parse_signed_request).and_return({})
97
+ @oauth.get_user_info_from_cookies(@cookie).should be_nil
98
+ end
99
+ end
100
+
101
+ context "if the code is present" do
102
+ it "adds the access_token into the hash" do
103
+ @oauth.get_user_info_from_cookies(@cookie)["access_token"].should == @token
104
+ end
105
+
106
+ it "returns nil if the call to FB fails" do
107
+ @oauth.stub(:get_access_token_info).and_return(nil)
108
+ @oauth.get_user_info_from_cookies(@cookie).should be_nil
109
+ end
110
+ end
111
+
112
+ it "shouldn't parse invalid cookies" do
113
+ # make an invalid string by replacing some values
114
+ bad_cookie_hash = @cookie.inject({}) { |hash, value| hash[value[0]] = value[1].gsub(/[0-9]/, "3") }
115
+ result = @oauth.get_user_info_from_cookies(bad_cookie_hash)
116
+ result.should be_nil
117
+ end
78
118
  end
119
+
120
+ context "for unsigned cookies" do
121
+ it "should properly parse valid cookies" do
122
+ result = @oauth.get_user_info_from_cookies(KoalaTest.oauth_test_data["valid_cookies"])
123
+ result.should be_a(Hash)
124
+ end
79
125
 
80
- it "shouldn't parse expired cookies" do
81
- result = @oauth.get_user_info_from_cookies(KoalaTest.oauth_test_data["expired_cookies"])
82
- result.should be_nil
83
- end
126
+ it "should return all the cookie components from valid cookie string" do
127
+ cookie_data = KoalaTest.oauth_test_data["valid_cookies"]
128
+ parsing_results = @oauth.get_user_info_from_cookies(cookie_data)
129
+ number_of_components = cookie_data["fbs_#{@app_id.to_s}"].scan(/\=/).length
130
+ parsing_results.length.should == number_of_components
131
+ end
84
132
 
85
- it "shouldn't parse invalid cookies" do
86
- # make an invalid string by replacing some values
87
- bad_cookie_hash = KoalaTest.oauth_test_data["valid_cookies"].inject({}) { |hash, value| hash[value[0]] = value[1].gsub(/[0-9]/, "3") }
88
- result = @oauth.get_user_info_from_cookies(bad_cookie_hash)
89
- result.should be_nil
133
+ it "should properly parse valid offline access cookies (e.g. no expiration)" do
134
+ result = @oauth.get_user_info_from_cookies(KoalaTest.oauth_test_data["offline_access_cookies"])
135
+ result["uid"].should
136
+ end
137
+
138
+ it "should return all the cookie components from offline access cookies" do
139
+ cookie_data = KoalaTest.oauth_test_data["offline_access_cookies"]
140
+ parsing_results = @oauth.get_user_info_from_cookies(cookie_data)
141
+ number_of_components = cookie_data["fbs_#{@app_id.to_s}"].scan(/\=/).length
142
+ parsing_results.length.should == number_of_components
143
+ end
144
+
145
+ it "shouldn't parse expired cookies" do
146
+ new_time = @time.to_i * 2
147
+ @time.stub(:to_i).and_return(new_time)
148
+ @oauth.get_user_info_from_cookies(KoalaTest.oauth_test_data["valid_cookies"]).should be_nil
149
+ end
150
+
151
+ it "shouldn't parse invalid cookies" do
152
+ # make an invalid string by replacing some values
153
+ bad_cookie_hash = KoalaTest.oauth_test_data["valid_cookies"].inject({}) { |hash, value| hash[value[0]] = value[1].gsub(/[0-9]/, "3") }
154
+ result = @oauth.get_user_info_from_cookies(bad_cookie_hash)
155
+ result.should be_nil
156
+ end
90
157
  end
91
158
  end
92
159
 
@@ -179,8 +246,24 @@ describe "Koala::Facebook::OAuth" do
179
246
  end
180
247
 
181
248
  describe "for fetching access tokens" do
182
- if KoalaTest.code
183
- describe "get_access_token_info" do
249
+ describe ".get_access_token_info" do
250
+ it "uses options[:redirect_uri] if provided" do
251
+ uri = "foo"
252
+ Koala.should_receive(:make_request).with(anything, hash_including(:redirect_uri => uri), anything, anything).and_return(Koala::Response.new(200, "", {}))
253
+ @oauth.get_access_token_info(@code, :redirect_uri => uri)
254
+ end
255
+
256
+ it "uses the redirect_uri used to create the @oauth if no :redirect_uri option is provided" do
257
+ Koala.should_receive(:make_request).with(anything, hash_including(:redirect_uri => @callback_url), anything, anything).and_return(Koala::Response.new(200, "", {}))
258
+ @oauth.get_access_token_info(@code)
259
+ end
260
+
261
+ it "makes a GET request" do
262
+ Koala.should_receive(:make_request).with(anything, anything, "get", anything).and_return(Koala::Response.new(200, "", {}))
263
+ @oauth.get_access_token_info(@code)
264
+ end
265
+
266
+ if KoalaTest.code
184
267
  it "should properly get and parse an access token token results into a hash" do
185
268
  result = @oauth.get_access_token_info(@code)
186
269
  result.should be_a(Hash)
@@ -190,36 +273,40 @@ describe "Koala::Facebook::OAuth" do
190
273
  result = @oauth.get_access_token_info(@code)
191
274
  result["access_token"].should
192
275
  end
193
-
194
276
  it "should raise an error when get_access_token is called with a bad code" do
195
277
  lambda { @oauth.get_access_token_info("foo") }.should raise_error(Koala::Facebook::APIError)
196
278
  end
197
279
  end
280
+ end
281
+
282
+ describe ".get_access_token" do
283
+ # TODO refactor these to be proper tests with stubs and tests against real data
284
+ it "should pass on any options provided to make_request" do
285
+ options = {:a => 2}
286
+ Koala.should_receive(:make_request).with(anything, anything, anything, hash_including(options)).and_return(Koala::Response.new(200, "", {}))
287
+ @oauth.get_access_token(@code, options)
288
+ end
198
289
 
199
- describe "get_access_token" do
200
- it "should use get_access_token_info to get and parse an access token token results" do
290
+ if KoalaTest.code
291
+ it "uses get_access_token_info to get and parse an access token token results" do
201
292
  result = @oauth.get_access_token(@code)
202
293
  result.should be_a(String)
203
294
  end
204
295
 
205
- it "should return the access token as a string" do
296
+ it "returns the access token as a string" do
206
297
  result = @oauth.get_access_token(@code)
207
298
  original = @oauth.get_access_token_info(@code)
208
299
  result.should == original["access_token"]
209
300
  end
210
301
 
211
- it "should raise an error when get_access_token is called with a bad code" do
302
+ it "raises an error when get_access_token is called with a bad code" do
212
303
  lambda { @oauth.get_access_token("foo") }.should raise_error(Koala::Facebook::APIError)
213
304
  end
214
-
215
- it "should pass on any options provided to make_request" do
216
- options = {:a => 2}
217
- Koala.should_receive(:make_request).with(anything, anything, anything, hash_including(options)).and_return(Koala::Response.new(200, "", {}))
218
- @oauth.get_access_token(@code, options)
219
- end
220
305
  end
221
- else
222
- it "OAuth code tests will not be run since the code field in facebook_data.yml is blank."
306
+ end
307
+
308
+ unless KoalaTest.code
309
+ it "Some OAuth code tests will not be run since the code field in facebook_data.yml is blank."
223
310
  end
224
311
 
225
312
  describe "get_app_access_token_info" do
@@ -243,16 +243,6 @@ describe "Koala::Facebook::TestUsers" do
243
243
  end
244
244
 
245
245
  describe "tests that create users" do
246
- before :each do
247
- test_users = Koala::Facebook::TestUsers.new({:app_access_token => @app_access_token, :app_id => @app_id})
248
- test_users.delete_all
249
- end
250
-
251
- after :each do
252
- test_users = Koala::Facebook::TestUsers.new({:app_access_token => @app_access_token, :app_id => @app_id})
253
- test_users.delete_all
254
- end
255
-
256
246
  it "should create a 5 person network" do
257
247
  size = 5
258
248
  @network = @test_users.create_network(size)
@@ -86,6 +86,34 @@ describe "Koala::UploadableIO" do
86
86
  end
87
87
  end
88
88
 
89
+ describe "when given an IO object" do
90
+ before(:each) do
91
+ @io = StringIO.open("abcdefgh")
92
+ @koala_io_params = [@io]
93
+ end
94
+
95
+ describe "and a content type" do
96
+ before :each do
97
+ @koala_io_params.concat(["image/jpg"])
98
+ end
99
+
100
+ it "returns an UploadableIO with the same io" do
101
+ Koala::UploadableIO.new(*@koala_io_params).io_or_path.should == @koala_io_params[0]
102
+ end
103
+
104
+ it "returns an UploadableIO with the same content_type" do
105
+ content_stub = @koala_io_params[1] = stub('Content Type')
106
+ Koala::UploadableIO.new(*@koala_io_params).content_type.should == content_stub
107
+ end
108
+ end
109
+
110
+ describe "and no content type" do
111
+ it "raises an exception" do
112
+ lambda { Koala::UploadableIO.new(*@koala_io_params) }.should raise_exception(Koala::KoalaError)
113
+ end
114
+ end
115
+ end
116
+
89
117
  describe "when given a Rails 3 ActionDispatch::Http::UploadedFile" do
90
118
  before(:each) do
91
119
  @tempfile, @uploaded_file = rails_3_mocks
@@ -30,11 +30,12 @@ oauth_test_data:
30
30
  # note: the tests stub the time class so these default cookies are always valid (if you're using the default app)
31
31
  # if not you may want to remove the stubbing to test expiration
32
32
  fbs_119908831367602: '"access_token=119908831367602|2.LKE7ksSPOx0V_8mHPr2NHQ__.3600.1273363200-2905623|CMpi0AYbn03Oukzv94AUha2qbO4.&expires=1273363200&secret=lT_9zm5r5IbJ6Aa5O54nFw__&session_key=2.LKE7ksSPOx0V_8mHPr2NHQ__.3600.1273363200-2905623&sig=9515e93113921f9476a4efbdd4a3c746&uid=2905623"'
33
- expired_cookies:
34
- fbs_119908831367602: '"access_token=119908831367602|2.xv9mi6QSOpr474s4n2X_pw__.3600.1273287600-2905623|yVt5WH_S6J5p3gFa5_5lBzckhws.&expires=1273287600&secret=V_E79ovQnXqxGctFuC_n5A__&session_key=2.xv9mi6QSOpr474s4n2X_pw__.3600.1273287600-2905623&sig=eeef60838c0c800258d89b7e6ddddddb&uid=2905623"'
35
33
  offline_access_cookies:
36
34
  # note: I've revoked the offline access for security reasons, so you can't make calls against this :)
37
35
  fbs_119908831367602: '"access_token=119908831367602|08170230801eb225068e7a70-2905623|Q3LDCYYF8CX9cstxnZLsxiR0nwg.&expires=0&secret=78abaee300b392e275072a9f2727d436&session_key=08170230801eb225068e7a70-2905623&sig=423b8aa4b6fa1f9a571955f8e929d567&uid=2905623"'
36
+ valid_signed_cookies:
37
+ "fbsr_119908831367602": "f1--LHwjHVCxfs97hRHL-4cF-0jNxZRc6MGzo1qHLb0.eyJhbGdvcml0aG0iOiJITUFDLVNIQTI1NiIsImNvZGUiOiIyLkFRQm90a0pBWlhVY1l3RkMuMzYwMC4xMzE0ODEzNjAwLjEtMjkwNTYyM3x4V2xya0d0UmJIZlpIclRnVWwxQmxJcVhRbjQiLCJpc3N1ZWRfYXQiOjEzMTQ4MDY2NTUsInVzZXJfaWQiOiIyOTA1NjIzIn0"
38
+
38
39
 
39
40
  # These values from the OAuth Playground (see above) will work out of the box
40
41
  # You can update this to live data if desired
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: koala
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0beta2
4
+ version: 1.2.0beta3
5
5
  prerelease: 5
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-08-23 00:00:00.000000000Z
12
+ date: 2011-09-12 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: multi_json
16
- requirement: &70292131094320 !ruby/object:Gem::Requirement
16
+ requirement: &70118378561560 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '1.0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70292131094320
24
+ version_requirements: *70118378561560
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: faraday
27
- requirement: &70292131091060 !ruby/object:Gem::Requirement
27
+ requirement: &70118378560320 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ~>
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: 0.7.0
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *70292131091060
35
+ version_requirements: *70118378560320
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: rspec
38
- requirement: &70292131088100 !ruby/object:Gem::Requirement
38
+ requirement: &70118378559340 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ~>
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '2.5'
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *70292131088100
46
+ version_requirements: *70118378559340
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: rake
49
- requirement: &70292131086000 !ruby/object:Gem::Requirement
49
+ requirement: &70118378557940 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ~>
@@ -54,7 +54,7 @@ dependencies:
54
54
  version: 0.8.7
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *70292131086000
57
+ version_requirements: *70118378557940
58
58
  description: Koala is a lightweight, flexible Ruby SDK for Facebook. It allows read/write
59
59
  access to the social graph via the Graph and REST APIs, as well as support for realtime
60
60
  updates and OAuth and Facebook Connect authentication. Koala is fully tested and
@@ -133,7 +133,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
133
133
  version: '0'
134
134
  segments:
135
135
  - 0
136
- hash: 2806885523067158352
136
+ hash: -3213298653109204495
137
137
  required_rubygems_version: !ruby/object:Gem::Requirement
138
138
  none: false
139
139
  requirements: