doesfacebook 0.6.0 → 1.0.0.pre1

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.
@@ -0,0 +1,46 @@
1
+ # AWEXOME LABS
2
+ # DoesFacebook
3
+ #
4
+ # Application -- representation of a single Facebook Application, defined on the
5
+ # developers portal at developers.facebook.com.
6
+ #
7
+ # Fields used in configuration match Facebook's API keys for the corresponding
8
+ # setting whenever possible. For reference, review the Graph API doc for Application:
9
+ # https://developers.facebook.com/docs/reference/api/application/
10
+ #
11
+
12
+ module DoesFacebook
13
+
14
+ class Application
15
+
16
+ # Define settable configuration keys for each application:
17
+ attr_accessor :id, :secret, :namespace, :canvas_url, :secure_canvas_url
18
+
19
+ # Prepare with a predefined configuration:
20
+ def initialize(opts={})
21
+ update_options(opts)
22
+ end
23
+
24
+ # Bulk set configuration options for this application
25
+ def update_options(opts={})
26
+ opts.each do |key, val|
27
+ self.send("#{key}=", val)
28
+ end
29
+ end
30
+
31
+ # Error in the case of an unknown key being configured:
32
+ def method_missing(meth, *args, &block)
33
+ if meth.to_s =~ /\=$/
34
+ key_name = meth.to_s.gsub(/\=$/,"")
35
+ raise DoesFacebook::ConfigurationError.new("Unknown configuration key `#{key_name}` cannot be set for Facebook applications.")
36
+ end
37
+ super
38
+ end
39
+
40
+ # Return true if this application supports SSL/HTTPS:
41
+ def supports_ssl?
42
+ !secure_canvas_url.nil?
43
+ end
44
+
45
+ end # Application
46
+ end # DoesFacebook
@@ -0,0 +1,58 @@
1
+ # AWEXOME LABS
2
+ # DoesFacebook : Configuration
3
+
4
+ module DoesFacebook
5
+
6
+ class Configuration
7
+
8
+ # Configurable options:
9
+ attr_accessor :applications, :app_selector
10
+
11
+ # Declare defaults on load:
12
+ def initialize
13
+ @applications = Array.new
14
+ @app_selector = Proc.new() do |request, apps|
15
+ apps.find do |a|
16
+ callback_path = request.ssl? && a.supports_ssl? ? a.secure_canvas_url : a.canvas_url
17
+ request.url.match(/^#{callback_path}.*/)
18
+ end
19
+ end
20
+ end
21
+
22
+ # If an unknown settings is configured, notify the user:
23
+ def method_missing(meth, *args, &block)
24
+ if meth.to_s =~ /\=$/
25
+ key_name = meth.to_s.gsub(/\=$/,"")
26
+ raise DoesFacebook::ConfigurationError.new("Unknown configuration `#{key_name}` cannot be set for DoesFacebook.")
27
+ end
28
+ super
29
+ end
30
+
31
+ # Add an application definition:
32
+ def add_application(app)
33
+ app = DoesFacebook::Application.new(app) if app.is_a?(Hash)
34
+ @applications << app
35
+ end
36
+
37
+ # Determine the current app given an incoming request:
38
+ def current_application(request)
39
+ app_selector.call(request, applications)
40
+ end
41
+
42
+ end # Configuration
43
+
44
+
45
+ # Provide an accessor to the gem configuration:
46
+ class << self
47
+ attr_accessor :configuration
48
+ end
49
+
50
+ # Yield the configuration to host:
51
+ def self.configure
52
+ self.configuration ||= Configuration.new
53
+ yield(configuration)
54
+ end
55
+
56
+ DoesFacebook.configuration = Configuration.new
57
+
58
+ end # DoesFacebook
@@ -0,0 +1,98 @@
1
+ # AWEXOME LABS
2
+ # DoesFacebook
3
+ #
4
+ # ControllerExtensions - convenience methods and filters injected into controllers
5
+ # which enact DoesFacebook
6
+ #
7
+
8
+ module DoesFacebook
9
+ module ControllerExtensions
10
+
11
+ protected
12
+
13
+ def fb_app
14
+ @fb_app ||= DoesFacebook.configuration.current_application(request)
15
+ end
16
+
17
+ def url_for_canvas(opts={})
18
+ canvas_root = if request.ssl? && fb_app.supports_ssl?
19
+ "https://apps.facebook.com/#{fb_app.namespace}/"
20
+ else
21
+ "http://apps.facebook.com/#{fb_app.namespace}/"
22
+ end
23
+ case opts
24
+ when String
25
+ opts =~ /:\/\// ? opts : File.join(canvas_root, opts)
26
+ when Hash
27
+ opts.merge(:only_path=>true)
28
+ File.join(canvas_root, url_for(opts))
29
+ end
30
+ end
31
+
32
+ def redirect_to_canvas(opts={})
33
+ @facebook_redirect_url = url_for_canvas(opts)
34
+ Rails.logger.info "Canvas Redirect to #{@facebook_redirect_url}"
35
+ begin
36
+ render :partial=>"facebook/redirect"
37
+ rescue ActionView::MissingTemplate => e
38
+ logger.info "Pretty Redirect Partial facebook/redirect Not Found. Using Unformatted Text."
39
+ render :text=>%{
40
+ Redirecting you to <a href="#{@facebook_redirect_url}">#{@facebook_redirect_url}</a>...
41
+ <script type="text/javascript"> top.location.href = "#{@facebook_redirect_url}"; </script>
42
+ }.html_safe
43
+ end
44
+ end
45
+
46
+
47
+
48
+ private
49
+
50
+ # Captures a signed_request parameter and manipulates the session to allow for
51
+ # a signed_request to be passed from iframe request to iframe request
52
+ # def sessionify_signed_request
53
+ # if request_parameter = request.params["signed_request"]
54
+ # session[:signed_request] = request_parameter
55
+ # logger.info " Facebook Signed Request received. Stored/updated in session."
56
+ # else
57
+ # params["signed_request"] = session[:signed_request]
58
+ # logger.info " No Facebook Signed Request received. Loaded, if present, from session."
59
+ # end
60
+ # end
61
+
62
+ # Ensures, using configuration options, that the request was signed by Facebook
63
+ def validate_signed_request
64
+ if request_parameter = request.params["signed_request"]
65
+ encoded_signature, encoded_data = request_parameter.split(".")
66
+ decoded_signature = base64_url_decode(encoded_signature)
67
+ digested = OpenSSL::HMAC.digest("sha256", fb_app.secret, encoded_data)
68
+ if valid = (digested == decoded_signature)
69
+ Rails.logger.info " Facebook Signed Request Valid."
70
+ else
71
+ Rails.logger.info " Facebook Signed Request is not Valid. Ensure request is from Facebook and correct Facebook app has been selected."
72
+ raise DoesFacebook::RequestSignatureInvalidError.new()
73
+ end
74
+ end
75
+ end
76
+
77
+ # If present, parses data from the signed request and inserts it into the fbparams
78
+ # object for use during requests
79
+ def parse_signed_request
80
+ Rails.logger.info " Facebook application \"#{fb_app.namespace}\" configuration in use for this request."
81
+ if request_parameter = request.params["signed_request"]
82
+ encoded_signature, encoded_data = request_parameter.split(".")
83
+ decoded_signature = base64_url_decode(encoded_signature)
84
+ decoded_data = base64_url_decode(encoded_data)
85
+ @fbparams = HashWithIndifferentAccess.new(JSON.parse(decoded_data))
86
+ Rails.logger.info " Facebook Parameters: #{fbparams.inspect}"
87
+ end
88
+ end
89
+
90
+
91
+ # Base64 URL Decode method
92
+ # see http://developers.facebook.com/docs/authentication/canvas
93
+ def base64_url_decode(str)
94
+ "#{str}==".tr("-_", "+/").unpack("m")[0]
95
+ end
96
+
97
+ end # ControllerExtensions
98
+ end # DoesFacebook
@@ -0,0 +1,37 @@
1
+ # AWEXOME LABS
2
+ # DoesFacebook
3
+ #
4
+ # Error -- represent individual configuration and runtime errors specific to
5
+ # the Facebook application or DoesFacebook
6
+ #
7
+
8
+ module DoesFacebook
9
+
10
+ class Error < StandardError
11
+ def initialize(message="DoesFacebook Runtime Error")
12
+ super
13
+ end
14
+ end # Error
15
+
16
+
17
+ class ConfigurationError < Error
18
+ def initialize(message="DoesFacebook Configuration Error")
19
+ super
20
+ end
21
+ end # ConfigurationError
22
+
23
+
24
+ class MiddlewareError < Error
25
+ def initialize(message="DoesFacebook Runtime Error")
26
+ super
27
+ end
28
+ end # MiddlewareError
29
+
30
+ class RequestSignatureInvalidError < Error
31
+ def initialize(message="Signed Request from Facebook is not valid.")
32
+ super
33
+ end
34
+ end # MiddlewareError
35
+
36
+
37
+ end # DoesFacebook
data/lib/doesfacebook.rb CHANGED
@@ -1,79 +1,60 @@
1
1
  # AWEXOME LABS
2
2
  # DoesFacebook
3
3
 
4
- require 'doesfacebook'
5
- require 'rails'
6
- require 'action_controller'
7
-
8
- require 'doesfacebook/config'
9
- require 'doesfacebook/filters'
10
- require 'doesfacebook/controls'
11
- require 'doesfacebook/session'
12
- require 'doesfacebook/middleware'
13
-
14
- require 'generators/doesfacebook/config/config_generator'
4
+ require "doesfacebook"
5
+ require "rails"
6
+ require "action_controller"
7
+
8
+ require "doesfacebook/configuration"
9
+ require "doesfacebook/error"
10
+ require "doesfacebook/application"
11
+ require "doesfacebook/controller_extensions"
12
+ require "helpers/does_facebook_helper"
13
+ # require "doesfacebook/session"
14
+ require "doesfacebook/middleware"
15
+ require "generators/doesfacebook/config/config_generator"
15
16
 
16
17
  module DoesFacebook
17
18
 
18
- # Create a Rails Engine
19
+ # Add configuration and features to Rails as an Engine:
19
20
  class Engine < Rails::Engine
20
- # engine_name :doesfacebook
21
- end
22
-
23
- # Create a Railtie for Rack, config injection
24
- class Railtie < Rails::Railtie
25
21
  initializer "doesfacebook.init" do |app|
26
22
  app.middleware.use DoesFacebook::Middleware
27
23
  end
24
+
25
+ initializer "doesfacebook.static_assets" do |app|
26
+ app.middleware.use ::ActionDispatch::Static, "#{root}/public"
27
+ end
28
+
29
+ paths["app/helpers"] << "lib/helpers"
28
30
  end
29
-
30
- # Return the current working version of DoesFacebook from VERSION file:
31
+
32
+ # Return the current version of the gem:
31
33
  def self.version
32
34
  @@version ||= File.open(File.join(File.dirname(__FILE__), "..", "VERSION"), "r").read
33
35
  end
34
-
36
+
35
37
  end # DoesFacebook
36
38
 
37
39
 
38
40
  module ActionController
39
41
  class Base
40
-
41
- # Call this method within your controller to parse configuration and enabled
42
- # session validation and parsing
42
+
43
+ # Call this method within your controller to enable Facebook actions:
43
44
  def self.does_facebook(opts={})
44
- self.instance_eval do
45
- include DoesFacebook::Config
46
- include DoesFacebook::Controls
47
- include DoesFacebook::Filters
48
- prepend_before_filter :parse_signed_request, :validate_signed_request
49
- prepend_before_filter :sessionify_signed_request unless opts[:session]==false
45
+ self.instance_eval do
46
+ include DoesFacebook::ControllerExtensions
50
47
  helper :does_facebook
51
-
52
- protected
53
- attr_reader :fbparams
54
- end
55
- end
56
-
57
- end
58
- end # ActionController
48
+ prepend_before_filter :validate_signed_request, opts
49
+ prepend_before_filter :parse_signed_request, opts
50
+ #prepend_before_filter :sessionify_signed_request unless opts[:session]==false
59
51
 
60
-
61
- module ActionMailer
62
- class Base
63
-
64
- # Call this method within your controller to parse configuration and enabled
65
- # session validation and parsing
66
- def self.does_facebook
67
- self.instance_eval do
68
- include DoesFacebook::Config
69
- helper :does_facebook
70
-
71
52
  protected
72
53
  attr_reader :fbparams
73
54
  end
74
55
  end
75
-
56
+
76
57
  end
77
- end # ActionMailer
58
+ end # ActionController
78
59
 
79
60
 
@@ -8,14 +8,14 @@ module DoesFacebook
8
8
  module Generators
9
9
  class ConfigGenerator < ::Rails::Generators::Base
10
10
 
11
- desc "Creates a boilerplate DoesFacebook configuration file at config/doesfacebook.yml"
11
+ desc "Creates a boilerplate DoesFacebook config/initializer at config/initializers/doesfacebook.rb"
12
12
 
13
13
  source_root File.expand_path("../templates", __FILE__)
14
14
 
15
15
  def create_config_file
16
- template "doesfacebook.yml", File.join("config","doesfacebook.yml")
16
+ template "doesfacebook.rb", File.join("config/initializers","doesfacebook.rb")
17
17
  end
18
18
 
19
19
  end
20
20
  end #Generators
21
- end #DoesFacebook
21
+ end #DoesFacebook
@@ -0,0 +1,33 @@
1
+ # AWEXOME LABS
2
+ # DoesFacebook Configuration File
3
+ #
4
+ # Use this initializer to declare logical Facebook applications your
5
+ # Rails app will harness.
6
+ #
7
+ # You can specify any number of applications statically, from a dynamic
8
+ # source such as your database, or from elsewhere.
9
+ #
10
+
11
+ DoesFacebook.configure do |config|
12
+
13
+ # Add each Facebook Application (defined in your Developer Dashboard
14
+ # at developers.facebook.com) here, like so:
15
+ config.add_application(
16
+ id: 123456789012345,
17
+ secret: "abcdefghijklmnopqrstuvwxyzABCDEF"
18
+ namespace: "your_app_namespace",
19
+ canvas_url: "http://your.dev.server.com/and/path",
20
+ secure_canvas_url: "https://secure.dev.server"
21
+ )
22
+
23
+ # You may specify the method by which DoesFacebook selects the app
24
+ # configuration for each request with a lambda or Proc. This example
25
+ # uses canvas_url, but you can make this distinction however you wish:
26
+ # config.app_selector = Proc.new() do |request, apps|
27
+ # apps.find do |a|
28
+ # callback_path = request.ssl? && a.supports_ssl? ? a.secure_canvas_url : a.canvas_url
29
+ # request.url.match(/^#{callback_path}.*/)
30
+ # end
31
+ # end
32
+
33
+ end
@@ -0,0 +1,70 @@
1
+ # AWEXOME LABS
2
+ # DoesFacebook
3
+ #
4
+ # DoesFacebookHelper - add helpers to
5
+
6
+ module DoesFacebookHelper
7
+
8
+ # Return a reference to the current Facebook Application config:
9
+ def fb_app
10
+ @fb_app
11
+ end
12
+
13
+ # Return the current application id to the view
14
+ def app_id
15
+ fb_app.id
16
+ end
17
+
18
+ # Return the current app namespace:
19
+ def app_namespace
20
+ fb_app.namespace
21
+ end
22
+
23
+ # Return the full canvas URL:
24
+ def app_canvas_url
25
+ "#{request.ssl? ? "https://" : "http://"}apps.facebook.com/#{app_namespace}"
26
+ end
27
+
28
+ # Generate a URL that points within the Facebook canvas
29
+ def url_for_canvas(url_opts={})
30
+ controller.send(:url_for_canvas, url_opts)
31
+ end
32
+
33
+ # Generate a link that points within the Facebook canvas
34
+ def link_to_canvas(text, url_opts={}, html_opts={})
35
+ content_tag("a", text, html_opts.merge(:rev=>"canvas", :href=>url_for_canvas(url_opts), :target=>"_top"), false)
36
+ end
37
+
38
+ # Display a user's Facebook profile photo
39
+ def profile_pic(facebook_id, opts={})
40
+ type = opts.delete(:type) || "square" # <= Valid types: square, small, normal, large
41
+ opts = {:class=>"profile-pic", :border=>0}.merge(opts)
42
+ image_tag("//graph.facebook.com/#{facebook_id}/picture?type=#{type}", opts)
43
+ end
44
+
45
+
46
+ # Insert properly-formed FB.init() call with fb-root doc element. Yields a block which
47
+ # can be used to inject further FB initialization JavaScript within fbAsyncInit
48
+ def fb_init(init_opts={}, &block)
49
+ init_opts = {appId: app_id, channelUrl: "/channel.html", status: true, cookie: true, xfbml: false}.merge(init_opts)
50
+ injection = """<!-- Facebook JS SDK -->
51
+ <div id=\"fb-root\"></div>
52
+ <script>
53
+ window.fbAsyncInit = function() {
54
+ FB.init(#{init_opts.to_json});"""
55
+ injection += capture(&block) if block_given?
56
+ injection += """
57
+ };
58
+ (function(d){
59
+ var js, id = 'facebook-jssdk', ref = d.getElementsByTagName('script')[0];
60
+ if (d.getElementById(id)) {return;}
61
+ js = d.createElement('script'); js.id = id; js.async = true;
62
+ js.src = \"//connect.facebook.net/en_US/all.js\";
63
+ ref.parentNode.insertBefore(js, ref);
64
+ }(document));
65
+ </script>"""
66
+ return injection.html_safe
67
+ end
68
+
69
+
70
+ end
@@ -0,0 +1,2 @@
1
+ <script src="//connect.facebook.net/en_US/all.js"></script>
2
+ <!-- DoesFacebook: Facebook Channel File: https://developers.facebook.com/docs/reference/javascript/ -->
metadata CHANGED
@@ -1,59 +1,128 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: doesfacebook
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
5
- prerelease:
4
+ version: 1.0.0.pre1
5
+ prerelease: 6
6
6
  platform: ruby
7
7
  authors:
8
- - mccolin
8
+ - Awexome Labs
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-10-11 00:00:00.000000000Z
12
+ date: 2013-05-21 00:00:00.000000000 Z
13
13
  dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rails
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: 3.2.0
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: 3.2.0
14
30
  - !ruby/object:Gem::Dependency
15
31
  name: bundler
16
- requirement: &2154459220 !ruby/object:Gem::Requirement
32
+ requirement: !ruby/object:Gem::Requirement
17
33
  none: false
18
34
  requirements:
19
- - - ~>
35
+ - - ! '>='
20
36
  - !ruby/object:Gem::Version
21
- version: 1.0.0
37
+ version: '1.1'
22
38
  type: :development
23
39
  prerelease: false
24
- version_requirements: *2154459220
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '1.1'
25
46
  - !ruby/object:Gem::Dependency
26
47
  name: jeweler
27
- requirement: &2154458600 !ruby/object:Gem::Requirement
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: 1.8.4
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 1.8.4
62
+ - !ruby/object:Gem::Dependency
63
+ name: rdoc
64
+ requirement: !ruby/object:Gem::Requirement
28
65
  none: false
29
66
  requirements:
30
67
  - - ~>
31
68
  - !ruby/object:Gem::Version
32
- version: 1.5.1
69
+ version: '3.12'
33
70
  type: :development
34
71
  prerelease: false
35
- version_requirements: *2154458600
36
- description: Paper-thin Facebook validation and signed request parsing Rails plugin
37
- email: info@awexomelabs.com
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ version: '3.12'
78
+ - !ruby/object:Gem::Dependency
79
+ name: rspec
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: 2.11.0
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: 2.11.0
94
+ description: Lightweight gem enables your Rails application to quickly and simply
95
+ integrate with Facebook
96
+ email: engineering@awexomelabs.com
38
97
  executables: []
39
98
  extensions: []
40
99
  extra_rdoc_files:
41
100
  - LICENSE
42
101
  - README.rdoc
43
102
  files:
44
- - app/helpers/does_facebook_helper.rb
103
+ - CHANGELOG.rdoc
104
+ - Gemfile
105
+ - Gemfile.lock
106
+ - LICENSE
107
+ - README.rdoc
108
+ - ROADMAP.rdoc
109
+ - Rakefile
110
+ - VERSION
111
+ - doesfacebook.gemspec
45
112
  - lib/doesfacebook.rb
46
- - lib/doesfacebook/config.rb
47
- - lib/doesfacebook/controls.rb
48
- - lib/doesfacebook/filters.rb
113
+ - lib/doesfacebook/application.rb
114
+ - lib/doesfacebook/configuration.rb
115
+ - lib/doesfacebook/controller_extensions.rb
116
+ - lib/doesfacebook/error.rb
49
117
  - lib/doesfacebook/middleware.rb
50
118
  - lib/doesfacebook/session.rb
51
119
  - lib/generators/doesfacebook/config/config_generator.rb
52
- - lib/generators/doesfacebook/config/templates/doesfacebook.yml
53
- - LICENSE
54
- - README.rdoc
55
- homepage: http://awexomelabs.com/
56
- licenses: []
120
+ - lib/generators/doesfacebook/config/templates/doesfacebook.rb
121
+ - lib/helpers/does_facebook_helper.rb
122
+ - public/channel.html
123
+ homepage: http://github.com/awexome/doesfacebook
124
+ licenses:
125
+ - MIT
57
126
  post_install_message:
58
127
  rdoc_options: []
59
128
  require_paths:
@@ -64,16 +133,20 @@ required_ruby_version: !ruby/object:Gem::Requirement
64
133
  - - ! '>='
65
134
  - !ruby/object:Gem::Version
66
135
  version: '0'
136
+ segments:
137
+ - 0
138
+ hash: 2444230836581017084
67
139
  required_rubygems_version: !ruby/object:Gem::Requirement
68
140
  none: false
69
141
  requirements:
70
- - - ! '>='
142
+ - - ! '>'
71
143
  - !ruby/object:Gem::Version
72
- version: '0'
144
+ version: 1.3.1
73
145
  requirements: []
74
146
  rubyforge_project:
75
- rubygems_version: 1.8.17
147
+ rubygems_version: 1.8.24
76
148
  signing_key:
77
149
  specification_version: 3
78
- summary: Paper-thin Facebook validation and signed request parsing Rails plugin
150
+ summary: Lightweight gem enables your Rails application to quickly and simply integrate
151
+ with Facebook
79
152
  test_files: []