Module: RPlatform::Rails::ControllerExtensions
- Defined in:
- lib/rplatform_rails/controller_extensions.rb
Constant Summary collapse
- FACEBOOK_SIGNATURE_TIME_SLACK =
signatures are allowed at most a 30 minute delta in the sig_time
48*3600
Instance Method Summary collapse
-
#added_facebook_application? ⇒ Boolean
returns true if the user has added (installed) the current application.
-
#facebook_api_key ⇒ Object
Facebook API key, as parsed from the YAML file.
-
#facebook_api_secret ⇒ Object
Facebook API secret, as parsed from the YAML file.
-
#facebook_callback_path ⇒ Object
Facebook callback path, as parsed from the YAML file (may be nil if this application is an external app).
-
#facebook_canvas_path ⇒ Object
Facebook canvas path, as parsed from the YAML file (may be nil if this application is an external app).
-
#facebook_debug_panel ⇒ Object
returns HTML containing information about the current environment (API key, API secret, etc.).
-
#facebook_platform_signature_verified? ⇒ Boolean
returns true if the fb_sig_* parameters have been verified with a correct signature.
-
#facebook_status_manager ⇒ Object
used for the debug panel, runs a series of tests to determine what might be wrong with your particular environment.
-
#fbparams ⇒ Object
Accessor for all params beginning with “fb_sig_”.
-
#fbsession ⇒ Object
Gives direct access to a Facebook session (of type RFacebook::FacebookWebSession) for this user.
-
#finish_facebook_login ⇒ Object
this is a callback method for EXTERNAL web applications, you should define this method to do something (for example, redirect the user to your main page, etc.).
- #get_network ⇒ Object
- #get_network_from_yml ⇒ Object
-
#in_ajax? ⇒ Boolean
returns true if the current request is an FBJS ajax request.
-
#in_external_app? ⇒ Boolean
returns true if the user is viewing the page from an external website.
-
#in_facebook_canvas? ⇒ Boolean
returns true if the user is viewing the page in the canvas.
-
#in_facebook_frame? ⇒ Boolean
returns true if the user is viewing the page in an iframe.
-
#in_mock_ajax? ⇒ Boolean
returns true if the current request is a mock-ajax request.
-
#log_out_of_facebook ⇒ Object
clear the current session so that a new user can log in.
-
#render_with_facebook_debug_panel(options = {}) ⇒ Object
special rendering method to use when debugging.
-
#require_facebook_install(urlOptions = {}) ⇒ Object
force the user to install your Facebook application.
-
#require_facebook_login(urlOptions = {}) ⇒ Object
force the user to log in to Facebook.
Instance Method Details
#added_facebook_application? ⇒ Boolean
returns true if the user has added (installed) the current application
214 215 216 217 |
# File 'lib/rplatform_rails/controller_extensions.rb', line 214 def added_facebook_application? # TODO: make this check fbparams instead (signature is validated there) return (params and params["fb_sig_added"] == "1") end |
#facebook_api_key ⇒ Object
Facebook API key, as parsed from the YAML file
64 65 66 |
# File 'lib/rplatform_rails/controller_extensions.rb', line 64 def facebook_api_key NETWORKS[get_network]["key"] end |
#facebook_api_secret ⇒ Object
Facebook API secret, as parsed from the YAML file
69 70 71 |
# File 'lib/rplatform_rails/controller_extensions.rb', line 69 def facebook_api_secret NETWORKS[get_network]["secret"] end |
#facebook_callback_path ⇒ Object
Facebook callback path, as parsed from the YAML file (may be nil if this application is an external app)
79 80 81 |
# File 'lib/rplatform_rails/controller_extensions.rb', line 79 def facebook_callback_path NETWORKS[get_network]["callback_path"] end |
#facebook_canvas_path ⇒ Object
Facebook canvas path, as parsed from the YAML file (may be nil if this application is an external app)
74 75 76 |
# File 'lib/rplatform_rails/controller_extensions.rb', line 74 def facebook_canvas_path NETWORKS[get_network]["canvas_path"] end |
#facebook_debug_panel ⇒ Object
returns HTML containing information about the current environment (API key, API secret, etc.)
309 310 311 312 313 |
# File 'lib/rplatform_rails/controller_extensions.rb', line 309 def facebook_debug_panel templatePath = File.join(File.dirname(__FILE__), '..', '..', 'templates', 'debug_panel.rhtml') template = File.read(templatePath) return ERB.new(template).result(Proc.new{}) end |
#facebook_platform_signature_verified? ⇒ Boolean
returns true if the fb_sig_* parameters have been verified with a correct signature
227 228 229 |
# File 'lib/rplatform_rails/controller_extensions.rb', line 227 def facebook_platform_signature_verified? return (fbparams.size != 0) end |
#facebook_status_manager ⇒ Object
used for the debug panel, runs a series of tests to determine what might be wrong with your particular environment
317 318 319 320 321 322 323 324 325 326 327 328 329 330 |
# File 'lib/rplatform_rails/controller_extensions.rb', line 317 def facebook_status_manager checks = [ SessionStatusCheck.new(self), (FacebookParamsStatusCheck.new(self) unless (!in_facebook_canvas? and !in_facebook_frame?)), InCanvasStatusCheck.new(self), InFrameStatusCheck.new(self), (CanvasPathStatusCheck.new(self) unless (!in_facebook_canvas? or !in_facebook_frame?)), (CallbackPathStatusCheck.new(self) unless (!in_facebook_canvas? or !in_facebook_frame?)), (FinishFacebookLoginStatusCheck.new(self) unless (in_facebook_canvas? or in_facebook_frame?)), APIKeyStatusCheck.new(self), APISecretStatusCheck.new(self) ].compact return StatusManager.new(checks) end |
#fbparams ⇒ Object
Accessor for all params beginning with “fb_sig_”. The signature is verified to prevent replay attacks and other calls that don’t originate from Facebook. (the “fb_sig_” prefix is removed from the parameter name)
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
# File 'lib/rplatform_rails/controller_extensions.rb', line 91 def fbparams # check to see if we have parsed the fb_sig_ params yet if @fbparams.nil? # first, look in the params hash sourceParams = (params || {}).dup @fbparams = parse_fb_sig_params(sourceParams) # second, look in the cookies hash if @fbparams.size == 0 sourceParams = ( || {}).dup @fbparams = parse_fb_sig_params(sourceParams) end # ensure that these parameters aren't being replayed sigTime = @fbparams["time"] ? @fbparams["time"].to_i : nil if (sigTime.nil? or (sigTime > 0 and Time.now.to_i > (sigTime + FACEBOOK_SIGNATURE_TIME_SLACK))) # signature expired, fbparams are not valid @fbparams = {} end # ensure that signature validates properly from Facebook expectedSignature = fbsession_holder.signature(@fbparams) actualSignature = sourceParams["fb_sig"] if (actualSignature.nil? or expectedSignature != actualSignature) # signatures didn't match, fbparams are not valid @fbparams = {} end end # as a last resort, if we are an iframe app, we might have saved the # fbparams to the session previously if @fbparams.size == 0 @fbparams ||= session[:_rfacebook_fbparams] || {} end # return fbparams (may or may not be populated) return @fbparams end |
#fbsession ⇒ Object
Gives direct access to a Facebook session (of type RFacebook::FacebookWebSession) for this user. An attempt will be made to activate this session (either using canvas params or an auth_token for external apps), but if the user has not been forced to log in to Facebook, the session will NOT be ready for usage. To double-check this, simply call ‘ready?’ to see if the session is okay to use.
136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 |
# File 'lib/rplatform_rails/controller_extensions.rb', line 136 def fbsession # do a check to ensure that we nil out the fbsession_holder in case there is a new user visiting if session[:_rfacebook_fbsession_holder] and fbparams["session_key"] and session[:_rfacebook_fbsession_holder].session_key != fbparams["session_key"] session[:_rfacebook_fbsession_holder] = nil end # if we have verified fb_sig_* params, we should be able to activate the session here if (!fbsession_holder.ready? and facebook_platform_signature_verified?) # then try to activate the session somehow (or retrieve from previous state) # these might be nil facebookUserId = fbparams["user"] facebookSessionKey = fbparams["session_key"] expirationTime = fbparams["expires"] # activate the session if we got all the pieces of information we needed if (facebookUserId and facebookSessionKey and expirationTime) fbsession_holder.activate_with_previous_session(facebookSessionKey, facebookUserId, expirationTime) RAILS_DEFAULT_LOGGER.debug "** RFACEBOOK INFO: Activated session from inside the canvas (user=#{facebookUserId}, session_key=#{facebookSessionKey}, expires=#{expirationTime})" # warn that we couldn't get a valid Facebook session since we were missing data else RAILS_DEFAULT_LOGGER.debug "** RFACEBOOK WARNING: Tried to get a valid Facebook session from POST params, but failed" end end # if we still don't have a session, check the Rails session # (used for external and iframe apps when fb_sig POST params weren't present) if (!fbsession_holder.ready? and session[:_rfacebook_fbsession_holder] and session[:_rfacebook_fbsession_holder].ready?) RAILS_DEFAULT_LOGGER.debug "** RFACEBOOK INFO: grabbing Facebook session from Rails session" @fbsession_holder = session[:_rfacebook_fbsession_holder] @fbsession_holder.logger = RAILS_DEFAULT_LOGGER end # set the network that should be used for this session REVIEW There is likely a better way to do this fbsession_holder.network = get_network # if all went well, we should definitely have a valid Facebook session object return fbsession_holder end |
#finish_facebook_login ⇒ Object
this is a callback method for EXTERNAL web applications, you should define this method to do something (for example, redirect the user to your main page, etc.)
233 234 235 |
# File 'lib/rplatform_rails/controller_extensions.rb', line 233 def finish_facebook_login # do nothing by default end |
#get_network ⇒ Object
42 43 44 45 46 |
# File 'lib/rplatform_rails/controller_extensions.rb', line 42 def get_network network = get_network_from_yml # check to see if there's a network configured for the given value. If not then default to facebook NETWORKS[network].nil? ? 'facebook' : network end |
#get_network_from_yml ⇒ Object
48 49 50 51 52 53 54 55 56 |
# File 'lib/rplatform_rails/controller_extensions.rb', line 48 def get_network_from_yml # host_parts = request.host.split('.') # network = host_parts[0] # TODO: finish this # networks = NETWORKS # networks.each {|n| n.value?()} return 'facebook' end |
#in_ajax? ⇒ Boolean
returns true if the current request is an FBJS ajax request
201 202 203 204 |
# File 'lib/rplatform_rails/controller_extensions.rb', line 201 def in_ajax? # TODO: make this check fbparams instead (signature is validated there) return (params and params["fb_sig_is_ajax"] == "1") end |
#in_external_app? ⇒ Boolean
returns true if the user is viewing the page from an external website
207 208 209 210 211 |
# File 'lib/rplatform_rails/controller_extensions.rb', line 207 def in_external_app? # FIXME: once you click away in an iframe app, you are considered to be an external app # TODO: read up on the hacks for avoiding nested iframes return (params and params["fb_sig"] == nil and !in_facebook_frame?) end |
#in_facebook_canvas? ⇒ Boolean
returns true if the user is viewing the page in the canvas
183 184 185 186 |
# File 'lib/rplatform_rails/controller_extensions.rb', line 183 def in_facebook_canvas? # TODO: make this check fbparams instead (signature is validated there) return (params and params["fb_sig_in_canvas"] == "1") end |
#in_facebook_frame? ⇒ Boolean
returns true if the user is viewing the page in an iframe
189 190 191 192 |
# File 'lib/rplatform_rails/controller_extensions.rb', line 189 def in_facebook_frame? # TODO: make this check fbparams instead (signature is validated there) return (params and params["fb_sig_in_iframe"] == "1") end |
#in_mock_ajax? ⇒ Boolean
returns true if the current request is a mock-ajax request
195 196 197 198 |
# File 'lib/rplatform_rails/controller_extensions.rb', line 195 def in_mock_ajax? # TODO: make this check fbparams instead (signature is validated there) return (params and params["fb_sig_is_mockajax"] == "1") end |
#log_out_of_facebook ⇒ Object
clear the current session so that a new user can log in
220 221 222 223 224 |
# File 'lib/rplatform_rails/controller_extensions.rb', line 220 def log_out_of_facebook session[:_rfacebook_fbsession_holder] = nil session[:_rfacebook_fbparams] = nil @fbsession_holder = nil end |
#render_with_facebook_debug_panel(options = {}) ⇒ Object
special rendering method to use when debugging
299 300 301 302 303 304 305 306 |
# File 'lib/rplatform_rails/controller_extensions.rb', line 299 def render_with_facebook_debug_panel(={}) begin renderedOutput = render_to_string() rescue Exception => e renderedOutput = facebook_canvas_backtrace(e) end render :text => "#{facebook_debug_panel}#{renderedOutput}" end |
#require_facebook_install(urlOptions = {}) ⇒ Object
force the user to install your Facebook application
277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 |
# File 'lib/rplatform_rails/controller_extensions.rb', line 277 def require_facebook_install(urlOptions={}) # if in_facebook_frame? and not added_facebook_application? # render :text => %Q(<script language="javascript">top.location.href="#{fbsession.get_install_url}&next=#{request.path.gsub(/#{facebook_callback_path}/, "")}"</script>) # end if (in_facebook_canvas? or in_facebook_frame?) if (!fbsession.ready? or !added_facebook_application?) redirect_to fbsession.get_install_url(urlOptions) return false end else RAILS_DEFAULT_LOGGER.info "** RFACEBOOK WARNING: require_facebook_install is not intended for external applications, using require_facebook_login instead" return require_facebook_login(urlOptions) end return true end |
#require_facebook_login(urlOptions = {}) ⇒ Object
force the user to log in to Facebook
243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 |
# File 'lib/rplatform_rails/controller_extensions.rb', line 243 def require_facebook_login(urlOptions={}) # check to be sure we haven't already performed a redirect or other action if !performed? # handle invalid sessions by forcing the user to log in if !fbsession.ready? # external applications need to be redirected if in_external_app? RAILS_DEFAULT_LOGGER.debug "** RFACEBOOK INFO: Redirecting to login for external app" redirect_to fbsession.get_login_url(urlOptions) return false # iframe and canvas apps need *validated* fbparams, otherwise session activation cannot happen elsif !facebook_platform_signature_verified? RAILS_DEFAULT_LOGGER.debug "** RFACEBOOK WARNING: Failed to verified canvas parameters from Facebook (probably due to a bad API key or API secret)" render :text => facebook_debug_panel return false else RAILS_DEFAULT_LOGGER.debug "** RFACEBOOK INFO: Redirecting to login for canvas app" urlOptions.merge!({:canvas=>true}) redirect_to fbsession.get_login_url(urlOptions) return false end end end # by default, the filter passes return true end |