devise_facebook_connectable 0.1.5 → 0.1.6

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -27,7 +27,7 @@ begin
27
27
  gemspec.extra_rdoc_files = SUPPORT_FILES
28
28
 
29
29
  gemspec.add_dependency 'activesupport', '>= 2.3.0'
30
- gemspec.add_dependency 'devise', '>= 0.7.1'
30
+ gemspec.add_dependency 'devise', '>= 0.7.3'
31
31
  gemspec.add_dependency 'facebooker', '>= 1.0.55'
32
32
  end
33
33
  Jeweler::GemcutterTasks.new
@@ -1,6 +1,6 @@
1
1
  # encoding: utf-8
2
2
 
3
- class DeviseFacebookConnectableGenerator < Rails::Generator::Base
3
+ class DeviseFacebookConnectableGenerator < Rails::Generator::Base #:nodoc:
4
4
 
5
5
  default_options :api_key => "YOUR_APP_API_KEY",
6
6
  :secret_key => "YOUR_APP_SECRET_KEY"
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * JavaScript Helpers for devise_facebook_connectable,
3
- * to make connect/login/logout with Devise seamless.
3
+ * to make sign in/out (connect) with Devise seamless.
4
4
  *
5
5
  * Note: JavaScript framework agnostic.
6
6
  */
@@ -16,32 +16,32 @@ if (typeof devise.facebook_connectable === 'undefined' || devise.facebook_connec
16
16
  /*
17
17
  * Connect/Login.
18
18
  */
19
- devise.facebook_connectable.login = function fbc_login() {
20
- document.getElementById('fb_connect_login_form').submit();
19
+ devise.facebook_connectable.sign_in = function fbc_sign_in() {
20
+ document.getElementById('fb_connect_sign_in_form').submit();
21
21
  return false;
22
22
  };
23
23
 
24
24
  /*
25
25
  * Connect/Login - with callback.
26
26
  */
27
- devise.facebook_connectable.login_with_callback = function fbc_login_with_callback() {
28
- FB.Connect.requireSession(devise.facebook_connectable.login);
27
+ devise.facebook_connectable.sign_in_with_callback = function fbc_sign_in_with_callback() {
28
+ FB.Connect.requireSession(devise.facebook_connectable.sign_in);
29
29
  return false;
30
30
  };
31
31
 
32
32
  /*
33
33
  * Logout.
34
34
  */
35
- devise.facebook_connectable.logout = function fbc_logout() {
36
- document.getElementById('fb_connect_logout_form').submit();
35
+ devise.facebook_connectable.sign_out = function fbc_sign_out() {
36
+ document.getElementById('fb_connect_sign_out_form').submit();
37
37
  return false;
38
38
  };
39
39
 
40
40
  /*
41
41
  * Logout - with callback.
42
42
  */
43
- devise.facebook_connectable.logout_with_callback = function fbc_logout_with_callback() {
44
- FB.Connect.logout(devise.facebook_connectable.logout);
43
+ devise.facebook_connectable.sign_out_with_callback = function fbc_sign_out_with_callback() {
44
+ FB.Connect.logout(devise.facebook_connectable.sign_out);
45
45
  return false;
46
46
  };
47
47
 
@@ -14,7 +14,6 @@ rescue
14
14
  end
15
15
 
16
16
  require 'devise_facebook_connectable/model'
17
- require 'devise_facebook_connectable/serializer'
18
17
  require 'devise_facebook_connectable/strategy'
19
18
  require 'devise_facebook_connectable/schema'
20
19
  require 'devise_facebook_connectable/routes'
@@ -42,11 +41,14 @@ end
42
41
 
43
42
  # Load core I18n locales: en
44
43
  #
45
- I18n.load_path.unshift File.expand_path(File.join(File.dirname(__FILE__), *%w[devise_facebook_connectable locales en.yml]))
44
+ I18n.load_path.unshift File.join(File.dirname(__FILE__), *%w[devise_facebook_connectable locales en.yml])
46
45
 
47
- # Add +:facebook_connectable+ serializers and strategies to defaults.
46
+ # Add +:facebook_connectable+ strategies to defaults.
48
47
  #
49
48
  Devise::ALL.unshift :facebook_connectable
50
49
  Devise::STRATEGIES.unshift :facebook_connectable
51
- Devise::SERIALIZERS.unshift :facebook_connectable
52
50
  Devise::CONTROLLERS[:sessions].unshift :facebook_connectable
51
+
52
+ Devise::Models.module_eval do
53
+ autoload :FacebookConnectable, 'devise_facebook_connectable/model'
54
+ end
@@ -1,16 +1,21 @@
1
1
  # encoding: utf-8
2
2
  require 'facebooker/session'
3
3
 
4
- module Devise
5
- module FacebookConnectable
6
- module Controllers
4
+ module Devise #:nodoc:
5
+ module FacebookConnectable #:nodoc:
6
+ module Controllers #:nodoc:
7
+
8
+ # Controller filters (extensions) needed for Facebook Connect.
9
+ #
7
10
  module Filters
8
11
 
9
- def self.included(base)
12
+ def self.included(base) #:nodoc:
10
13
  base.class_eval do
11
14
  before_filter :expired_session_hack
12
15
  before_filter :set_facebook_session
16
+
13
17
  rescue_from ::Facebooker::Session::SessionExpired, :with => :facebook_session_expired
18
+ rescue_from ::ActionController::InvalidAuthenticityToken, :with => :invalid_authenticity_token
14
19
 
15
20
  helper_method :facebook_session
16
21
 
@@ -26,7 +31,15 @@ module Devise
26
31
  #
27
32
  def facebook_session_expired
28
33
  reset_session
29
- redirect_to root_url
34
+ set_flash_message :failure, :facebook_timeout
35
+ render_with_scope :new, :controller => :sessions
36
+ end
37
+
38
+ # Handle expired Facebook sessions automatically.
39
+ #
40
+ def invalid_authenticity_token
41
+ set_now_flash_message :failure, :facebook_authenticity_token
42
+ render_with_scope :new, :controller => :sessions
30
43
  end
31
44
 
32
45
  end
@@ -2,6 +2,8 @@ en:
2
2
  devise:
3
3
  sessions:
4
4
  facebook_invalid: "Could not login. Invalid account."
5
- facebook_session_expired: "Could not login. Facebook Connect session expired."
6
- facebook_login: "Connect"
7
- facebook_logout: "Logout"
5
+ facebook_timeout: "Facebook session expired., please sign in again to continue."
6
+ facebook_authenticity_token: "Something went wrong. For security reasons, please sign in again." # Revise this message =)
7
+ facebook_actions:
8
+ sign_in: "Sign in" # NOTE: Not used for the default Facebook Connect button.
9
+ sign_out: "Sign out"
@@ -2,35 +2,34 @@
2
2
  require 'devise/models'
3
3
  require 'facebooker/session'
4
4
  require 'devise_facebook_connectable/strategy'
5
- require 'devise_facebook_connectable/serializer'
6
5
 
7
- module Devise
8
- module FacebookConnectable
9
- module Model
6
+ module Devise #:nodoc:
7
+ # module FacebookConnectable #:nodoc:
8
+ module Models #:nodoc:
10
9
 
11
10
  # Facebook Connectable Module, responsible for validating authenticity of a
12
11
  # user and storing credentials while signing in using their Facebook account.
13
12
  #
14
- # Configuration:
13
+ # == Configuration:
15
14
  #
16
15
  # You can overwrite configuration values by setting in globally in Devise (+Devise.setup+),
17
16
  # using devise method, or overwriting the respective instance method.
18
17
  #
19
- # facebook_uid_field: Defines the name of the Facebook user UID database attribute/column.
18
+ # +facebook_uid_field+ - Defines the name of the Facebook user UID database attribute/column.
20
19
  #
21
- # facebook_session_key_field: Defines the name of the Facebook session key database attribute/column.
20
+ # +facebook_session_key_field+ - Defines the name of the Facebook session key database attribute/column.
22
21
  #
23
- # facebook_auto_create_account: Speifies if account should automatically be created upon connect
22
+ # +facebook_auto_create_account+ - Speifies if account should automatically be created upon connect
24
23
  # if not already exists.
25
24
  #
26
- # Examples:
25
+ # == Examples:
27
26
  #
28
27
  # User.facebook_connect(:uid => '123456789') # returns authenticated user or nil
29
28
  # User.find(1).facebook_connected? # returns true/false
30
29
  #
31
30
  module FacebookConnectable
32
31
 
33
- def self.included(base)
32
+ def self.included(base) #:nodoc:
34
33
  base.class_eval do
35
34
  extend ClassMethods
36
35
  extend ::Devise::Models::SessionSerializer
@@ -43,14 +42,17 @@ module Devise
43
42
  self.send(:"#{self.class.facebook_uid_field}=", attributes[:uid])
44
43
  self.send(:"#{self.class.facebook_session_key_field}=", attributes[:session_key])
45
44
 
46
- # Only populate +email+ field if it's available (say, if +authenticable+ module is used).
45
+ # Confirm without e-mail - if confirmable module is loaded.
46
+ self.skip_confirmation! if self.respond_to?(:skip_confirmation!)
47
+
48
+ # Only populate +email+ field if it's available (e.g. if +authenticable+ module is used).
47
49
  self.email = attributes[:email] || '' if self.respond_to?(:email)
48
50
 
49
51
  # Lazy hack: These database fields are required if +authenticable+/+confirmable+
50
- # module(s) is used.
52
+ # module(s) is used. Could be avoided with :null => true for authenticatable
53
+ # migration, but keeping this to avoid unnecessary problems.
51
54
  self.password_salt = '' if self.respond_to?(:password_salt)
52
55
  self.encrypted_password = '' if self.respond_to?(:encrypted_password)
53
- self.confirmed_at = ::Time.now if self.respond_to?(:confirmed_at)
54
56
  end
55
57
 
56
58
  # Checks if Facebook Connect:ed.
@@ -60,12 +62,12 @@ module Devise
60
62
  end
61
63
  alias :is_facebook_connected? :facebook_connected?
62
64
 
63
- # Hook that gets called before connect (each time). Useful for
65
+ # Hook that gets called *before* connect (each time). Useful for
64
66
  # fetching additional user info (etc.) from Facebook.
65
67
  #
66
68
  # Default: Do nothing.
67
69
  #
68
- # Examples:
70
+ # == Examples:
69
71
  #
70
72
  # # Overridden in Facebook Connect:able model, e.g. "User".
71
73
  # #
@@ -97,11 +99,33 @@ module Devise
97
99
  #
98
100
  # end
99
101
  #
100
- # For more info:
101
- # http://facebooker.pjkh.com/user/populate
102
+ # == For more info:
103
+ #
104
+ # * http://facebooker.pjkh.com/user/populate
102
105
  #
103
- def on_before_facebook_connect(fb_session)
104
- self.send(:before_facebook_connect, fb_session) rescue nil
106
+ def on_before_facebook_connect(facebook_session)
107
+ if self.respond_to?(:before_facebook_connect)
108
+ self.send(:before_facebook_connect, facebook_session) rescue nil
109
+ end
110
+ end
111
+
112
+ # Hook that gets called *after* connect (each time). Useful for
113
+ # fetching additional user info (etc.) from Facebook.
114
+ #
115
+ # Default: Do nothing.
116
+ #
117
+ # == Example:
118
+ #
119
+ # # Overridden in Facebook Connect:able model, e.g. "User".
120
+ # #
121
+ # def after_facebook_connect(fb_session)
122
+ # # See "on_before_facebook_connect" example.
123
+ # end
124
+ #
125
+ def on_after_facebook_connect(facebook_session)
126
+ if self.respond_to?(:after_facebook_connect)
127
+ self.send(:after_facebook_connect, facebook_session) rescue nil
128
+ end
105
129
  end
106
130
 
107
131
  # Optional: Store session key.
@@ -115,10 +139,10 @@ module Devise
115
139
  # Optional: Recreate Facebook session for this account/user.
116
140
  #
117
141
  def new_facebook_session
142
+ timeout_in = ::Devise.respond_to?(:timeout_in) ? ::Devise.timeout_in : 1.hour.from_now
118
143
  returning(::Facebooker::Session.create) do |new_session|
119
144
  new_session.secure_with!(self.send(:"#{self.class.facebook_session_key_field}"),
120
- self.send(:"#{self.class.facebook_uid_field}"),
121
- 1.hour.from_now
145
+ self.send(:"#{self.class.facebook_uid_field}"), timeout_in
122
146
  )
123
147
  ::Facebooker::Session.current = new_session
124
148
  end
@@ -135,7 +159,7 @@ module Devise
135
159
 
136
160
  # Configuration params accessible within +Devise.setup+ procedure (in initalizer).
137
161
  #
138
- # Example:
162
+ # == Example:
139
163
  #
140
164
  # Devise.setup do |config|
141
165
  # config.facebook_uid_field = :facebook_uid
@@ -151,6 +175,7 @@ module Devise
151
175
 
152
176
  # Alias don't work for some reason, so...a more Ruby-ish alias
153
177
  # for +facebook_auto_create_account+.
178
+ #
154
179
  def facebook_auto_create_account?
155
180
  self.facebook_auto_create_account
156
181
  end
@@ -169,7 +194,7 @@ module Devise
169
194
  # Overwrite to add customized conditions, create a join, or maybe use a
170
195
  # namedscope to filter records while authenticating.
171
196
  #
172
- # Example:
197
+ # == Example:
173
198
  #
174
199
  # def self.find_for_facebook_connect(conditions = {})
175
200
  # conditions[:active] = true
@@ -191,9 +216,5 @@ module Devise
191
216
 
192
217
  end
193
218
  end
194
- end
195
- end
196
-
197
- Devise::Models.module_eval do
198
- include ::Devise::FacebookConnectable::Model
219
+ # end
199
220
  end
@@ -3,7 +3,9 @@
3
3
  ActionController::Routing::RouteSet::Mapper.class_eval do
4
4
 
5
5
  protected
6
- # Re-use "authenticatable"-stuff.
6
+
7
+ # Setup routes for +FacebookSessionsController+.
8
+ #
7
9
  alias :facebook_connectable :authenticatable
8
10
 
9
11
  end
@@ -2,11 +2,12 @@
2
2
  require 'devise/schema'
3
3
  require 'devise_facebook_connectable/model'
4
4
 
5
- module Devise
6
- module FacebookConnectable
5
+ module Devise #:nodoc:
6
+ module FacebookConnectable #:nodoc:
7
+
7
8
  module Schema
8
9
 
9
- # Creates facebook_uid and facebook_session_key (for Facebook Connect authentication/management).
10
+ # Database migration schema for Facebook Connect.
10
11
  #
11
12
  def facebook_connectable
12
13
  apply_schema ::Devise.facebook_uid_field, Integer, :limit => 8 # BIGINT unsigned / 64-bit int
@@ -2,62 +2,65 @@
2
2
  require 'devise/strategies/base'
3
3
  require 'facebooker/session'
4
4
 
5
- module Devise
6
- module FacebookConnectable
5
+ module Devise #:nodoc:
6
+ module FacebookConnectable #:nodoc:
7
+ module Strategies #:nodoc:
7
8
 
8
- # Default strategy for signing in a user using Facebook Connect (a Facebook account).
9
- # Redirects to sign_in page if it's not authenticated
10
- #
11
- class Strategy < ::Warden::Strategies::Base
9
+ # Default strategy for signing in a user using Facebook Connect (a Facebook account).
10
+ # Redirects to sign_in page if it's not authenticated
11
+ #
12
+ class FacebookConnectable < ::Warden::Strategies::Base
12
13
 
13
- include ::Devise::Strategies::Base
14
+ include ::Devise::Strategies::Base
14
15
 
15
- # Without a Facebook session authentication cannot proceed.
16
- #
17
- def valid?
18
- ::Facebooker::Session.current.present?
19
- end
16
+ # Without a Facebook session authentication cannot proceed.
17
+ #
18
+ def valid?
19
+ ::Facebooker::Session.current.present?
20
+ end
20
21
 
21
- # Authenticate user with Facebook Connect.
22
- #
23
- def authenticate!
24
- klass = mapping.to
25
- begin
26
- facebook_session = ::Facebooker::Session.current # session[:facebook_session]
27
- facebook_user = facebook_session.user
28
-
29
- user = klass.facebook_connect(:uid => facebook_user.uid)
30
-
31
- if user.present?
32
- success!(user)
33
- else
34
- if klass.facebook_auto_create_account?
35
- user = returning(klass.new) do |u|
36
- u.store_facebook_credentials!(
37
- :session_key => facebook_session.session_key,
38
- :uid => facebook_user.uid
39
- )
40
- u.on_before_facebook_connect(facebook_session)
41
- end
22
+ # Authenticate user with Facebook Connect.
23
+ #
24
+ def authenticate!
25
+ klass = mapping.to
26
+ begin
27
+ facebook_session = ::Facebooker::Session.current # session[:facebook_session]
28
+ facebook_user = facebook_session.user
42
29
 
43
- begin
44
- user.save_with_validation(false)
45
- success!(user)
46
- rescue
30
+ user = klass.facebook_connect(:uid => facebook_user.uid)
31
+
32
+ if user.present?
33
+ success!(user)
34
+ else
35
+ if klass.facebook_auto_create_account?
36
+ user = returning(klass.new) do |u|
37
+ u.store_facebook_credentials!(
38
+ :session_key => facebook_session.session_key,
39
+ :uid => facebook_user.uid
40
+ )
41
+ u.on_before_facebook_connect(facebook_session)
42
+ end
43
+
44
+ begin
45
+ user.save_with_validation(false)
46
+ user.on_after_facebook_connect(facebook_session)
47
+ success!(user)
48
+ rescue
49
+ fail!(:facebook_invalid)
50
+ end
51
+ else
47
52
  fail!(:facebook_invalid)
48
53
  end
49
- else
50
- fail!(:facebook_invalid)
51
54
  end
55
+ # NOTE: Facebooker::Session::SessionExpired errors handled in the controller.
56
+ rescue => e
57
+ fail!(e.message)
52
58
  end
53
- # NOTE: Handled in the controller.
54
- rescue # ::Facebooker::Session::SessionExpired
55
- fail!(:facebook_invalid)
56
59
  end
57
- end
58
60
 
61
+ end
59
62
  end
60
63
  end
61
64
  end
62
65
 
63
- Warden::Strategies.add(:facebook_connectable, Devise::FacebookConnectable::Strategy)
66
+ Warden::Strategies.add(:facebook_connectable, Devise::FacebookConnectable::Strategies::FacebookConnectable)
@@ -1,101 +1,113 @@
1
1
  # encoding: utf-8
2
2
  require 'devise/mapping'
3
+ require 'facebooker/rails/helpers'
3
4
 
4
- # Facebook Connect view helpers, i.e. connect/login/logout links, etc.
5
- #
6
- # Dependencies:
7
- #
8
- # +devise.facebook_connectable.js+ (is generated with the generator)
9
- #
10
- module Devise
11
- module FacebookConnectable
5
+ module Devise #:nodoc:
6
+ module FacebookConnectable #:nodoc:
7
+
8
+ # Facebook Connect view helpers, i.e. sign in/out (connect) links, etc.
9
+ #
10
+ # == Dependencies:
11
+ #
12
+ # * devise.facebook_connectable.js (is generated with the generator)
13
+ #
12
14
  module Helpers
13
15
 
14
- # References:
16
+ # == References:
15
17
  #
16
18
  # * http://facebooker.rubyforge.org/
17
19
  # * http://wiki.developers.facebook.com/index.php/Connect/Authorization_Websites
18
20
  # * http://developers.facebook.com/docs/?u=facebook.jslib.FB.Connect
19
21
  #
20
22
 
21
- # Known issues:
23
+ # == Known issues:
22
24
  #
23
- # * autologoutlink - There's no onlogout callback - only onlogin, so it's not straightforward
24
- # to trigger submit on the logout form to destroy the Warden session.
25
- # Best solution now is either to hook the even manually on click,
26
- # or use regular link like propsed here:
25
+ # * *autologoutlink* - There's no onlogout callback - only onlogin, so it's not straightforward
26
+ # to trigger submit on the sign out form to destroy the Warden session.
27
+ # Best solution now is either to hook the even manually on click,
28
+ # or use regular link like propsed here:
27
29
  #
28
30
  # http://forum.developers.facebook.com/viewtopic.php?pid=121283
29
31
  #
30
32
 
31
- # Make the Facebook Connect strings localized with current locale
32
- # by default. Just for convenience.
33
- #
34
- def localized_fb_connect_javascript_tag(options = {})
35
- fb_connect_javascript_tag(options.reverse_merge(:lang => ::I18n.locale))
36
- end
37
-
38
- # Convenient connect/login/logout method. See below.
33
+ # Convenient sign in/out (connect) method. See below.
39
34
  #
40
35
  def facebook_link(options = {})
41
- unless signed_in?(options[:for])
42
- facebook_login_or_connect_link(options)
36
+ scope = auto_detect_scope(options.slice(:scope, :for))
37
+ options.except!(:scope, :for)
38
+
39
+ unless signed_in?(scope)
40
+ facebook_sign_in_link(options.merge(:scope => scope))
43
41
  else
44
- facebook_logout_link(options)
42
+ facebook_sign_out_link(options.merge(:scope => scope))
45
43
  end
46
44
  end
47
45
 
48
- # Agnostic Facebook Connect login/connect button/link.
46
+ # Deprecated in favor for +facebook_sign_in_link+.
49
47
  #
50
- # Case 1: If Facebook account already connected to the app/site, this is same as
51
- # a traditional "account login" but with the Facebook dialog unless already
48
+ def facebook_login_link(options = {})
49
+ ::ActiveSupport::Deprecation.warn("facebook_login_link is deprecated. Use: facebook_sign_in_link")
50
+ facebook_sign_in_link(options)
51
+ end
52
+
53
+ # Deprecated in favor for +facebook_sign_in_link+.
54
+ #
55
+ def facebook_logout_link(options = {})
56
+ ::ActiveSupport::Deprecation.warn("facebook_logout_link is deprecated. Use: facebook_sign_out_link")
57
+ facebook_sign_out_link(options)
58
+ end
59
+
60
+ # Agnostic Facebook Connect sign in/out (connect) button/link.
61
+ #
62
+ # *Case 1:* If Facebook account already connected to the app/site, this is same as
63
+ # a traditional "account sign in" but with the Facebook dialog unless already
52
64
  # logged in to Facebook.
53
65
  #
54
- # Case 2: If account is not connected to the app/site already;
66
+ # *Case 2:* If account is not connected to the app/site already;
55
67
  # then this is the same as a traditional "create account".
56
68
  #
57
- def facebook_login_or_connect_link(options = {})
58
- resource = options.delete(:for)
69
+ def facebook_sign_in_link(options = {})
70
+ scope = auto_detect_scope(options.slice(:scope, :for))
71
+ options.except!(:scope, :for)
59
72
  options.reverse_merge!(
60
- :label => ::I18n.t(:facebook_login, :scope => [:devise, :sessions]),
73
+ :label => ::I18n.t(:sign_in, :scope => [:devise, :sessions, :facebook_actions]),
61
74
  :size => :large,
62
75
  :length => :long,
63
76
  :background => :white,
64
77
  :button => true,
65
78
  :autologoutlink => false
66
79
  )
80
+ options.merge!(:sign_out => true) if options[:autologoutlink] && signed_in?(scope)
67
81
 
68
- # It seems Devise using :get method for session destroy. Not really RESTful?
69
- # options.merge!(:method => :delete) if options[:autologoutlink] && signed_in?(options[:for])
70
-
71
- content_tag(:span, :class => 'fb_connect_login_link') do
72
- facebook_connect_form(resource, options.slice(:method)) <<
82
+ content_tag(:div, :class => 'facebook_connect_link sign_in') do
83
+ facebook_connect_form(scope, options.slice(:method)) <<
73
84
  if options[:button]
74
- fb_login_button('devise.facebook_connectable.login();', options)
85
+ fb_login_button('devise.facebook_connectable.sign_in();', options)
75
86
  else
76
- fb_logout_link(options[:label], 'devise.facebook_connectable.login_with_callback();')
87
+ fb_logout_link(options[:label], 'devise.facebook_connectable.sign_in_with_callback();')
77
88
  end
78
89
  end
79
90
  end
80
- alias :facebook_login_link :facebook_login_or_connect_link
81
- alias :facebook_connect_link :facebook_login_or_connect_link
91
+ alias :facebook_connect_link :facebook_sign_in_link
82
92
 
83
- # Agnostic Facebook Connect logout button/link. Logs out the current
93
+ # Agnostic Facebook Connect sign_out button/link. Logs out the current
84
94
  # user from both the app/site and Facebook main site (for security reasons).
85
95
  #
86
- def facebook_logout_link(options = {})
96
+ def facebook_sign_out_link(options = {})
97
+ scope = auto_detect_scope(options.slice(:scope, :for))
98
+ options.except!(:scope, :for)
87
99
  options.reverse_merge!(
88
- :label => ::I18n.t(:facebook_logout, :scope => [:devise, :sessions]),
100
+ :label => ::I18n.t(:sign_out, :scope => [:devise, :sessions, :facebook_actions]),
89
101
  :size => :large,
90
102
  :length => :long,
91
103
  :background => :white,
92
104
  :button => false
93
105
  )
94
106
 
95
- content_tag(:span, :class => 'fb_connect_logout_link') do
96
- facebook_connect_form(options.delete(:for), :logout => true, :method => :get) <<
107
+ content_tag(:div, :class => 'facebook_connect_link sign_out') do
108
+ facebook_connect_form(scope, :sign_out => true, :method => :get) <<
97
109
  if options[:button]
98
- fb_login_button('devise.facebook_connectable.logout();', options.merge(:autologoutlink => true))
110
+ fb_login_button('devise.facebook_connectable.sign_out();', options.merge(:autologoutlink => true))
99
111
  else
100
112
  fb_logout_link(options[:label], destroy_session_path(:user))
101
113
  end
@@ -106,7 +118,7 @@ module Devise
106
118
  # Disconnects, i.e. deletes, user account. Identical as "Delete my account",
107
119
  # but for Facebook Connect (which "un-installs" the app/site for the current user).
108
120
  #
109
- # References:
121
+ # == References:
110
122
  #
111
123
  # * http://wiki.developers.facebook.com/index.php/Auth.revokeAuthorization
112
124
  #
@@ -114,7 +126,7 @@ module Devise
114
126
  raise "facebook_disconnect_link: Not implemented yet."
115
127
  # TODO:
116
128
  # options.reverse_merge!(
117
- # :label => ::I18n.t(:facebook_logout, :scope => [:devise, :sessions]),
129
+ # :label => ::I18n.t(:facebook_disconnect, :scope => [:devise, :sessions, :actions]),
118
130
  # )
119
131
  # content_tag(:div, :class => 'fb_connect_disconnect_link') do
120
132
  # link_to_function(options[:label], 'devise.facebook_connectable.disconnect_with_callback();')
@@ -123,21 +135,49 @@ module Devise
123
135
 
124
136
  protected
125
137
 
126
- # Generate agnostic hidden login/logout form for Facebook Connect.
138
+ # Auto-detect Devise scope using +Warden::Manager.default_scope+.
139
+ # Used to make the link-helpers smart if - like in most cases -
140
+ # only one devise scope will be used, e.g. "user" or "account".
141
+ #
142
+ def auto_detect_scope(options = {})
143
+ scope = options[:scope] || options[:for]
144
+ scope ||= ::Warden::Manager.default_scope
145
+ mapping = ::Devise::Mapping.new(scope, {})
146
+
147
+ if mapping.for.include?(:facebook_connectable)
148
+ scope
149
+ else
150
+ error_message =
151
+ "devise/facebook_connectable: %s" <<
152
+ " Did you forget to devise facebook_connect in your model? Like this: devise :facebook_connectable." <<
153
+ " You can also specify scope explicitly, e.g.: facebook_*link :for => :customer."
154
+ error_message %=
155
+ if scope.present?
156
+ "#{scope.inspect} is not a valid facebook_connectable devise scope. " <<
157
+ "Loaded modules for this scope: #{mapping.for.inspect}."
158
+ else
159
+ "Could not auto-detect any facebook_connectable devise-model."
160
+ end
161
+ raise error_message
162
+ end
163
+ end
164
+
165
+ # Generate agnostic hidden sign in/out (connect) form for Facebook Connect.
127
166
  #
128
- def facebook_connect_form(for_resource, options = {})
129
- logout_form = options.delete(:logout) || (options[:method] == :delete)
167
+ def facebook_connect_form(scope, options = {})
168
+ sign_out_form = options.delete(:sign_out)
130
169
  options.reverse_merge!(
131
- :id => (logout_form ? 'fb_connect_logout_form' : 'fb_connect_login_form'),
170
+ :id => (sign_out_form ? 'fb_connect_sign_out_form' : 'fb_connect_sign_in_form'),
132
171
  :style => 'display:none;'
133
172
  )
134
- resource = ::Devise::Mapping.find_by_path(request.path).to rescue for_resource
135
- url = logout_form ? destroy_session_path(resource) : session_path(resource)
136
- form_for(resource, :url => url, :html => options) { |f| }
173
+ scope = ::Devise::Mapping.find_by_path(request.path).to rescue scope
174
+ url = sign_out_form ? destroy_session_path(scope) : session_path(scope)
175
+
176
+ form_for(scope, :url => url, :html => options) { |f| }
137
177
  end
138
178
 
139
179
  end
140
180
  end
141
181
  end
142
182
 
143
- ::ActionView::Base.send :include, ::Devise::FacebookConnectable::Helpers
183
+ ::ActionView::Base.send :include, Devise::FacebookConnectable::Helpers
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: devise_facebook_connectable
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.5
4
+ version: 0.1.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jonas Grimfelt
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-12-11 00:00:00 +01:00
12
+ date: 2009-12-16 00:00:00 +01:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -30,7 +30,7 @@ dependencies:
30
30
  requirements:
31
31
  - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: 0.7.1
33
+ version: 0.7.3
34
34
  version:
35
35
  - !ruby/object:Gem::Dependency
36
36
  name: facebooker
@@ -59,7 +59,6 @@ extra_rdoc_files:
59
59
  - lib/devise_facebook_connectable/model.rb
60
60
  - lib/devise_facebook_connectable/routes.rb
61
61
  - lib/devise_facebook_connectable/schema.rb
62
- - lib/devise_facebook_connectable/serializer.rb
63
62
  - lib/devise_facebook_connectable/strategy.rb
64
63
  - lib/devise_facebook_connectable/view_helpers.rb
65
64
  files:
@@ -73,7 +72,6 @@ files:
73
72
  - lib/devise_facebook_connectable/model.rb
74
73
  - lib/devise_facebook_connectable/routes.rb
75
74
  - lib/devise_facebook_connectable/schema.rb
76
- - lib/devise_facebook_connectable/serializer.rb
77
75
  - lib/devise_facebook_connectable/strategy.rb
78
76
  - lib/devise_facebook_connectable/view_helpers.rb
79
77
  has_rdoc: true
@@ -1,4 +0,0 @@
1
- # encoding: utf-8
2
- require 'devise/serializers/authenticatable'
3
-
4
- Warden::Serializers.add(:facebook_connectable, Devise::Serializers::Authenticatable)