Class: Rack::FacebookConnect

Inherits:
Object
  • Object
show all
Includes:
Helpers
Defined in:
lib/rack/facebook_connect.rb,
lib/rack/facebook_connect/helpers.rb

Defined Under Namespace

Modules: Helpers

Instance Method Summary collapse

Methods included from Helpers

#request

Constructor Details

#initialize(app, api_key, api_secret, options = {}) ⇒ FacebookConnect

Initialize the Rack::FacebookConnect middleware. Requires a Facebook API key and secret and takes the following options:

:permissions

An array of Facebook extended permissions, defaults to %w(email offline_access)

:get_info

Boolean as to whether to fetch info about the user on login. Defaults to “true”.



13
14
15
16
17
18
19
20
21
22
# File 'lib/rack/facebook_connect.rb', line 13

def initialize(app, api_key, api_secret, options = {})
  @options = {
    :permissions => %w(email offline_access),
    :get_info => true
  }.merge(options)
  
  @app = app
  @api_key = api_key
  @api_secret = api_secret
end

Instance Method Details

#_call(env) ⇒ Object

:nodoc:



28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/rack/facebook_connect.rb', line 28

def _call(env) #:nodoc:
  @env = env
  @base_url = (request.scheme.downcase == 'https' ? 'https://ssl.connect.facebook.com' : 'http://static.ak.connect.facebook.com')
  
  case request.path
    when "/auth/facebook/xd_receiver.html"
      xd_receiver
    when '/auth/facebook/callback'
      perform_callback
    else
      inject_facebook
  end
end

#call(env) ⇒ Object



24
25
26
# File 'lib/rack/facebook_connect.rb', line 24

def call(env)
  dup._call(env)
end

#inject_facebookObject

:nodoc:



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/rack/facebook_connect.rb', line 78

def inject_facebook #:nodoc:
  status, headers, responses = @app.call(@env)
  responses = Array(responses) unless responses.respond_to?(:each)

  if headers["Content-Type"] =~ %r{(text/html)|(application/xhtml+xml)}
    resp = []
    responses.each do |r|
      r.sub! /(<html[^\/>]*)>/i, '\1 xmlns:fb=\"http://www.facebook.com/2008/fbml\">'
      r.sub! /(<body[^\/>]*)>/i, '\1><script src="' + @base_url + '/js/api_lib/v0.4/FeatureLoader.js.php/en_US" type="text/javascript"></script>'
      r.sub! /<\/body>/i, <<-HTML
        <script type="text/javascript">
          FB.init("#{@api_key}", "/auth/facebook/xd_receiver.html");
          function rack_fbconnect() {
            FB.Connect.showPermissionDialog("#{Array(@options[:permissions]).join(',')}", function(perms) {
              if (perms) {
                window.location.href = '/auth/facebook/callback';
              } else {
                window.location.href = '/auth/facebook/callback?permissions=denied';
              }
            });
          }
        </script></body>
      HTML
      resp << r
    end
  end
  
  Rack::Response.new(resp || responses, status, headers).finish
end

#perform_callbackObject

:nodoc:



59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/rack/facebook_connect.rb', line 59

def perform_callback #:nodoc:
  request[:auth] = {
    :provider => :facebook,
    :user_id => request.cookies["#{@api_key}_user"],
    :session => {
      :key => request.cookies["#{@api_key}_session_key"],
      :secret => request.cookies["#{@api_key}_ss"],
      :expires => (Time.at(request.cookies["#{@api_key}_expires"].to_i) if request.cookies["#{@api_key}_expires"].to_i > 0)
    }
  }
  
  if @options[:get_info]
    require 'mini_fb'
    request[:auth][:info] = MiniFB.call(@api_key, @api_secret, "Users.getInfo", 'session_key' => request[:auth][:session][:key], 'uids' => request[:auth][:user_id], 'fields' => MiniFB::User.all_fields)[0]
  end
  
  @app.call(@env)
end

#xd_receiverObject

:nodoc:



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/rack/facebook_connect.rb', line 42

def xd_receiver #:nodoc:
  xd = <<-HTML
  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
  <html xmlns="http://www.w3.org/1999/xhtml" >
  <head>
      <title>Cross-Domain Receiver Page</title>
  </head>
  <body>
      <script src="#{@base_url}/js/api_lib/v0.4/XdCommReceiver.js" type="text/javascript"></script>
  </body>
  </html>
  HTML
  
  Rack::Response.new(xd).finish
end