koala 1.3.0 → 1.4.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +6 -9
- data/CHANGELOG +15 -1
- data/Gemfile +3 -4
- data/lib/koala/api/graph_api.rb +57 -53
- data/lib/koala/http_service.rb +1 -1
- data/lib/koala/oauth.rb +63 -36
- data/lib/koala/version.rb +1 -1
- data/readme.md +1 -1
- data/spec/cases/graph_api_batch_spec.rb +19 -19
- data/spec/cases/http_service_spec.rb +7 -0
- data/spec/cases/koala_test_spec.rb +5 -0
- data/spec/cases/oauth_spec.rb +72 -32
- data/spec/fixtures/facebook_data.yml +1 -1
- data/spec/fixtures/mock_facebook_responses.yml +12 -3
- data/spec/support/graph_api_shared_examples.rb +19 -21
- data/spec/support/mock_http_service.rb +1 -1
- metadata +13 -11
data/.travis.yml
CHANGED
@@ -1,13 +1,10 @@
|
|
1
1
|
rvm:
|
2
|
-
- 1.8.7
|
2
|
+
- 1.8.7
|
3
3
|
- 1.9.2
|
4
4
|
- 1.9.3
|
5
5
|
- ruby-head
|
6
|
-
-
|
7
|
-
-
|
8
|
-
-
|
9
|
-
-
|
10
|
-
|
11
|
-
branches:
|
12
|
-
except:
|
13
|
-
- rdoc
|
6
|
+
- jruby-18mode # JRuby in 1.8 mode
|
7
|
+
- jruby-19mode # JRuby in 1.9 mode
|
8
|
+
- rbx-18mode
|
9
|
+
- rbx-19mode
|
10
|
+
- ree
|
data/CHANGELOG
CHANGED
@@ -1,3 +1,17 @@
|
|
1
|
+
v1.4
|
2
|
+
New methods:
|
3
|
+
-- OAuth#exchange_access_token(_info) allows you to extend access tokens you receive (thanks, etiennebarrie!)
|
4
|
+
Updated methods:
|
5
|
+
-- HTTPServices#encode_params sorts parameters to aid in URL comparison (thanks, sholden!)
|
6
|
+
-- get_connections is now aliased as get_connection (use whichever makes sense to you)
|
7
|
+
Internal improvements:
|
8
|
+
-- Fixed a readme typo (thanks, brycethornton!)
|
9
|
+
Testing improvements:
|
10
|
+
-- Added parallel_tests to development gem file
|
11
|
+
-- Fixed failing live tests
|
12
|
+
-- Koala now tests against JRuby and Rubinius in 1.9 mode on Travis-CI
|
13
|
+
|
14
|
+
|
1
15
|
v1.3
|
2
16
|
New methods:
|
3
17
|
-- OAuth#url_for_dialog creates URLs for Facebook dialog pages
|
@@ -24,7 +38,7 @@ Testing improvements:
|
|
24
38
|
-- Expanded/improved test coverage
|
25
39
|
-- The test suite no longer users any hard-coded user IDs
|
26
40
|
-- KoalaTest.test_user_api allows access to the TestUsers instance
|
27
|
-
-- Configured tests to run in random order using RSpec 2.8.0rc1
|
41
|
+
-- Configured tests to run in random order using RSpec 2.8.0rc1
|
28
42
|
|
29
43
|
v1.2.1
|
30
44
|
New methods:
|
data/Gemfile
CHANGED
@@ -5,11 +5,12 @@ group :development do
|
|
5
5
|
end
|
6
6
|
|
7
7
|
group :development, :test do
|
8
|
-
gem "typhoeus"
|
8
|
+
gem "typhoeus" unless defined? JRUBY_VERSION
|
9
9
|
|
10
10
|
# Testing infrastructure
|
11
11
|
gem 'guard'
|
12
12
|
gem 'guard-rspec'
|
13
|
+
gem "parallel_tests"
|
13
14
|
|
14
15
|
if RUBY_PLATFORM =~ /darwin/
|
15
16
|
# OS X integration
|
@@ -18,8 +19,6 @@ group :development, :test do
|
|
18
19
|
end
|
19
20
|
end
|
20
21
|
|
21
|
-
if defined? JRUBY_VERSION
|
22
|
-
gem "jruby-openssl"
|
23
|
-
end
|
22
|
+
gem "jruby-openssl" if defined? JRUBY_VERSION
|
24
23
|
|
25
24
|
gemspec
|
data/lib/koala/api/graph_api.rb
CHANGED
@@ -17,7 +17,7 @@ module Koala
|
|
17
17
|
# token, this will fetch the profile of the active user and the list
|
18
18
|
# of the user's friends:
|
19
19
|
#
|
20
|
-
# @example
|
20
|
+
# @example
|
21
21
|
# graph = Koala::Facebook::API.new(access_token)
|
22
22
|
# user = graph.get_object("me")
|
23
23
|
# friends = graph.get_connections(user["id"], "friends")
|
@@ -25,7 +25,7 @@ module Koala
|
|
25
25
|
# You can see a list of all of the objects and connections supported
|
26
26
|
# by the API at http://developers.facebook.com/docs/reference/api/.
|
27
27
|
#
|
28
|
-
# You can obtain an access token via OAuth or by using the Facebook JavaScript SDK.
|
28
|
+
# You can obtain an access token via OAuth or by using the Facebook JavaScript SDK.
|
29
29
|
# If you're using the JavaScript SDK, you can use the
|
30
30
|
# {Koala::Facebook::OAuth#get_user_from_cookie} method to get the OAuth access token
|
31
31
|
# for the active user from the cookie provided by Facebook.
|
@@ -35,12 +35,12 @@ module Koala
|
|
35
35
|
# Objects
|
36
36
|
|
37
37
|
# Get information about a Facebook object.
|
38
|
-
#
|
38
|
+
#
|
39
39
|
# @param id the object ID (string or number)
|
40
|
-
# @param args any additional arguments
|
40
|
+
# @param args any additional arguments
|
41
41
|
# (fields, metadata, etc. -- see {http://developers.facebook.com/docs/reference/api/ Facebook's documentation})
|
42
42
|
# @param options (see Koala::Facebook::API#api)
|
43
|
-
#
|
43
|
+
#
|
44
44
|
# @raise [Koala::Facebook::APIError] if the ID is invalid or you don't have access to that object
|
45
45
|
#
|
46
46
|
# @return a hash of object data
|
@@ -50,11 +50,11 @@ module Koala
|
|
50
50
|
end
|
51
51
|
|
52
52
|
# Get information about multiple Facebook objects in one call.
|
53
|
-
#
|
53
|
+
#
|
54
54
|
# @param ids an array or comma-separated string of object IDs
|
55
55
|
# @param args (see #get_object)
|
56
56
|
# @param options (see Koala::Facebook::API#api)
|
57
|
-
#
|
57
|
+
#
|
58
58
|
# @raise [Koala::Facebook::APIError] if any ID is invalid or you don't have access to that object
|
59
59
|
#
|
60
60
|
# @return an array of object data hashes
|
@@ -70,14 +70,14 @@ module Koala
|
|
70
70
|
#
|
71
71
|
# @note put_object is (for historical reasons) the same as put_connections.
|
72
72
|
# Please use put_connections; in a future version of Koala (2.0?),
|
73
|
-
# put_object will issue a POST directly to an individual object, not to a connection.
|
73
|
+
# put_object will issue a POST directly to an individual object, not to a connection.
|
74
74
|
def put_object(parent_object, connection_name, args = {}, options = {})
|
75
75
|
raise APIError.new({"type" => "KoalaMissingAccessToken", "message" => "Write operations require an access token"}) unless @access_token
|
76
76
|
graph_call("#{parent_object}/#{connection_name}", args, "post", options)
|
77
77
|
end
|
78
78
|
|
79
79
|
# Delete an object from the Graph if you have appropriate permissions.
|
80
|
-
#
|
80
|
+
#
|
81
81
|
# @param id (see #get_object)
|
82
82
|
# @param options (see #get_object)
|
83
83
|
#
|
@@ -91,27 +91,28 @@ module Koala
|
|
91
91
|
# Fetch information about a given connection (e.g. type of activity -- feed, events, photos, etc.)
|
92
92
|
# for a specific user.
|
93
93
|
# See {http://developers.facebook.com/docs/api Facebook's documentation} for a complete list of connections.
|
94
|
-
#
|
95
|
-
# @note to access connections like /user_id/CONNECTION/other_user_id,
|
94
|
+
#
|
95
|
+
# @note to access connections like /user_id/CONNECTION/other_user_id,
|
96
96
|
# simply pass "CONNECTION/other_user_id" as the connection_name
|
97
97
|
#
|
98
98
|
# @param id (see #get_object)
|
99
|
-
# @param connection_name what
|
99
|
+
# @param connection_name what
|
100
100
|
# @param args any additional arguments
|
101
101
|
# @param options (see #get_object)
|
102
|
-
#
|
102
|
+
#
|
103
103
|
# @return [Koala::Facebook::API::GraphCollection] an array of object hashes (in most cases)
|
104
|
-
def
|
104
|
+
def get_connection(id, connection_name, args = {}, options = {})
|
105
105
|
# Fetchs the connections for given object.
|
106
106
|
graph_call("#{id}/#{connection_name}", args, "get", options)
|
107
107
|
end
|
108
|
+
alias_method :get_connections, :get_connection
|
108
109
|
|
109
110
|
|
110
111
|
# Write an object to the Graph for a specific user.
|
111
|
-
# See {http://developers.facebook.com/docs/api#publishing Facebook's documentation}
|
112
|
+
# See {http://developers.facebook.com/docs/api#publishing Facebook's documentation}
|
112
113
|
# for all the supported writeable objects.
|
113
114
|
#
|
114
|
-
# @note (see #
|
115
|
+
# @note (see #get_connection)
|
115
116
|
#
|
116
117
|
# @example
|
117
118
|
# graph.put_object("me", "feed", :message => "Hello, world")
|
@@ -123,8 +124,8 @@ module Koala
|
|
123
124
|
# extended permissions.
|
124
125
|
#
|
125
126
|
# @param id (see #get_object)
|
126
|
-
# @param connection_name (see #
|
127
|
-
# @param args (see #
|
127
|
+
# @param connection_name (see #get_connection)
|
128
|
+
# @param args (see #get_connection)
|
128
129
|
# @param options (see #get_object)
|
129
130
|
#
|
130
131
|
# @return a hash containing the new object's id
|
@@ -136,11 +137,11 @@ module Koala
|
|
136
137
|
|
137
138
|
# Delete an object's connection (for instance, unliking the object).
|
138
139
|
#
|
139
|
-
# @note (see #
|
140
|
-
#
|
140
|
+
# @note (see #get_connection)
|
141
|
+
#
|
141
142
|
# @param id (see #get_object)
|
142
|
-
# @param connection_name (see #
|
143
|
-
# @args (see #
|
143
|
+
# @param connection_name (see #get_connection)
|
144
|
+
# @args (see #get_connection)
|
144
145
|
# @param options (see #get_object)
|
145
146
|
#
|
146
147
|
# @return (see #delete_object)
|
@@ -150,10 +151,13 @@ module Koala
|
|
150
151
|
graph_call("#{id}/#{connection_name}", args, "delete", options)
|
151
152
|
end
|
152
153
|
|
153
|
-
# Fetches a photo.
|
154
|
-
# (Facebook returns the src of the photo as a response header; this method parses that properly,
|
154
|
+
# Fetches a photo.
|
155
|
+
# (Facebook returns the src of the photo as a response header; this method parses that properly,
|
155
156
|
# unlike using get_connections("photo").)
|
156
157
|
#
|
158
|
+
# @param options options for Facebook (see #get_object).
|
159
|
+
# To get a different size photo, pass :type => size (small, normal, large, square).
|
160
|
+
#
|
157
161
|
# @note to delete photos or videos, use delete_object(id)
|
158
162
|
#
|
159
163
|
# @return the URL to the image
|
@@ -199,7 +203,7 @@ module Koala
|
|
199
203
|
put_object(*args)
|
200
204
|
end
|
201
205
|
|
202
|
-
# Write directly to the user's wall.
|
206
|
+
# Write directly to the user's wall.
|
203
207
|
# Convenience method equivalent to put_object(id, "feed").
|
204
208
|
#
|
205
209
|
# To get wall posts, use get_connections(user, "feed")
|
@@ -220,13 +224,13 @@ module Koala
|
|
220
224
|
# "picture" => "http://www.example.com/thumbnail.jpg"
|
221
225
|
# })
|
222
226
|
#
|
223
|
-
# @see #put_connections
|
227
|
+
# @see #put_connections
|
224
228
|
# @return (see #put_connections)
|
225
229
|
def put_wall_post(message, attachment = {}, target_id = "me", options = {})
|
226
230
|
self.put_object(target_id, "feed", attachment.merge({:message => message}), options)
|
227
231
|
end
|
228
232
|
|
229
|
-
# Comment on a given object.
|
233
|
+
# Comment on a given object.
|
230
234
|
# Convenience method equivalent to put_connection(id, "comments").
|
231
235
|
#
|
232
236
|
# To delete comments, use delete_object(comment_id).
|
@@ -242,7 +246,7 @@ module Koala
|
|
242
246
|
self.put_object(id, "comments", {:message => message}, options)
|
243
247
|
end
|
244
248
|
|
245
|
-
# Like a given object.
|
249
|
+
# Like a given object.
|
246
250
|
# Convenience method equivalent to put_connections(id, "likes").
|
247
251
|
#
|
248
252
|
# To get a list of a user's or object's likes, use get_connections(id, "likes").
|
@@ -256,7 +260,7 @@ module Koala
|
|
256
260
|
self.put_object(id, "likes", {}, options)
|
257
261
|
end
|
258
262
|
|
259
|
-
# Unlike a given object.
|
263
|
+
# Unlike a given object.
|
260
264
|
# Convenience method equivalent to delete_connection(id, "likes").
|
261
265
|
#
|
262
266
|
# @param id (see #get_object)
|
@@ -275,7 +279,7 @@ module Koala
|
|
275
279
|
# @param search_terms the query to search for
|
276
280
|
# @param args additional arguments, such as type, fields, etc.
|
277
281
|
# @param options (see #get_object)
|
278
|
-
#
|
282
|
+
#
|
279
283
|
# @return [Koala::Facebook::API::GraphCollection] an array of search results
|
280
284
|
def search(search_terms, args = {}, options = {})
|
281
285
|
args.merge!({:q => search_terms}) unless search_terms.nil?
|
@@ -286,10 +290,10 @@ module Koala
|
|
286
290
|
# In general, we're trying to avoid adding convenience methods to Koala
|
287
291
|
# except to support cases where the Facebook API requires non-standard input
|
288
292
|
# such as JSON-encoding arguments, posts directly to objects, etc.
|
289
|
-
|
290
|
-
# Make an FQL query.
|
293
|
+
|
294
|
+
# Make an FQL query.
|
291
295
|
# Convenience method equivalent to get_object("fql", :q => query).
|
292
|
-
#
|
296
|
+
#
|
293
297
|
# @param query the FQL query to perform
|
294
298
|
# @param args (see #get_object)
|
295
299
|
# @param options (see #get_object)
|
@@ -298,15 +302,15 @@ module Koala
|
|
298
302
|
end
|
299
303
|
|
300
304
|
# Make an FQL multiquery.
|
301
|
-
# This method simplifies the result returned from multiquery into a more logical format.
|
302
|
-
#
|
305
|
+
# This method simplifies the result returned from multiquery into a more logical format.
|
306
|
+
#
|
303
307
|
# @param queries a hash of query names => FQL queries
|
304
308
|
# @param args (see #get_object)
|
305
309
|
# @param options (see #get_object)
|
306
310
|
#
|
307
311
|
# @example
|
308
312
|
# @api.fql_multiquery({
|
309
|
-
# "query1" => "select post_id from stream where source_id = me()",
|
313
|
+
# "query1" => "select post_id from stream where source_id = me()",
|
310
314
|
# "query2" => "select fromid from comment where post_id in (select post_id from #query1)"
|
311
315
|
# })
|
312
316
|
# # returns {"query1" => [obj1, obj2, ...], "query2" => [obj3, ...]}
|
@@ -319,15 +323,15 @@ module Koala
|
|
319
323
|
results.inject({}) {|outcome, data| outcome[data["name"]] = data["fql_result_set"]; outcome}
|
320
324
|
end
|
321
325
|
end
|
322
|
-
|
326
|
+
|
323
327
|
# Get a page's access token, allowing you to act as the page.
|
324
328
|
# Convenience method for @api.get_object(page_id, :fields => "access_token").
|
325
329
|
#
|
326
330
|
# @param id the page ID
|
327
331
|
# @param args (see #get_object)
|
328
|
-
# @param options (see #get_object)
|
332
|
+
# @param options (see #get_object)
|
329
333
|
#
|
330
|
-
# @return the page's access token (discarding expiration and any other information)
|
334
|
+
# @return the page's access token (discarding expiration and any other information)
|
331
335
|
def get_page_access_token(id, args = {}, options = {})
|
332
336
|
result = get_object(id, args.merge(:fields => "access_token"), options) do
|
333
337
|
result ? result["access_token"] : nil
|
@@ -340,14 +344,14 @@ module Koala
|
|
340
344
|
# @param urls the URLs for which you want comments
|
341
345
|
# @param args (see #get_object)
|
342
346
|
# @param options (see #get_object)
|
343
|
-
#
|
347
|
+
#
|
344
348
|
# @returns a hash of urls => comment arrays
|
345
349
|
def get_comments_for_urls(urls = [], args = {}, options = {})
|
346
350
|
return [] if urls.empty?
|
347
351
|
args.merge!(:ids => urls.respond_to?(:join) ? urls.join(",") : urls)
|
348
352
|
get_object("comments", args, options)
|
349
353
|
end
|
350
|
-
|
354
|
+
|
351
355
|
def set_app_restrictions(app_id, restrictions_hash, args = {}, options = {})
|
352
356
|
graph_call(app_id, args.merge(:restrictions => MultiJson.encode(restrictions_hash)), "post", options)
|
353
357
|
end
|
@@ -355,9 +359,9 @@ module Koala
|
|
355
359
|
# Certain calls such as {#get_connections} return an array of results which you can page through
|
356
360
|
# forwards and backwards (to see more feed stories, search results, etc.).
|
357
361
|
# Those methods use get_page to request another set of results from Facebook.
|
358
|
-
#
|
362
|
+
#
|
359
363
|
# @note You'll rarely need to use this method unless you're using Sinatra or another non-Rails framework
|
360
|
-
# (see {Koala::Facebook::GraphCollection GraphCollection} for more information).
|
364
|
+
# (see {Koala::Facebook::GraphCollection GraphCollection} for more information).
|
361
365
|
#
|
362
366
|
# @param params an array of arguments to graph_call
|
363
367
|
# as returned by {Koala::Facebook::GraphCollection.parse_page_url}.
|
@@ -367,10 +371,10 @@ module Koala
|
|
367
371
|
graph_call(*params)
|
368
372
|
end
|
369
373
|
|
370
|
-
# Execute a set of Graph API calls as a batch.
|
371
|
-
# See {https://github.com/arsduo/koala/wiki/Batch-requests batch request documentation}
|
374
|
+
# Execute a set of Graph API calls as a batch.
|
375
|
+
# See {https://github.com/arsduo/koala/wiki/Batch-requests batch request documentation}
|
372
376
|
# for more information and examples.
|
373
|
-
#
|
377
|
+
#
|
374
378
|
# @param http_options HTTP options for the entire request.
|
375
379
|
#
|
376
380
|
# @yield batch_api [Koala::Facebook::GraphBatchAPI] an API subclass
|
@@ -388,7 +392,7 @@ module Koala
|
|
388
392
|
# end
|
389
393
|
# # => [{"id" => my_id, ...}, {"id"" => koppel_id, ...}]
|
390
394
|
#
|
391
|
-
# @return an array of results from your batch calls (as if you'd made them individually),
|
395
|
+
# @return an array of results from your batch calls (as if you'd made them individually),
|
392
396
|
# arranged in the same order they're made.
|
393
397
|
def batch(http_options = {}, &block)
|
394
398
|
batch_client = GraphBatchAPI.new(access_token, self)
|
@@ -399,7 +403,7 @@ module Koala
|
|
399
403
|
batch_client
|
400
404
|
end
|
401
405
|
end
|
402
|
-
|
406
|
+
|
403
407
|
# Make a call directly to the Graph API.
|
404
408
|
# (See any of the other methods for example invocations.)
|
405
409
|
#
|
@@ -408,12 +412,12 @@ module Koala
|
|
408
412
|
# @param verb the type of HTTP request to make (get, post, delete, etc.)
|
409
413
|
# @options (see #get_object)
|
410
414
|
#
|
411
|
-
# @yield response when making a batch API call, you can pass in a block
|
412
|
-
# that parses the results, allowing for cleaner code.
|
415
|
+
# @yield response when making a batch API call, you can pass in a block
|
416
|
+
# that parses the results, allowing for cleaner code.
|
413
417
|
# The block's return value is returned in the batch results.
|
414
418
|
# See the code for {#get_picture} or {#fql_multiquery} for examples.
|
415
419
|
# (Not needed in regular calls; you'll probably rarely use this.)
|
416
|
-
#
|
420
|
+
#
|
417
421
|
# @raise [Koala::Facebook::APIError] if Facebook returns an error
|
418
422
|
#
|
419
423
|
# @return the result from Facebook
|
@@ -425,13 +429,13 @@ module Koala
|
|
425
429
|
|
426
430
|
# turn this into a GraphCollection if it's pageable
|
427
431
|
result = GraphCollection.evaluate(result, self)
|
428
|
-
|
432
|
+
|
429
433
|
# now process as appropriate for the given call (get picture header, etc.)
|
430
434
|
post_processing ? post_processing.call(result) : result
|
431
435
|
end
|
432
436
|
|
433
437
|
private
|
434
|
-
|
438
|
+
|
435
439
|
def check_response(response)
|
436
440
|
# check for Graph API-specific errors
|
437
441
|
# this returns an error, which is immediately raised (non-batch)
|
data/lib/koala/http_service.rb
CHANGED
@@ -86,7 +86,7 @@ module Koala
|
|
86
86
|
#
|
87
87
|
# @return the appropriately-encoded string
|
88
88
|
def self.encode_params(param_hash)
|
89
|
-
((param_hash || {}).collect do |key_and_value|
|
89
|
+
((param_hash || {}).sort_by{|k, v| k.to_s}.collect do |key_and_value|
|
90
90
|
key_and_value[1] = MultiJson.encode(key_and_value[1]) unless key_and_value[1].is_a? String
|
91
91
|
"#{key_and_value[0].to_s}=#{CGI.escape key_and_value[1]}"
|
92
92
|
end).join("&")
|
data/lib/koala/oauth.rb
CHANGED
@@ -4,12 +4,12 @@ require 'base64'
|
|
4
4
|
|
5
5
|
module Koala
|
6
6
|
module Facebook
|
7
|
-
|
7
|
+
|
8
8
|
DIALOG_HOST = "www.facebook.com"
|
9
|
-
|
9
|
+
|
10
10
|
class OAuth
|
11
11
|
attr_reader :app_id, :app_secret, :oauth_callback_url
|
12
|
-
|
12
|
+
|
13
13
|
# Creates a new OAuth client.
|
14
14
|
#
|
15
15
|
# @param app_id [String, Integer] a Facebook application ID
|
@@ -20,14 +20,14 @@ module Koala
|
|
20
20
|
@app_secret = app_secret
|
21
21
|
@oauth_callback_url = oauth_callback_url
|
22
22
|
end
|
23
|
-
|
23
|
+
|
24
24
|
# Parses the cookie set Facebook's JavaScript SDK.
|
25
25
|
#
|
26
26
|
# @note in parsing Facebook's new signed cookie format this method has to make a request to Facebook.
|
27
27
|
# We recommend storing authenticated user info in your Rails session (or equivalent) and only
|
28
28
|
# calling this when needed.
|
29
29
|
#
|
30
|
-
# @param cookie_hash a set of cookies that includes the Facebook cookie.
|
30
|
+
# @param cookie_hash a set of cookies that includes the Facebook cookie.
|
31
31
|
# You can pass Rack/Rails/Sinatra's cookie hash directly to this method.
|
32
32
|
#
|
33
33
|
# @return the authenticated user's information as a hash, or nil.
|
@@ -60,21 +60,21 @@ module Koala
|
|
60
60
|
alias_method :get_user_from_cookie, :get_user_from_cookies
|
61
61
|
|
62
62
|
# URLs
|
63
|
-
|
63
|
+
|
64
64
|
# Builds an OAuth URL, where users will be prompted to log in and for any desired permissions.
|
65
|
-
# When the users log in, you receive a callback with their
|
65
|
+
# When the users log in, you receive a callback with their
|
66
66
|
# See http://developers.facebook.com/docs/authentication/.
|
67
67
|
#
|
68
68
|
# @see #url_for_access_token
|
69
69
|
#
|
70
|
-
# @note The server-side authentication and dialog methods should only be used
|
70
|
+
# @note The server-side authentication and dialog methods should only be used
|
71
71
|
# if your application can't use the Facebook Javascript SDK,
|
72
72
|
# which provides a much better user experience.
|
73
73
|
# See http://developers.facebook.com/docs/reference/javascript/.
|
74
74
|
#
|
75
75
|
# @param options any query values to add to the URL, as well as any special/required values listed below.
|
76
76
|
# @option options permissions an array or comma-separated string of desired permissions
|
77
|
-
#
|
77
|
+
#
|
78
78
|
# @raise ArgumentError if no OAuth callback was specified in OAuth#new or in options as :redirect_uri
|
79
79
|
#
|
80
80
|
# @return an OAuth URL you can send your users to
|
@@ -84,7 +84,7 @@ module Koala
|
|
84
84
|
options[:scope] = permissions.is_a?(Array) ? permissions.join(",") : permissions
|
85
85
|
end
|
86
86
|
url_options = {:client_id => @app_id}.merge(options)
|
87
|
-
|
87
|
+
|
88
88
|
# Creates the URL for oauth authorization for a given callback and optional set of permissions
|
89
89
|
build_url("https://#{GRAPH_SERVER}/oauth/authorize", true, url_options)
|
90
90
|
end
|
@@ -92,9 +92,9 @@ module Koala
|
|
92
92
|
# Once you receive an OAuth code, you need to redeem it from Facebook using an appropriate URL.
|
93
93
|
# (This is done by your server behind the scenes.)
|
94
94
|
# See http://developers.facebook.com/docs/authentication/.
|
95
|
-
#
|
95
|
+
#
|
96
96
|
# @see #url_for_oauth_code
|
97
|
-
#
|
97
|
+
#
|
98
98
|
# @note (see #url_for_oauth_code)
|
99
99
|
#
|
100
100
|
# @param code an OAuth code received from Facebook
|
@@ -106,7 +106,7 @@ module Koala
|
|
106
106
|
def url_for_access_token(code, options = {})
|
107
107
|
# Creates the URL for the token corresponding to a given code generated by Facebook
|
108
108
|
url_options = {
|
109
|
-
:client_id => @app_id,
|
109
|
+
:client_id => @app_id,
|
110
110
|
:code => code,
|
111
111
|
:client_secret => @app_secret
|
112
112
|
}.merge(options)
|
@@ -115,7 +115,7 @@ module Koala
|
|
115
115
|
|
116
116
|
# Builds a URL for a given dialog (feed, friends, OAuth, pay, send, etc.)
|
117
117
|
# See http://developers.facebook.com/docs/reference/dialogs/.
|
118
|
-
#
|
118
|
+
#
|
119
119
|
# @note (see #url_for_oauth_code)
|
120
120
|
#
|
121
121
|
# @param dialog_type the kind of Facebook dialog you want to show
|
@@ -124,37 +124,37 @@ module Koala
|
|
124
124
|
# @return an URL your server can query for the user's access token
|
125
125
|
def url_for_dialog(dialog_type, options = {})
|
126
126
|
# some endpoints require app_id, some client_id, supply both doesn't seem to hurt
|
127
|
-
url_options = {:app_id => @app_id, :client_id => @app_id}.merge(options)
|
127
|
+
url_options = {:app_id => @app_id, :client_id => @app_id}.merge(options)
|
128
128
|
build_url("http://#{DIALOG_HOST}/dialog/#{dialog_type}", true, url_options)
|
129
129
|
end
|
130
|
-
|
130
|
+
|
131
131
|
# access tokens
|
132
|
-
|
132
|
+
|
133
133
|
# Fetches an access token, token expiration, and other info from Facebook.
|
134
134
|
# Useful when you've received an OAuth code using the server-side authentication process.
|
135
135
|
# @see url_for_oauth_code
|
136
136
|
#
|
137
137
|
# @note (see #url_for_oauth_code)
|
138
|
-
#
|
138
|
+
#
|
139
139
|
# @param code (see #url_for_access_token)
|
140
140
|
# @param options any additional parameters to send to Facebook when redeeming the token
|
141
|
-
#
|
142
|
-
# @raise Koala::Facebook::APIError if Facebook returns an error response
|
143
|
-
#
|
144
|
-
# @return a hash of the access token info returned by Facebook (token, expiration, etc.)
|
141
|
+
#
|
142
|
+
# @raise Koala::Facebook::APIError if Facebook returns an error response
|
143
|
+
#
|
144
|
+
# @return a hash of the access token info returned by Facebook (token, expiration, etc.)
|
145
145
|
def get_access_token_info(code, options = {})
|
146
146
|
# convenience method to get a parsed token from Facebook for a given code
|
147
147
|
# should this require an OAuth callback URL?
|
148
148
|
get_token_from_server({:code => code, :redirect_uri => options[:redirect_uri] || @oauth_callback_url}, false, options)
|
149
149
|
end
|
150
150
|
|
151
|
-
|
151
|
+
|
152
152
|
# Fetches the access token (ignoring expiration and other info) from Facebook.
|
153
153
|
# Useful when you've received an OAuth code using the server-side authentication process.
|
154
154
|
# @see get_access_token_info
|
155
|
-
#
|
155
|
+
#
|
156
156
|
# @note (see #url_for_oauth_code)
|
157
|
-
#
|
157
|
+
#
|
158
158
|
# @param (see #get_access_token_info)
|
159
159
|
#
|
160
160
|
# @raise (see #get_access_token_info)
|
@@ -169,7 +169,7 @@ module Koala
|
|
169
169
|
|
170
170
|
# Fetches the application's access token, along with any other information provided by Facebook.
|
171
171
|
# See http://developers.facebook.com/docs/authentication/ (search for App Login).
|
172
|
-
#
|
172
|
+
#
|
173
173
|
# @param options any additional parameters to send to Facebook when redeeming the token
|
174
174
|
#
|
175
175
|
# @return the application access token and other information (expiration, etc.)
|
@@ -180,7 +180,7 @@ module Koala
|
|
180
180
|
|
181
181
|
# Fetches the application's access token (ignoring expiration and other info).
|
182
182
|
# @see get_app_access_token_info
|
183
|
-
#
|
183
|
+
#
|
184
184
|
# @param (see #get_app_access_token_info)
|
185
185
|
#
|
186
186
|
# @return the application access token
|
@@ -190,13 +190,40 @@ module Koala
|
|
190
190
|
end
|
191
191
|
end
|
192
192
|
|
193
|
+
# Fetches an access_token with extended expiration time, along with any other information provided by Facebook.
|
194
|
+
# See https://developers.facebook.com/docs/offline-access-deprecation/#extend_token (search for fb_exchange_token).
|
195
|
+
#
|
196
|
+
# @param access_token the access token to exchange
|
197
|
+
# @param options any additional parameters to send to Facebook when exchanging tokens.
|
198
|
+
#
|
199
|
+
# @return the access token with extended expiration time and other information (expiration, etc.)
|
200
|
+
def exchange_access_token_info(access_token, options = {})
|
201
|
+
get_token_from_server({
|
202
|
+
:grant_type => 'fb_exchange_token',
|
203
|
+
:fb_exchange_token => access_token
|
204
|
+
}, true, options)
|
205
|
+
end
|
206
|
+
|
207
|
+
# Fetches an access token with extended expiration time (ignoring expiration and other info).
|
208
|
+
|
209
|
+
# @see exchange_access_token_info
|
210
|
+
#
|
211
|
+
# @param (see #exchange_access_token_info)
|
212
|
+
#
|
213
|
+
# @return A new access token or the existing one, set to expire in 60 days.
|
214
|
+
def exchange_access_token(access_token, options = {})
|
215
|
+
if info = exchange_access_token_info(access_token, options)
|
216
|
+
info["access_token"]
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
193
220
|
# Parses a signed request string provided by Facebook to canvas apps or in a secure cookie.
|
194
221
|
#
|
195
222
|
# @param input the signed request from Facebook
|
196
|
-
#
|
223
|
+
#
|
197
224
|
# @raise RuntimeError if the signature is incomplete, invalid, or using an unsupported algorithm
|
198
|
-
#
|
199
|
-
# @return a hash of the validated request information
|
225
|
+
#
|
226
|
+
# @return a hash of the validated request information
|
200
227
|
def parse_signed_request(input)
|
201
228
|
encoded_sig, encoded_envelope = input.split('.', 2)
|
202
229
|
raise 'SignedRequest: Invalid (incomplete) signature data' unless encoded_sig && encoded_envelope
|
@@ -214,7 +241,7 @@ module Koala
|
|
214
241
|
end
|
215
242
|
|
216
243
|
# Old session key code
|
217
|
-
|
244
|
+
|
218
245
|
# @deprecated Facebook no longer provides session keys.
|
219
246
|
def get_token_info_from_session_keys(sessions, options = {})
|
220
247
|
Koala::Utils.deprecate("Facebook no longer provides session keys. The relevant OAuth methods will be removed in the next release.")
|
@@ -271,7 +298,7 @@ module Koala
|
|
271
298
|
end
|
272
299
|
components
|
273
300
|
end
|
274
|
-
|
301
|
+
|
275
302
|
def parse_unsigned_cookie(fb_cookie)
|
276
303
|
# remove the opening/closing quote
|
277
304
|
fb_cookie = fb_cookie.gsub(/\"/, "")
|
@@ -285,7 +312,7 @@ module Koala
|
|
285
312
|
sig = Digest::MD5.hexdigest(auth_string + @app_secret)
|
286
313
|
sig == components["sig"] && (components["expires"] == "0" || Time.now.to_i < components["expires"].to_i) ? components : nil
|
287
314
|
end
|
288
|
-
|
315
|
+
|
289
316
|
def parse_signed_cookie(fb_cookie)
|
290
317
|
components = parse_signed_request(fb_cookie)
|
291
318
|
if code = components["code"]
|
@@ -315,12 +342,12 @@ module Koala
|
|
315
342
|
str += '=' * (4 - str.length.modulo(4))
|
316
343
|
Base64.decode64(str.tr('-_', '+/'))
|
317
344
|
end
|
318
|
-
|
345
|
+
|
319
346
|
def build_url(base, require_redirect_uri = false, url_options = {})
|
320
|
-
if require_redirect_uri && !(url_options[:redirect_uri] ||= url_options.delete(:callback) || @oauth_callback_url)
|
347
|
+
if require_redirect_uri && !(url_options[:redirect_uri] ||= url_options.delete(:callback) || @oauth_callback_url)
|
321
348
|
raise ArgumentError, "url_for_dialog must get a callback either from the OAuth object or in the parameters!"
|
322
349
|
end
|
323
|
-
|
350
|
+
|
324
351
|
"#{base}?#{Koala::HTTPService.encode_params(url_options)}"
|
325
352
|
end
|
326
353
|
end
|