rfacebook 0.9.0 → 0.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README CHANGED
@@ -1,117 +1,8 @@
1
- ============================== FACEBOOK RAILS CONTROLLER EXTENSIONS NOTES ==============================
1
+ ============================== DOCUMENTATION ==============================
2
2
 
3
- Rails Applications:
4
-
5
- First, set up your Facebook Developer account properly. By properly,
6
- I mean that you need to set your callback URL to be the root of your
7
- Rails application. For example:
8
-
9
- Callback URL >>> http://www.mycrazywebsite.com/ ***NOTE: trailing slash is necessary
10
- Canvas Page URL >>> http://apps.facebook.com/mycrazywebsite
11
-
12
- Then, whenever a user visits
13
-
14
- http://apps.facebook.com/mycrazywebsite/someRailsController/someAction
15
-
16
- ...the Facebook API will call:
17
-
18
- http://www.mycrazywebsite.com/someRailsController/someAction
19
-
20
-
21
- You can get this behavior by installing the new RFacebook gem. After
22
- installing the gem, make your ApplicationController look like this:
23
-
24
- require "facebook_rails_controller_extensions"
25
-
26
- class ApplicationController < ActionController::Base
27
-
28
- # additions to integrate Facebook into controllers
29
- include RFacebook::RailsControllerExtensions
30
-
31
- def facebook_api_key
32
- return "YOUR API KEY HERE"
33
- end
34
-
35
- def facebook_api_secret
36
- return "YOUR API SECRET HERE"
37
- end
38
-
39
- end
40
-
41
- You will have access to 2 new items in your controllers:
42
-
43
- (1) "fbsession"
44
- Contains a FacebookWebSession. Will return false for "is_valid?" if you haven't forced the user to log in.
45
-
46
-
47
- (2) "fbparams"
48
- Contains all the params that are prefixed with "fb_sig_". You shouldn't ever *really* need this, but its there just in case.
49
-
50
-
51
- And, you have a few new filters to try out:
52
-
53
- (1) require_facebook_login
54
- (2) require_facebook_install
55
-
56
- For example, one of my Rails controllers looks like this:
57
-
58
- class FacebookController < ApplicationController
59
-
60
- before_filter :require_facebook_install # require users to install the application (less intrusive is to require_facebook_login)
61
-
62
- def index
63
- xml = fbsession.users_getInfo(:uids => [fbsession.session_user_id], :fields => ["first_name", "last_name"])
64
- @firstName = xml.at("first_name").inner_html
65
- @lastName = xml.at("last_name").inner_html
66
- end
67
-
68
-
69
- end
70
-
71
-
72
-
73
- ============================== FACEBOOK PLATFORM NOTES ==============================
74
-
75
-
76
- ============================== IMPORTANT NOTES ==============================
77
-
78
-
79
- ** THIS IS ESPECIALLY IMPORTANT FOR PEOPLE WHO USED THE OLD CLIENT WHEN IT WAS CALLED "RBook" **
80
-
81
- [1] The RBook name was already taken, so now you need to change any "RBook" references to "RFacebook"
82
-
83
- [2] The desktop app login process is much simpler now:
84
-
85
- fbsession = RFacebook::FacebookDesktopSession.new(APIKEY, APISECRET)
86
- puts fbsession.get_login_url # tell the user to login at this url
87
- # ...after the user logs in...
88
- fbsession.activate
89
-
90
- [3] The "init_with_token" method is now "activate_with_token" (it is a little less confusing with this naming)
91
-
92
- [4] A helpful "NotActivatedException" will be raised if you forget to activate your session in one of the following ways:
93
-
94
- Web: you must call either "activate_with_token" or "activate_with_previous_session"
95
- Desktop: you must call either "activate" or "activate_with_previous_session"
96
-
97
- [5] Infinite sessions are now supported (web and desktop)...
98
-
99
- Web:
100
-
101
- (a) Save the session key to a file or something
102
- (i.e. "keyToSave = fbsession.session_key")
103
-
104
- (b) Normally, you would redirect the user to "get_login_url" and then call "activate_with_token" after the callback.
105
- With an infinite session, skip these two steps and call "fbsession.activate_with_previous_session(keyToSave)" instead.
106
-
107
- Desktop:
108
-
109
- (a) Save the session key and session secret to a file or something
110
- (i.e. "keyToSave = fbsession.session_key" and "secretToSave = fbsession.session_secret")
111
-
112
- (b) Normally, you would redirect the user to "get_login_url" and then call "activate".
113
- With an infinite session, skip these two steps and call "fbsession.activate_with_previous_session(keyToSave, secretToSave)" instead.
3
+ Please see the RFacebook homepage for usage information and other help.
114
4
 
5
+ http://rfacebook.rubyforge.org
115
6
 
116
7
 
117
8
  ============================== LICENSE ==============================
@@ -153,8 +153,8 @@ class FacebookWebSession < FacebookSession
153
153
  # key - the session key to use
154
154
  def activate_with_previous_session(key, uid=nil, expires=nil)
155
155
 
156
- # TODO: what is a good way to handle expiration?
157
- # low priority since the API will give an error code for me...
156
+ # set the expiration
157
+ @session_expires = expires
158
158
 
159
159
  # set the session key
160
160
  @session_key = key
data/lib/facepricot.rb CHANGED
@@ -81,6 +81,7 @@ module RFacebook
81
81
 
82
82
  def initialize(xml)
83
83
  @doc = Hpricot.XML(xml)
84
+ @raw_xml = xml
84
85
  end
85
86
 
86
87
  def method_missing(methodSymbol, *params)
@@ -99,6 +100,10 @@ module RFacebook
99
100
  return FacepricotChain.new(@doc.containers[0])
100
101
  end
101
102
 
103
+ def raw_xml
104
+ return @raw_xml
105
+ end
106
+
102
107
  def to_s
103
108
  return @doc.containers[0].inner_html
104
109
  end
@@ -110,7 +115,6 @@ module RFacebook
110
115
  include FacepricotChaining
111
116
 
112
117
  def initialize(hpricotDoc)
113
- # TODO: does this fix the Hpricot HTML entity escaping problem?
114
118
  super(hpricotDoc.inner_html.gsub("&amp;", "&"))
115
119
  @doc = hpricotDoc
116
120
  end
@@ -29,7 +29,6 @@
29
29
 
30
30
  require "facebook_web_session"
31
31
  require "rfacebook_on_rails/status_manager"
32
- require "rfacebook_on_rails/templates/debug_panel"
33
32
 
34
33
  module RFacebook
35
34
  module Rails
@@ -46,51 +45,58 @@ module RFacebook
46
45
  # SECTION: Template Methods (must be implemented by concrete subclass)
47
46
 
48
47
  def facebook_api_key
49
- raise APIKeyNeededStandardError
48
+ raise APIKeyNeededStandardError, "RFACEBOOK ERROR: when using the RFacebook on Rails plugin, please be sure that you have a facebook.yml file with 'key' defined"
50
49
  end
51
50
 
52
51
  def facebook_api_secret
53
- raise APISecretNeededStandardError
52
+ raise APISecretNeededStandardError, "RFACEBOOK ERROR: when using the RFacebook on Rails plugin, please be sure that you have a facebook.yml file with 'secret' defined"
54
53
  end
55
54
 
56
55
  def facebook_canvas_path
57
- raise APICanvasPathNeededStandardError
56
+ raise APICanvasPathNeededStandardError, "RFACEBOOK ERROR: when using the RFacebook on Rails plugin, please be sure that you have a facebook.yml file with 'canvas_path' defined"
58
57
  end
59
58
 
60
59
  def facebook_callback_path
61
- raise APICallbackNeededStandardError
60
+ raise APICallbackNeededStandardError, "RFACEBOOK ERROR: when using the RFacebook on Rails plugin, please be sure that you have a facebook.yml file with 'callback_path' defined"
62
61
  end
63
62
 
64
63
  def finish_facebook_login
65
- raise APIFinisherNeededStandardError
64
+ raise APIFinisherNeededStandardError, "RFACEBOOK ERROR: in an external Facebook application, you should define finish_facebook_login in your controller (often this is used to redirect to a 'login success' page, but it can also simply do nothing)"
66
65
  end
67
66
 
68
67
 
69
68
 
70
69
  # SECTION: Special Variables
71
70
 
71
+ # Function: fbparams
72
+ # Accessor for all params beginning with "fb_sig_"
73
+ #
74
+ # Returns:
75
+ # A Hash of those parameters, with the fb_sig_ stripped from the keys
72
76
  def fbparams
73
77
 
74
- dup_params = (self.params || {}).dup
75
-
76
78
  # try to get fbparams from the params hash
77
79
  if (!@fbparams || @fbparams.length <= 0)
80
+ dup_params = (self.params || {}).dup
78
81
  @fbparams = rfacebook_session_holder.get_fb_sig_params(dup_params)
79
82
  end
80
83
 
81
84
  # else, try to get fbparams from the cookies hash
82
- # TODO: we don't write anything into the cookie, so this is kind of pointless right now
83
- if (@fbparams.length <= 0)
84
- @fbparams = rfacebook_session_holder.get_fb_sig_params(cookies)
85
+ if (!@fbparams || @fbparams.length <= 0)
86
+ dup_cookies = (self.cookies || {}).dup
87
+ @fbparams = rfacebook_session_holder.get_fb_sig_params(dup_cookies)
85
88
  end
86
-
87
- # TODO: fb_sig_params now includes all friend ids by default, so we can avoid an API call to friends.get
88
- # we should extend FacebookWebSession for Rails to make this optimization
89
-
89
+
90
90
  return @fbparams
91
91
 
92
92
  end
93
93
 
94
+ # Function: fbsession
95
+ # Accessor for a FacebookWebSession that has been activated, either in the Canvas
96
+ # (via fb_sig parameters) or in an external app (via an auth_token).
97
+ #
98
+ # Returns:
99
+ # A FacebookWebSession. You may want to check is_valid? before using it.
94
100
  def fbsession
95
101
 
96
102
  # if we are in the canvas, iframe, or mock ajax, we should be able to activate the session here
@@ -132,11 +138,11 @@ module RFacebook
132
138
  end
133
139
 
134
140
  def in_facebook_canvas?
135
- return (params["fb_sig_in_canvas"] != nil)
141
+ return (params["fb_sig_in_canvas"] != nil)# and params["fb_sig_in_canvas"] == "1")
136
142
  end
137
143
 
138
144
  def in_facebook_frame?
139
- return (params["fb_sig_in_iframe"] != nil or params["fb_sig_in_canvas"] != nil)
145
+ return (params["fb_sig_in_iframe"] != nil)# and params["fb_sig_in_iframe"] == "1")
140
146
  end
141
147
 
142
148
  def in_mock_ajax?
@@ -144,23 +150,38 @@ module RFacebook
144
150
  end
145
151
 
146
152
  def in_external_app?
153
+ # FIXME: once you click away in an iframe app, you are considered to be an external app
154
+ # TODO: read up on the RFacebook hacks for avoiding nested iframes
147
155
  return (!params[:fb_sig] and !in_facebook_frame?)
148
156
  end
149
157
 
158
+ def added_facebook_application?
159
+ return fbparams["added"].to_i == 1
160
+ end
161
+
150
162
  # SECTION: before_filters
151
163
 
152
164
  def handle_facebook_login
153
-
154
- if (!in_facebook_canvas? and !rfacebook_session_holder.is_valid?)
165
+
166
+ if !in_facebook_canvas?
155
167
 
156
168
  if params["auth_token"]
157
169
 
158
170
  # activate with the auth token
159
- RAILS_DEFAULT_LOGGER.debug "** RFACEBOOK INFO: creating a new Facebook session from auth_token"
160
- rfacebook_session_holder.activate_with_token(params["auth_token"])
171
+ RAILS_DEFAULT_LOGGER.debug "** RFACEBOOK INFO: attempting to create a new Facebook session from auth_token"
172
+ staleToken = false
173
+ begin
174
+
175
+ # try to use the auth_token
176
+ rfacebook_session_holder.activate_with_token(params["auth_token"])
177
+
178
+ rescue StandardError => e
179
+ RAILS_DEFAULT_LOGGER.debug "** RFACEBOOK INFO: Tried to use a stale auth_token"
180
+ staleToken = true
181
+ end
161
182
 
162
183
  # template method call upon success
163
- if rfacebook_session_holder.is_valid?
184
+ if (rfacebook_session_holder.is_valid? and !staleToken)
164
185
  RAILS_DEFAULT_LOGGER.debug "** RFACEBOOK INFO: Login was successful, calling finish_facebook_login"
165
186
  if in_external_app?
166
187
  finish_facebook_login
@@ -178,15 +199,13 @@ module RFacebook
178
199
 
179
200
  # warning logs
180
201
  if !rfacebook_session_holder.is_valid?
181
- RAILS_DEFAULT_LOGGER.debug "** RFACEBOOK WARNING: Facebook session could not be activated (from handle_facebook_login)"
182
- elsif params["auth_token"]
183
- # TODO: ignoring is proper when we have already used the auth_token (we could try to reauth and swallow the exception)
184
- # however, we probably want to re-auth if the new auth_token is valid (new user, old user probably logged out)
185
- RAILS_DEFAULT_LOGGER.debug "** RFACEBOOK INFO: received a new auth_token, but we already have a valid session (ignored new auth_token)"
202
+ RAILS_DEFAULT_LOGGER.info "** RFACEBOOK WARNING: Facebook session could not be activated (from handle_facebook_login)"
186
203
  end
187
204
 
188
205
  end
189
206
 
207
+ return true
208
+
190
209
  end
191
210
 
192
211
  def require_facebook_login
@@ -214,45 +233,80 @@ module RFacebook
214
233
  elsif (!fbparams or fbparams.size == 0)
215
234
 
216
235
  RAILS_DEFAULT_LOGGER.debug "** RFACEBOOK WARNING: Failed to activate due to a bad API key or API secret"
217
- render_text facebook_debug_panel
236
+ render :text => facebook_debug_panel
218
237
  return false
219
238
 
220
239
  else
221
240
 
222
241
  RAILS_DEFAULT_LOGGER.debug "** RFACEBOOK INFO: Redirecting to login for canvas app"
223
- render :text => "<fb:redirect url=\"#{sess.get_login_url(:canvas=>true)}\" />"
242
+ redirect_to sess.get_login_url(:canvas=>true)
224
243
  return false
225
244
 
226
245
  end
227
246
  end
228
247
  end
229
-
248
+
249
+ return true
230
250
  end
231
251
 
232
252
  def require_facebook_install
233
- sess = fbsession
234
- if (in_facebook_canvas? and (!sess.is_valid? or (fbparams["added"].to_i != 1)))
235
- render :text => "<fb:redirect url=\"#{sess.get_install_url}\" />"
253
+ if (in_facebook_canvas? or in_facebook_frame?)
254
+ if (!fbsession.is_valid? or !added_facebook_application?)
255
+ redirect_to fbsession.get_install_url
256
+ return false
257
+ end
258
+ else
259
+ RAILS_DEFAULT_LOGGER.info "** RFACEBOOK WARNING: require_facebook_install is not intended for external applications, using require_facebook_login instead"
260
+ return require_facebook_login
236
261
  end
262
+ return true
237
263
  end
238
264
 
239
265
  # SECTION: Facebook Debug Panel
240
266
 
241
267
  def render_with_facebook_debug_panel(options={})
242
- # oldLayout = options[:layout]
243
- # options[:layout] = false
244
268
  begin
245
269
  renderedOutput = render_to_string(options)
246
- rescue # TODO: don't catch-all here, just the exceptions that we originate
247
- renderedOutput = "Errors prevented this page from rendering properly."
270
+ rescue Exception => e
271
+ # TODO: make the backtrace rendering better (Evan Weaver's solution seems good, hopefully he'll allow usage of facebook_exceptions)
272
+ prettyBacktrace = e.backtrace.map do |line|
273
+ cleanLine = line.gsub(RAILS_ROOT, "").gsub("<", "&lt;").gsub(">", "&gt;")
274
+ pieces = cleanLine.split("\n")
275
+ if (pieces and pieces.size> 0)
276
+ cleanLine = "<ul>"
277
+ pieces.each do |piece|
278
+ if matches = /.*[\/\\]+((.*)\:([0-9]+)\:\s*in\s*\`(.*)\')/.match(piece)
279
+ oldPiece = piece
280
+ filename = matches[2]
281
+ line = matches[3]
282
+ method = matches[4]
283
+ piece = "<div class='summary'><strong>#{filename}</strong>:<em>#{line}</em> in <strong>#{method}</strong></div>"
284
+ piece += "<div class='rawsummary'>#{oldPiece}</div>"
285
+ end
286
+ cleanLine += "<li>#{piece}</li>"
287
+ end
288
+ cleanLine += "</ul>"
289
+ end
290
+ "<tr><td>#{cleanLine}</td></tr>"
291
+ end
292
+ renderedOutput = "
293
+ <div class='RFacebook'>
294
+ <div class='backtrace'>
295
+ <table>
296
+ <tr><td>
297
+ <h1>RFacebook <span style='font-weight: normal; color: #6D84B4'>exception backtrace</span></h1>
298
+ </td></tr>
299
+ #{prettyBacktrace}
300
+ </table>
301
+ </div>
302
+ </div>"
248
303
  end
249
- # options[:text] = "#{facebook_debug_panel}#{renderedOutput}"
250
- # options[:layout] = oldLayout
251
304
  render_text "#{facebook_debug_panel}#{renderedOutput}"
252
305
  end
253
306
 
254
307
  def facebook_debug_panel(options={})
255
- return ERB.new(RFacebook::Rails::DEBUG_PANEL_ERB_TEMPLATE).result(Proc.new{}) # TODO: should use File.dirname(__FILE__) + 'templates/debug_panel.rhtml' instead
308
+ template = File.read(File.dirname(__FILE__) + "/templates/debug_panel.rhtml")
309
+ return ERB.new(template).result(Proc.new{})
256
310
  end
257
311
 
258
312
  def facebook_status_manager
@@ -287,12 +341,79 @@ module RFacebook
287
341
  if (!in_facebook_canvas? and rfacebook_session_holder.is_valid?)
288
342
  RAILS_DEFAULT_LOGGER.debug "** RFACEBOOK INFO: persisting Facebook session information into Rails session"
289
343
  session[:rfacebook_session] = @rfacebook_session_holder.dup
290
- session[:rfacebook_session].logger = nil # pstore can't serialize the Rails logger
344
+ session[:rfacebook_session].logger = nil # some session stores can't serialize the Rails logger
291
345
  end
292
346
  end
293
347
 
294
348
 
295
- # SECTION: URL Management
349
+ # SECTION: URL Management
350
+
351
+ def url_for__RFACEBOOK(options={}, *parameters)
352
+
353
+ # error check
354
+ if !options
355
+ RAILS_DEFAULT_LOGGER.info "** RFACEBOOK WARNING: options cannot be nil in call to url_for"
356
+ end
357
+
358
+ # use special URL rewriting when inside the canvas
359
+ # setting the mock_ajax option to true will override this
360
+ # and force usage of regular Rails rewriting
361
+ if (in_facebook_canvas? and !options[:mock_ajax]) #TODO: do something separate for in_facebook_frame?
362
+
363
+ if options.is_a? Hash
364
+ options[:only_path] = true
365
+ end
366
+
367
+ # try to get a regular URL
368
+ path = url_for__ALIASED(options, *parameters)
369
+
370
+ # replace anything that references the callback with the
371
+ # Facebook canvas equivalent (apps.facebook.com/*)
372
+ if (path.starts_with?(self.facebook_callback_path) or "#{path}/".starts_with?(self.facebook_callback_path))
373
+ path.sub!(self.facebook_callback_path, self.facebook_canvas_path)
374
+ path = "http://apps.facebook.com#{path}"
375
+ elsif (path.starts_with?("http://www.facebook.com") or path.starts_with?("https://www.facebook.com"))
376
+ # be sure that URLs that go to some other Facebook service redirect back to the canvas
377
+ if path.include?("?")
378
+ path = "#{path}&canvas=true"
379
+ else
380
+ path = "#{path}?canvas=true"
381
+ end
382
+ elsif (!path.starts_with?("http://") and !path.starts_with?("https://"))
383
+ # default to a full URL (will link externally)
384
+ RAILS_DEFAULT_LOGGER.debug "** RFACEBOOK INFO: failed to get canvas-friendly URL ("+path+") for ["+options.inspect+"], creating an external URL instead"
385
+ path = "#{request.protocol}#{request.host}:#{request.port}#{path}"
386
+ end
387
+
388
+ # mock-ajax rewriting
389
+ elsif options[:mock_ajax]
390
+ options.delete(:mock_ajax) # clear it so it doesnt show up in the url
391
+ options[:only_path] = true
392
+ path = "#{request.protocol}#{request.host}:#{request.port}#{url_for__ALIASED(options, *parameters)}"
393
+
394
+ # regular Rails rewriting
395
+ else
396
+ path = url_for__ALIASED(options, *parameters)
397
+ end
398
+
399
+ return path
400
+ end
401
+
402
+ def redirect_to__RFACEBOOK(options = {}, *parameters)
403
+ if in_facebook_canvas?
404
+
405
+ canvasRedirUrl = url_for(options, *parameters)
406
+ RAILS_DEFAULT_LOGGER.debug "** RFACEBOOK INFO: Canvas redirect to #{canvasRedirUrl}"
407
+ render :text => "<fb:redirect url=\"#{canvasRedirUrl}\" />"
408
+
409
+ else
410
+ RAILS_DEFAULT_LOGGER.debug "** RFACEBOOK INFO: Regular redirect_to"
411
+ redirect_to__ALIASED(options, *parameters)
412
+ end
413
+ end
414
+
415
+
416
+ # SECTION: Extension Helpers
296
417
 
297
418
  CLASSES_EXTENDED = []
298
419
 
@@ -301,7 +422,7 @@ module RFacebook
301
422
  # check for a double include
302
423
  doubleInclude = false
303
424
  CLASSES_EXTENDED.each do |klass|
304
- if base.allocate.is_a?(klass) # TODO: is there a more direct way than allocating an instance and checking is_a?
425
+ if base.allocate.is_a?(klass)
305
426
  doubleInclude = true
306
427
  end
307
428
  end
@@ -310,83 +431,21 @@ module RFacebook
310
431
  RAILS_DEFAULT_LOGGER.info "** RFACEBOOK WARNING: detected double-include of RFacebook controller extensions. Please see instructions for RFacebook on Rails plugin usage (http://rfacebook.rubyforge.org). You may be including the deprecated RFacebook::RailsControllerExtensions in addition to the plugin."
311
432
 
312
433
  else
434
+
435
+ # keep track that we have already extended this class
313
436
  CLASSES_EXTENDED << base
314
437
 
315
438
  # we need to use an eval since we will be overriding ActionController::Base methods
316
439
  # and we need to be able to call the originals
317
440
  base.class_eval '
318
-
319
441
  alias_method(:url_for__ALIASED, :url_for)
320
-
321
- def url_for(options={}, *parameters)
322
-
323
- # error check
324
- if !options
325
- RAILS_DEFAULT_LOGGER.info "** RFACEBOOK WARNING: options cannot be nil in call to url_for"
326
- end
327
-
328
- # use special URL rewriting when inside the canvas
329
- # setting the mock_ajax option to true will override this
330
- # and force usage of regular Rails rewriting
331
- if (in_facebook_canvas? and !options[:mock_ajax]) #TODO: or in_facebook_frame?
332
-
333
- if options.is_a? Hash
334
- options[:only_path] = true
335
- end
336
-
337
- # try to get a regular URL
338
- path = url_for__ALIASED(options, *parameters)
339
-
340
- # replace anything that references the callback with the
341
- # Facebook canvas equivalent (apps.facebook.com/*)
342
- if (path.starts_with?(self.facebook_callback_path) or "#{path}/".starts_with?(self.facebook_callback_path))
343
- path.sub!(self.facebook_callback_path, self.facebook_canvas_path)
344
- path = "http://apps.facebook.com#{path}"
345
- else
346
- # default to a full URL (will link externally)
347
- RAILS_DEFAULT_LOGGER.debug "** RFACEBOOK INFO: failed to get canvas-friendly URL ("+path+") for ["+options.inspect+"], creating an external URL instead"
348
- path = "#{request.protocol}#{request.host}:#{request.port}#{path}"
349
- end
350
-
351
- # mock-ajax rewriting
352
- elsif options[:mock_ajax]
353
- options.delete(:mock_ajax) # clear it so it doesnt show up in the url
354
- options[:only_path] = true
355
- path = "#{request.protocol}#{request.host}:#{request.port}#{url_for__ALIASED(options, *parameters)}"
356
-
357
- # regular Rails rewriting
358
- else
359
- path = url_for__ALIASED(options, *parameters)
360
- end
361
-
362
- return path
363
- end
364
-
442
+ alias_method(:url_for, :url_for__RFACEBOOK)
365
443
 
366
444
  alias_method(:redirect_to__ALIASED, :redirect_to)
367
-
368
- def redirect_to(options = {}, *parameters)
369
- if in_facebook_canvas?
370
-
371
- canvasRedirUrl = url_for(options, *parameters)
372
-
373
- # ensure that we come back to the canvas if we redirect
374
- # to somewhere else on Facebook
375
- if canvasRedirUrl.starts_with?("http://www.facebook.com")
376
- canvasRedirUrl = "#{canvasRedirUrl}&canvas"
377
- end
378
-
379
- RAILS_DEFAULT_LOGGER.debug "** RFACEBOOK INFO: Canvas redirect to #{canvasRedirUrl}"
380
- render :text => "<fb:redirect url=\"#{canvasRedirUrl}\" />"
381
-
382
- else
383
- RAILS_DEFAULT_LOGGER.debug "** RFACEBOOK INFO: Regular redirect_to"
384
- redirect_to__ALIASED(options, *parameters)
385
- end
386
- end
445
+ alias_method(:redirect_to, :redirect_to__RFACEBOOK)
387
446
  '
388
447
 
389
- # ensure that we persist the Facebook session in the Rails session (if possible)
448
+ # ensure that we persist the Facebook session into the Rails session (if possible)
390
449
  base.after_filter(:rfacebook_persist_session_to_rails)
391
450
 
392
451
  # fix third party cookies in IE
@@ -32,49 +32,84 @@ require "rfacebook_on_rails/controller_extensions"
32
32
  require "rfacebook_on_rails/model_extensions"
33
33
  require "rfacebook_on_rails/session_extensions"
34
34
 
35
- module RFacebook
36
- module Rails
37
- module Plugin
38
- #####
39
- module ControllerExtensions
40
- def facebook_api_key
41
- FACEBOOK["key"] || super
42
- end
43
- def facebook_api_secret
44
- FACEBOOK["secret"] || super
45
- end
46
- def facebook_canvas_path
47
- FACEBOOK["canvas_path"] || super
48
- end
49
- def facebook_callback_path
50
- FACEBOOK["callback_path"] || super
51
- end
52
- end
53
- #####
54
- module ModelExtensions
55
- def facebook_api_key
56
- FACEBOOK["key"] || super
57
- end
58
- def facebook_api_secret
59
- FACEBOOK["secret"] || super
60
- end
61
- end
62
- #####
63
- module ViewExtensions
64
- end
35
+ module RFacebook::Rails::Plugin
36
+
37
+ module ControllerExtensions
38
+ def facebook_api_key
39
+ FACEBOOK["key"] || super
40
+ end
41
+ def facebook_api_secret
42
+ FACEBOOK["secret"] || super
43
+ end
44
+ def facebook_canvas_path
45
+ FACEBOOK["canvas_path"] || super
46
+ end
47
+ def facebook_callback_path
48
+ FACEBOOK["callback_path"] || super
49
+ end
50
+ end
51
+
52
+ module ModelExtensions
53
+ def facebook_api_key
54
+ FACEBOOK["key"] || super
55
+ end
56
+ def facebook_api_secret
57
+ FACEBOOK["secret"] || super
65
58
  end
66
59
  end
60
+
61
+ module ViewExtensions
62
+ end
63
+
64
+ end
65
+
66
+ # inject methods to Rails MVC classes
67
+ ActionView::Base.send(:include, RFacebook::Rails::ViewExtensions)
68
+ ActionView::Base.send(:include, RFacebook::Rails::Plugin::ViewExtensions)
69
+
70
+ ActionController::Base.send(:include, RFacebook::Rails::ControllerExtensions)
71
+ ActionController::Base.send(:include, RFacebook::Rails::Plugin::ControllerExtensions)
72
+
73
+ ActiveRecord::Base.send(:include, RFacebook::Rails::ModelExtensions)
74
+ ActiveRecord::Base.send(:include, RFacebook::Rails::Plugin::ModelExtensions)
75
+
76
+ # inject methods to Rails session management classes
77
+ CGI::Session.send(:include, RFacebook::Rails::SessionExtensions)
78
+
79
+ # TODO: document SessionStoreExtensions as API so that anyone can patch their own custom session container in addition to these
80
+ CGI::Session::PStore.send(:include, RFacebook::Rails::SessionStoreExtensions)
81
+ CGI::Session::ActiveRecordStore.send(:include, RFacebook::Rails::SessionStoreExtensions)
82
+ CGI::Session::DRbStore.send(:include, RFacebook::Rails::SessionStoreExtensions)
83
+ CGI::Session::FileStore.send(:include, RFacebook::Rails::SessionStoreExtensions)
84
+ CGI::Session::MemoryStore.send(:include, RFacebook::Rails::SessionStoreExtensions)
85
+ begin
86
+ CGI::Session::MemCacheStore.send(:include, RFacebook::Rails::SessionStoreExtensions)
87
+ rescue
88
+ RAILS_DEFAULT_LOGGER.debug "** RFACEBOOK INFO: It looks like you don't have memcache-client, so MemCacheStore was not extended"
67
89
  end
68
90
 
69
- # load Facebook configuration file
91
+ # load Facebook configuration file (credit: Evan Weaver)
70
92
  begin
71
93
  FACEBOOK = YAML.load_file("#{RAILS_ROOT}/config/facebook.yml")[RAILS_ENV]
72
94
  rescue
73
95
  FACEBOOK = {}
74
96
  end
75
97
 
98
+ # parse for full URLs in facebook.yml (multiple people have made this mistake)
99
+ def ensureRelativePath(path)
100
+ if matchData = /(\w+)(\:\/\/)([\w0-9\.]+)([\:0-9]*)(.*)/.match(path)
101
+ relativePath = matchData.captures[4]
102
+ RAILS_DEFAULT_LOGGER.debug "** RFACEBOOK INFO: It looks like you used a full URL (#{path}) in facebook.yml. RFacebook expected a relative path and has automatically converted this URL to #{relativePath}."
103
+ return relativePath
104
+ else
105
+ return path
106
+ end
107
+ end
108
+
109
+ FACEBOOK["canvas_path"] = ensureRelativePath(FACEBOOK["canvas_path"])
110
+ FACEBOOK["callback_path"] = ensureRelativePath(FACEBOOK["callback_path"])
111
+
76
112
  # make sure the paths have leading and trailing slashes
77
- # TODO: also parse for full URLs beginning with HTTP (see: http://rubyforge.org/tracker/index.php?func=detail&aid=13096&group_id=3607&atid=13796)
78
113
  def ensureLeadingAndTrailingSlashesForPath(path)
79
114
  if (path and path.size>0)
80
115
  if !path.starts_with?("/")
@@ -90,38 +125,4 @@ def ensureLeadingAndTrailingSlashesForPath(path)
90
125
  end
91
126
 
92
127
  FACEBOOK["canvas_path"] = ensureLeadingAndTrailingSlashesForPath(FACEBOOK["canvas_path"])
93
- FACEBOOK["callback_path"] = ensureLeadingAndTrailingSlashesForPath(FACEBOOK["callback_path"])
94
-
95
- # inject methods to Rails MVC classes
96
- ActionView::Base.send(:include, RFacebook::Rails::ViewExtensions)
97
- ActionView::Base.send(:include, RFacebook::Rails::Plugin::ViewExtensions)
98
-
99
- ActionController::Base.send(:include, RFacebook::Rails::ControllerExtensions)
100
- ActionController::Base.send(:include, RFacebook::Rails::Plugin::ControllerExtensions)
101
-
102
- ActiveRecord::Base.send(:include, RFacebook::Rails::ModelExtensions)
103
- ActiveRecord::Base.send(:include, RFacebook::Rails::Plugin::ModelExtensions)
104
-
105
- # inject methods to patch Rails session containers
106
- # TODO: document this as API so that everyone knows how to patch their own custom session container
107
- module RFacebook::Rails::Toolbox
108
- def self.patch_session_store_class(sessionStoreKlass)
109
- sessionStoreKlass.send(:include, RFacebook::Rails::SessionStoreExtensions)
110
- sessionStoreKlass.class_eval'
111
- alias :initialize__ALIASED :initialize
112
- alias :initialize :initialize__RFACEBOOK
113
- '
114
- end
115
- end
116
-
117
- # patch as many session stores as possible
118
- RFacebook::Rails::Toolbox::patch_session_store_class(CGI::Session::PStore)
119
- RFacebook::Rails::Toolbox::patch_session_store_class(CGI::Session::ActiveRecordStore)
120
- RFacebook::Rails::Toolbox::patch_session_store_class(CGI::Session::DRbStore)
121
- RFacebook::Rails::Toolbox::patch_session_store_class(CGI::Session::FileStore)
122
- RFacebook::Rails::Toolbox::patch_session_store_class(CGI::Session::MemoryStore)
123
- begin
124
- RFacebook::Rails::Toolbox::patch_session_store_class(CGI::Session::MemCacheStore)
125
- rescue
126
- # TODO: this needs to be handled better
127
- end
128
+ FACEBOOK["callback_path"] = ensureLeadingAndTrailingSlashesForPath(FACEBOOK["callback_path"])
@@ -101,17 +101,7 @@ production:
101
101
 
102
102
  puts "======================================================"
103
103
  puts "Tunneling #{remoteHost}:#{remotePort} to 0.0.0.0:#{localPort}"
104
-
105
- # TODO: learn more about autossh
106
- # if system("autossh -V")
107
- # cmd = "autossh -M 8888"
108
- # puts "(autossh found, using port 8888 to monitor it)"
109
- # else
110
- # cmd = "ssh"
111
- # puts "(autossh not found, using ssh instead)"
112
- # end
113
- cmd = "ssh"
114
-
104
+
115
105
  puts
116
106
  puts "NOTES:"
117
107
  puts "* ensure that you have Rails running on your local machine at port #{localPort}"
@@ -119,19 +109,17 @@ production:
119
109
  puts "* use ctrl-c to quit the tunnel"
120
110
  puts "* if you have problems creating the tunnel, you may need to add the following to /etc/ssh/sshd_config on your server:"
121
111
  puts "
122
-
123
112
  GatewayPorts clientspecified
124
113
 
125
114
  "
126
115
  puts "* if you have problems with #{remoteHost} timing out your ssh connection, add the following lines to your '~/.ssh/config' file:"
127
116
  puts "
128
-
129
117
  Host #{remoteHost}
130
118
  ServerAliveInterval 120
131
119
 
132
120
  "
133
121
  puts "======================================================"
134
- exec "#{cmd} -nNT -g -R *:#{remotePort}:0.0.0.0:#{localPort} #{remoteUsername}@#{remoteHost}"
122
+ exec "ssh -nNT -g -R *:#{remotePort}:0.0.0.0:#{localPort} #{remoteUsername}@#{remoteHost}"
135
123
 
136
124
 
137
125
  end
@@ -30,21 +30,20 @@
30
30
  require "digest/md5"
31
31
  require "cgi"
32
32
 
33
- # patch up the CGI session module to use Facebook session keys when cookies aren't available
34
- class CGI::Session
35
-
36
- alias :initialize__ALIASED :initialize
37
- alias :new_session__ALIASED :new_session
38
-
39
- def using_facebook_session_id?
40
- return @using_fb_session_id
41
- end
33
+ module RFacebook::Rails::SessionExtensions
42
34
 
35
+ # SECTION: New Methods
43
36
  def force_to_be_new!
44
37
  @force_to_be_new = true
45
38
  end
46
39
 
47
- def new_session
40
+ def using_facebook_session_id?
41
+ return (@fb_sig_session_id != nil)
42
+ end
43
+
44
+ # SECTION: Base Overrides
45
+
46
+ def new_session__RFACEBOOK
48
47
  if @force_to_be_new
49
48
  return true
50
49
  else
@@ -52,50 +51,152 @@ class CGI::Session
52
51
  end
53
52
  end
54
53
 
55
- def initialize(request, options = {})
54
+ def initialize__RFACEBOOK(request, options = {})
56
55
 
57
- # check the environment to find a Facebook sig_session_key (credit: Blake Carlson and David Troy)
58
- fbsessionId = nil
59
- ["RAW_POST_DATA", "QUERY_STRING", "HTTP_REFERER"].each do |tableSource|
60
- if request.env_table[tableSource]
61
- fbsessionId = CGI::parse(request.env_table[tableSource]).fetch('fb_sig_session_key'){[]}.first
62
- RAILS_DEFAULT_LOGGER.debug "** RFACEBOOK INFO: checked #{tableSource} for Facebook session id and got [#{fbsessionId}]"
56
+ # only try to use the sig when we don't have a cookie (i.e., in the canvas)
57
+ if in_facebook_canvas?(request)
58
+
59
+ # try a few different ways
60
+ RAILS_DEFAULT_LOGGER.debug "** RFACEBOOK INFO: Attempting to use fb_sig_session_key as a session key, since we are inside the canvas"
61
+ @fb_sig_session_id = lookup_request_parameter(request, "fb_sig_session_key")
62
+
63
+ # we only want to change the session_id if we got one from the fb_sig
64
+ if @fb_sig_session_id
65
+ options["session_id"] = Digest::MD5.hexdigest(@fb_sig_session_id)
66
+ RAILS_DEFAULT_LOGGER.debug "** RFACEBOOK INFO: using MD5 of fb_sig_session_key [#{options['session_id']}] for the Rails session id"
63
67
  end
64
- break if fbsessionId
65
- end
66
-
67
- # we only want to change the session_id if we got one from the fb_sig
68
- if fbsessionId
69
- options['session_id'] = Digest::MD5.hexdigest(fbsessionId)
70
- @using_facebook_session_id = true
71
- RAILS_DEFAULT_LOGGER.debug "** RFACEBOOK INFO: using MD5 of Facebook session id [#{options['session_id']}] for the Rails session id}"
72
68
  end
73
69
 
74
70
  # now call the default Rails session initialization
75
71
  initialize__ALIASED(request, options)
76
72
  end
73
+
74
+ # SECTION: Extension Helpers
75
+
76
+ def self.included(base)
77
+ base.class_eval'
78
+ alias :initialize__ALIASED :initialize
79
+ alias :initialize :initialize__RFACEBOOK
80
+
81
+ alias :new_session__ALIASED :new_session
82
+ alias :new_session :new_session__RFACEBOOK
83
+ '
84
+ end
85
+
86
+ # SECTION: Private Helpers
87
+
88
+ private
89
+
90
+ # TODO: it seems that there should be a better way to just get raw parameters
91
+ # (not sure why the nil key bug doesn't seem to be fixed in my installation)
92
+ # ...also, there seems to be some interaction with Mongrel as well that can
93
+ # cause the parameters to fail
94
+ def lookup_request_parameter(request, key)
95
+
96
+ # Depending on the user's version of Rails, this may fail due to a bug in Rails parsing of
97
+ # nil keys: http://dev.rubyonrails.org/ticket/5137, so we have a backup plan
98
+ begin
99
+
100
+ # this should work on most Rails installations
101
+ return request.parameters[key]
102
+
103
+ rescue
104
+
105
+ # this saves most other Rails installations
106
+ begin
107
+
108
+ retval = nil
109
+
110
+ # try accessing raw_post (doesn't work in some mongrel installations)
111
+ if request.respond_to?(:raw_post)
112
+ return CGI::parse(request.send(:raw_post)).fetch(key){[]}.first
113
+ end
114
+
115
+ # try accessing the raw environment table
116
+ if !retval
117
+ envTable = nil
118
+
119
+ envTable = request.send(:env_table) if request.respond_to?(:env_table)
120
+ if !envTable
121
+ envTable = request.send(:env) if request.respond_to?(:env)
122
+ end
123
+
124
+ if envTable
125
+ # credit: Blake Carlson and David Troy
126
+ ["RAW_POST_DATA", "QUERY_STRING"].each do |tableSource|
127
+ if envTable[tableSource]
128
+ retval = CGI::parse(envTable[tableSource]).fetch(key){[]}.first
129
+ end
130
+ break if retval
131
+ end
132
+ end
133
+ end
134
+
135
+ # hopefully we got a parameter
136
+ return retval
137
+
138
+ rescue
139
+
140
+ # for some reason, we just can't get the parameters
141
+ RAILS_DEFAULT_LOGGER.info "** RFACEBOOK WARNING: failed to access request.parameters"
142
+ return nil
143
+
144
+ end
145
+ end
146
+ end
147
+
148
+ def in_facebook_canvas?(request)
149
+ # TODO: we should probably be checking the fb_sig for validity here (template method needed)
150
+ # ...we can only do this if we can grab the equivalent of a params hash
151
+ return lookup_request_parameter(request, "fb_sig_in_canvas")
152
+ end
153
+
77
154
  end
78
155
 
79
156
  # Module: SessionStoreExtensions
80
157
  #
81
- # Special initialize method that forces any session store to use the Facebook session
158
+ # Special initialize method that attempts to force any session store to use the Facebook session
82
159
  module RFacebook::Rails::SessionStoreExtensions
160
+
161
+ # SECTION: Base Overrides
162
+
83
163
  def initialize__RFACEBOOK(session, options, *extraParams)
84
- begin
85
- RAILS_DEFAULT_LOGGER.debug "** RFACEBOOK INFO: inside #{self.class.to_s}, with session_id: #{session.session_id}, new_session = #{session.new_session ? 'yes' : 'no'}"
86
- initialize__ALIASED(session, options, *extraParams)
87
- rescue Exception => e
164
+
165
+ if session.using_facebook_session_id?
166
+
167
+ # we got the fb_sig_session_key, so alter Rails' behavior to use that key to make a session
88
168
  begin
89
- RAILS_DEFAULT_LOGGER.debug "** RFACEBOOK INFO: failed to init #{self.class.to_s} session, trying to make a new session"
90
- # FIXME: technically this might be a security problem, since an external browser can grab any unused session id they want
91
- if session.session_id
92
- session.force_to_be_new!
93
- end
169
+ RAILS_DEFAULT_LOGGER.debug "** RFACEBOOK INFO: using fb_sig_session_key for the #{self.class.to_s} session (session_id=#{session.session_id})"
94
170
  initialize__ALIASED(session, options, *extraParams)
95
- rescue Exception => e
96
- RAILS_DEFAULT_LOGGER.debug "** RFACEBOOK INFO: failed to create a new #{self.class.to_s} session falling back to default Rails behavior"
97
- raise e
171
+ rescue Exception => e
172
+ begin
173
+ RAILS_DEFAULT_LOGGER.debug "** RFACEBOOK INFO: failed to initialize session (session_id=#{session.session_id}), trying to force a new session"
174
+ if session.session_id
175
+ session.force_to_be_new!
176
+ end
177
+ initialize__ALIASED(session, options, *extraParams)
178
+ rescue Exception => e
179
+ RAILS_DEFAULT_LOGGER.debug "** RFACEBOOK INFO: failed to force a new session, falling back to default Rails behavior"
180
+ raise e
181
+ end
98
182
  end
183
+
184
+ else
185
+
186
+ # we didn't get the fb_sig_session_key, do not alter Rails' behavior
187
+ RAILS_DEFAULT_LOGGER.debug "** RFACEBOOK INFO: using default Rails sessions (since we didn't find an fb_sig_session_key in the environment)"
188
+ initialize__ALIASED(session, options, *extraParams)
189
+
99
190
  end
100
191
  end
192
+
193
+ # SECTION: Extension Helpers
194
+
195
+ def self.included(base)
196
+ base.class_eval'
197
+ alias :initialize__ALIASED :initialize
198
+ alias :initialize :initialize__RFACEBOOK
199
+ '
200
+ end
201
+
101
202
  end
@@ -1,36 +1,3 @@
1
- # Copyright (c) 2007, Matt Pizzimenti (www.livelearncode.com)
2
- # All rights reserved.
3
- #
4
- # Redistribution and use in source and binary forms, with or without modification,
5
- # are permitted provided that the following conditions are met:
6
- #
7
- # Redistributions of source code must retain the above copyright notice,
8
- # this list of conditions and the following disclaimer.
9
- #
10
- # Redistributions in binary form must reproduce the above copyright notice,
11
- # this list of conditions and the following disclaimer in the documentation
12
- # and/or other materials provided with the distribution.
13
- #
14
- # Neither the name of the original author nor the names of contributors
15
- # may be used to endorse or promote products derived from this software
16
- # without specific prior written permission.
17
- #
18
- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19
- # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20
- # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21
- # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22
- # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23
- # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24
- # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25
- # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26
- # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27
- # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
- #
29
-
30
- module RFacebook
31
- module Rails
32
- DEBUG_PANEL_ERB_TEMPLATE = <<-end_info
33
-
34
1
  <style type="text/css">
35
2
 
36
3
  .RFacebook .environment
@@ -136,6 +103,66 @@ module RFacebook
136
103
  color: black;
137
104
  }
138
105
 
106
+ .RFacebook .backtrace
107
+ {
108
+ border-collapse: collapse;
109
+ background-color: #3B5998;
110
+ color: white;
111
+ }
112
+
113
+ .RFacebook .backtrace
114
+ {
115
+ padding: 30px;
116
+ background: #3B5998;
117
+ }
118
+
119
+ .RFacebook .backtrace h1
120
+ {
121
+ margin: 0px 0px 5px 0px;
122
+ padding: 0px;
123
+
124
+ color: white;
125
+ font-size: 1.6em;
126
+ }
127
+
128
+ /*
129
+ .RFacebook table.backtrace td
130
+ {
131
+ padding: 10px 2px 10px 2px;
132
+ border-width: 1px 0px 1px 0px;
133
+
134
+ border-style: solid;
135
+ border-color: #ccc;
136
+ }
137
+ */
138
+
139
+ .RFacebook .backtrace div.summary
140
+ {
141
+ font-size: 1.2em;
142
+ padding: 2px;
143
+ color: white;
144
+ }
145
+
146
+ .RFacebook .backtrace div.rawsummary
147
+ {
148
+ font-size: 0.7em;
149
+ color: #6D84B4;
150
+ padding-left: 5px;
151
+ }
152
+
153
+ .RFacebook ul
154
+ {
155
+ margin: 0px;
156
+ padding: 0px;
157
+ list-style-type: none;
158
+ }
159
+
160
+ .RFacebook ul li
161
+ {
162
+ list-style-type: none;
163
+ padding: 5px;
164
+ }
165
+
139
166
  </style>
140
167
 
141
168
  <div class="RFacebook">
@@ -170,9 +197,9 @@ module RFacebook
170
197
  <% end %>
171
198
  </td>
172
199
  <td class="value">
173
- <% if statusCheck.message.class == String %>
200
+ <% if statusCheck.message.is_a? String %>
174
201
  <%= statusCheck.message %>
175
- <% elsif statusCheck.message.class == Hash %>
202
+ <% elsif statusCheck.message.is_a? Hash %>
176
203
  <table class="details">
177
204
  <% statusCheck.message.each do |k,v| %>
178
205
  <tr>
@@ -191,20 +218,3 @@ module RFacebook
191
218
 
192
219
  </div>
193
220
  </div>
194
-
195
-
196
-
197
-
198
-
199
-
200
-
201
-
202
-
203
-
204
-
205
-
206
-
207
- end_info
208
-
209
- end
210
- end
@@ -53,14 +53,14 @@ module RFacebook
53
53
 
54
54
  def image_path(*params)
55
55
  path = super(*params)
56
- if (in_facebook_canvas? or in_mock_ajax?) # TODO: or in_facebook_frame?)
56
+ if (in_facebook_canvas? or in_mock_ajax?)
57
57
  path = "#{request.protocol}#{request.host_with_port}#{path}"
58
58
  end
59
59
  return path
60
60
  end
61
61
 
62
- def rfacebook_debug_panel(options={})
63
- return @controller.rfacebook_debug_panel(options)
62
+ def facebook_debug_panel(options={})
63
+ return @controller.facebook_debug_panel(options)
64
64
  end
65
65
 
66
66
  end
metadata CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.1
3
3
  specification_version: 1
4
4
  name: rfacebook
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.9.0
7
- date: 2007-08-18 00:00:00 -05:00
6
+ version: 0.9.1
7
+ date: 2007-08-20 00:00:00 -04:00
8
8
  summary: A Ruby interface to the Facebook API v1.0+ (F8 and beyond). Works with RFacebook on Rails plugin (see rfacebook.rubyforge.org).
9
9
  require_paths:
10
10
  - lib
@@ -47,7 +47,7 @@ files:
47
47
  - lib/rfacebook_on_rails/plugin/rake.rb
48
48
  - lib/rfacebook_on_rails/plugin/Rakefile.rb
49
49
  - lib/rfacebook_on_rails/plugin/uninstall.rb
50
- - lib/rfacebook_on_rails/templates/debug_panel.rb
50
+ - lib/rfacebook_on_rails/templates/debug_panel.rhtml
51
51
  - README
52
52
  test_files: []
53
53