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.
@@ -1,13 +1,10 @@
1
1
  rvm:
2
- - 1.8.7 # (current default)
2
+ - 1.8.7
3
3
  - 1.9.2
4
4
  - 1.9.3
5
5
  - ruby-head
6
- - rbx
7
- - rbx-2.0
8
- - ree
9
- - jruby
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
@@ -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 get_connections(id, connection_name, args = {}, options = {})
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 #get_connections)
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 #get_connections)
127
- # @param args (see #get_connections)
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 #get_connections)
140
- #
140
+ # @note (see #get_connection)
141
+ #
141
142
  # @param id (see #get_object)
142
- # @param connection_name (see #get_connections)
143
- # @args (see #get_connections)
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)
@@ -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("&")
@@ -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