doesfacebook 0.6.0 → 1.0.0.pre1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.rdoc +49 -0
- data/Gemfile +21 -0
- data/Gemfile.lock +105 -0
- data/LICENSE +1 -1
- data/README.rdoc +139 -69
- data/ROADMAP.rdoc +55 -0
- data/Rakefile +64 -0
- data/VERSION +1 -0
- data/doesfacebook.gemspec +71 -0
- data/lib/doesfacebook/application.rb +46 -0
- data/lib/doesfacebook/configuration.rb +58 -0
- data/lib/doesfacebook/controller_extensions.rb +98 -0
- data/lib/doesfacebook/error.rb +37 -0
- data/lib/doesfacebook.rb +31 -50
- data/lib/generators/doesfacebook/config/config_generator.rb +3 -3
- data/lib/generators/doesfacebook/config/templates/doesfacebook.rb +33 -0
- data/lib/helpers/does_facebook_helper.rb +70 -0
- data/public/channel.html +2 -0
- metadata +99 -26
- data/app/helpers/does_facebook_helper.rb +0 -73
- data/lib/doesfacebook/config.rb +0 -49
- data/lib/doesfacebook/controls.rb +0 -47
- data/lib/doesfacebook/filters.rb +0 -71
- data/lib/generators/doesfacebook/config/templates/doesfacebook.yml +0 -32
@@ -1,73 +0,0 @@
|
|
1
|
-
# AWEXOME LABS
|
2
|
-
# DoesFacebook
|
3
|
-
#
|
4
|
-
# DoesFacebookHelper - add helpers to
|
5
|
-
|
6
|
-
module DoesFacebookHelper
|
7
|
-
|
8
|
-
# Return the current application id to the view
|
9
|
-
def app_id
|
10
|
-
controller.send(:facebook_config)[:app_id]
|
11
|
-
end
|
12
|
-
|
13
|
-
# Return the current app callback URL
|
14
|
-
def app_callback_url
|
15
|
-
if request.ssl?
|
16
|
-
controller.send(:facebook_config)[:ssl_callback_url] || controller.send(:facebook_config)[:callback_url]
|
17
|
-
else
|
18
|
-
controller.send(:facebook_config)[:callback_url]
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
# Return the current app namespace:
|
23
|
-
def app_namespace
|
24
|
-
controller.send(:facebook_config)[:namespace]
|
25
|
-
end
|
26
|
-
|
27
|
-
# Deprecated: "canvas_name" configuration is deprecated, but essentially aliased to "namespace":
|
28
|
-
def app_canvas_name
|
29
|
-
ActiveSupport::Deprecation.warn "DoesFacebook: Helper and configuration key \"canvas_name\" and \"app_canvas_name\" is deprecated. Use \"namespace\" or \"app_namespace\" instead.", caller
|
30
|
-
app_namespace
|
31
|
-
end
|
32
|
-
|
33
|
-
# Return the full canvas URL:
|
34
|
-
def app_canvas_url
|
35
|
-
"#{request.ssl? ? "https://" : "http://"}apps.facebook.com/#{app_namespace}"
|
36
|
-
end
|
37
|
-
|
38
|
-
# Generate a URL that points within the Facebook canvas
|
39
|
-
def url_for_canvas(url_opts={})
|
40
|
-
canvas_root = app_canvas_url
|
41
|
-
if url_opts.is_a?(Hash)
|
42
|
-
return File.join(canvas_root, url_for(url_opts))
|
43
|
-
elsif url_opts.include?("://")
|
44
|
-
return url_opts
|
45
|
-
else
|
46
|
-
return File.join(canvas_root, url_opts)
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
# Generate a link that stays within the Facebook canvas
|
51
|
-
def link_to_canvas(text, url_opts={}, html_opts={})
|
52
|
-
url = url_for_canvas(url_opts)
|
53
|
-
content_tag("a", text, html_opts.merge(:rev=>"canvas", :href=>url, :target=>"_top"), false)
|
54
|
-
end
|
55
|
-
|
56
|
-
# Insert properly-formed FB.init() call with fb-root doc element
|
57
|
-
def fb_init(opts={})
|
58
|
-
opts = {:status=>true, :cookie=>true, :xfbml=>true}.merge(opts)
|
59
|
-
opts.merge!(:appId=>app_id)
|
60
|
-
raw("""<div id=\"fb-root\"></div>
|
61
|
-
<script src=\"http://connect.facebook.net/en_US/all.js\"></script>
|
62
|
-
<script>
|
63
|
-
FB.init(#{opts.to_json});
|
64
|
-
window.fbAsyncInit = function() {
|
65
|
-
FB.XFBML.parse();
|
66
|
-
FB.Canvas.setAutoGrow();
|
67
|
-
}
|
68
|
-
</script>
|
69
|
-
""")
|
70
|
-
end
|
71
|
-
|
72
|
-
|
73
|
-
end
|
data/lib/doesfacebook/config.rb
DELETED
@@ -1,49 +0,0 @@
|
|
1
|
-
# AWEXOME LABS
|
2
|
-
# DoesFacebook Config
|
3
|
-
|
4
|
-
module DoesFacebook
|
5
|
-
module Config
|
6
|
-
|
7
|
-
protected
|
8
|
-
|
9
|
-
# Load app configuration by Facebook callback path with a fallback to config
|
10
|
-
# defined with name matching our current environment:
|
11
|
-
def facebook_config
|
12
|
-
@facebook_config ||= nil
|
13
|
-
return @facebook_config unless @facebook_config.nil?
|
14
|
-
app_name, app_config = all_facebook_config.find do |name, config|
|
15
|
-
test_callback = if request.ssl? && config["ssl_callback_url"]
|
16
|
-
config["ssl_callback_url"]
|
17
|
-
else
|
18
|
-
config["callback_url"]
|
19
|
-
end
|
20
|
-
request.url.match(/^#{test_callback}.*/)
|
21
|
-
end
|
22
|
-
if app_config
|
23
|
-
app_config = HashWithIndifferentAccess.new(app_config)
|
24
|
-
if app_config[:canvas_name]
|
25
|
-
app_config[:namespace] ||= app_config.delete(:canvas_name)
|
26
|
-
Rails.logger.warn(" DoesFacebook Deprecation Warning: \"canvas_name\" field in doesfacebook.yml should be renamed \"namespace\" as per Facebook Roadmap")
|
27
|
-
end
|
28
|
-
Rails.logger.info(" Facebook configuration for app \"#{app_name}\" loaded for request URL #{request.url}")
|
29
|
-
@facebook_config = app_config
|
30
|
-
else
|
31
|
-
Rails.logger.warn(" Facebook configuration could not be found. doesfacebook.yml has no app for host #{request.host}")
|
32
|
-
Rails.logger.warn(" Facebook configuration can be generated by running \"rails generate does_facebook:config\"")
|
33
|
-
end
|
34
|
-
return @facebook_config
|
35
|
-
end
|
36
|
-
|
37
|
-
|
38
|
-
# Load configuration from YAML file for all environments:
|
39
|
-
def all_facebook_config
|
40
|
-
return @@all_facebook_config if @all_facebook_config
|
41
|
-
config_file = File.join(Rails.root, "config", "doesfacebook.yml")
|
42
|
-
if File.exist?(config_file)
|
43
|
-
return @@all_facebook_config ||= YAML.load(File.open( config_file ))
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
end
|
48
|
-
end # DoesFacebook
|
49
|
-
|
@@ -1,47 +0,0 @@
|
|
1
|
-
# AWEXOME LABS
|
2
|
-
# DoesFacebook
|
3
|
-
#
|
4
|
-
# Controls - convenience methods for injection into controllers
|
5
|
-
|
6
|
-
module DoesFacebook
|
7
|
-
module Controls
|
8
|
-
|
9
|
-
# Exception Classes:
|
10
|
-
class MalformedUrlOptions < Exception; end
|
11
|
-
|
12
|
-
|
13
|
-
protected
|
14
|
-
|
15
|
-
# Mechanism for redirecting within the Facebook canvas:
|
16
|
-
def redirect_to_canvas_old(opts={})
|
17
|
-
raise MalformedUrlOptions.new("Options passed to `redirect_to_canvas` must be a URL options Hash") unless opts.is_a?(Hash)
|
18
|
-
dest = File.join("http://apps.facebook.com/", facebook_config[:namespace], url_for(opts.merge(:only_path=>true)))
|
19
|
-
|
20
|
-
ActiveSupport::Deprecation.warn "DoesFacebook: redirect_to_canvas_old method is deprecated and does not support HTTPS. Use redirect_to_canvas instead.", caller
|
21
|
-
|
22
|
-
logger.info "Canvas Redirect to #{opts.inspect}=>#{dest}"
|
23
|
-
redirect_to dest
|
24
|
-
end
|
25
|
-
|
26
|
-
# Purer, JavaScript-based solution for redirecting within the Facebook canvas:
|
27
|
-
def redirect_to_canvas(opts={})
|
28
|
-
raise MalformedUrlOptions.new("Options passed to `redirect_to_canvas` must be a URL options Hash") unless opts.is_a?(Hash)
|
29
|
-
apps_root = request.ssl? ? "https://apps.facebook.com/" : "http://apps.facebook.com/"
|
30
|
-
dest = File.join(apps_root, facebook_config[:namespace], url_for(opts.merge(:only_path=>true)))
|
31
|
-
@facebook_redirect_url = dest
|
32
|
-
logger.info "Canvas Redirect to #{opts.inspect}=>#{dest}"
|
33
|
-
begin
|
34
|
-
render :partial=>"facebook/redirect"
|
35
|
-
rescue ActionView::MissingTemplate=>e
|
36
|
-
logger.info "Pretty Redirect Partial facebook/redirect Not Found. Using Unformatted Text."
|
37
|
-
render :text=>%{
|
38
|
-
Redirecting you to <a href="#{dest}">#{dest}</a>...
|
39
|
-
<script type="text/javascript">
|
40
|
-
top.location.href = "#{dest}";
|
41
|
-
</script>
|
42
|
-
}
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
end # Controls
|
47
|
-
end # DoesFacebook
|
data/lib/doesfacebook/filters.rb
DELETED
@@ -1,71 +0,0 @@
|
|
1
|
-
# AWEXOME LABS
|
2
|
-
# DoesFacebook
|
3
|
-
#
|
4
|
-
# Filters - before and after filters for controller that process Facebook behavior
|
5
|
-
|
6
|
-
module DoesFacebook
|
7
|
-
module Filters
|
8
|
-
|
9
|
-
protected
|
10
|
-
|
11
|
-
# Captures a signed_request parameter and manipulates the session to allow for
|
12
|
-
# a signed_request to be passed from iframe request to iframe request
|
13
|
-
def sessionify_signed_request
|
14
|
-
if request_parameter = request.params["signed_request"]
|
15
|
-
session[:signed_request] = request_parameter
|
16
|
-
logger.info " Facebook Signed Request received. Stored/updated in session."
|
17
|
-
else
|
18
|
-
params["signed_request"] = session[:signed_request]
|
19
|
-
logger.info " No Facebook Signed Request received. Loaded, if present, from session."
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
|
24
|
-
# Ensures, using configuration options, that the request was signed by Facebook
|
25
|
-
def validate_signed_request
|
26
|
-
if request_parameter = request.params["signed_request"]
|
27
|
-
if app_secret = facebook_config["secret_key"]
|
28
|
-
encoded_signature, encoded_data = request_parameter.split(".")
|
29
|
-
decoded_signature = base64_url_decode(encoded_signature)
|
30
|
-
digested = OpenSSL::HMAC.digest("sha256", app_secret, encoded_data)
|
31
|
-
valid = (digested == decoded_signature)
|
32
|
-
if valid
|
33
|
-
logger.info " Facebook Signed Request Valid."
|
34
|
-
else
|
35
|
-
logger.info " Facebook Signed Request is not Valid. Ensure request is from Facebook."
|
36
|
-
raise "DoesFacebook: Invalid Signed Request. Ensure request is from Facebook."
|
37
|
-
end
|
38
|
-
else
|
39
|
-
logger.info " Facebook Signed Request cannot be verified without app configuration"
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
|
45
|
-
# If present, parses data from the signed request and inserts it into the fbparams
|
46
|
-
# object for use during requests
|
47
|
-
def parse_signed_request
|
48
|
-
if request_parameter = request.params["signed_request"]
|
49
|
-
encoded_signature, encoded_data = request_parameter.split(".")
|
50
|
-
decoded_signature = base64_url_decode(encoded_signature)
|
51
|
-
decoded_data = base64_url_decode(encoded_data)
|
52
|
-
@fbparams = HashWithIndifferentAccess.new(JSON.parse(decoded_data).merge({
|
53
|
-
"signature"=>encoded_signature,
|
54
|
-
"data"=>encoded_data
|
55
|
-
}))
|
56
|
-
logger.info " Facebook Parameters: #{fbparams.inspect}"
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
private
|
63
|
-
|
64
|
-
# Base64 URL Decode method
|
65
|
-
# see http://developers.facebook.com/docs/authentication/canvas
|
66
|
-
def base64_url_decode(str)
|
67
|
-
"#{str}==".tr("-_", "+/").unpack("m")[0]
|
68
|
-
end
|
69
|
-
|
70
|
-
end
|
71
|
-
end # DoesFacebook
|
@@ -1,32 +0,0 @@
|
|
1
|
-
# AWEXOME LABS
|
2
|
-
# DoesFacebook Configuration File
|
3
|
-
#
|
4
|
-
# The appropriate application configuration will be loaded for each
|
5
|
-
# request based on the callback path of your application. The host
|
6
|
-
# of each incoming request will be compared against the callback_url
|
7
|
-
# or ssl_callback_url fields of your app.
|
8
|
-
#
|
9
|
-
# Top-level keys in this file are configuration names. If you have one
|
10
|
-
# app for each environment, however, naming an app after the corresponding
|
11
|
-
# Rails environment ("development","production",etc.) will provide a
|
12
|
-
# fallback should the request host not directly resolve to a callback_url
|
13
|
-
#
|
14
|
-
|
15
|
-
name_of_app:
|
16
|
-
app_id: 1234567890
|
17
|
-
secret_key: 1234567890abcdefghijklmnopqrsttuv
|
18
|
-
namespace: your_canvas_name
|
19
|
-
callback_url: http://your.dev.server.com/and/path
|
20
|
-
|
21
|
-
name_of_another_app:
|
22
|
-
app_id: 1234567890
|
23
|
-
secret_key: 1234567890abcdefghijklmnopqrsttuv
|
24
|
-
namespace: your_canvas_name
|
25
|
-
callback_url: http://your.dev.server.com/and/path
|
26
|
-
|
27
|
-
name_of_production_app:
|
28
|
-
app_id: 1234567890
|
29
|
-
secret_key: 1234567890abcdefghijklmnopqrsttuv
|
30
|
-
namespace: your_canvas_name
|
31
|
-
callback_url: http://your.server.com/and/path
|
32
|
-
ssl_callback_url: https://your.secure.server.com/and/path
|