sorcery 0.1.4 → 0.2.0

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.

Potentially problematic release.


This version of sorcery might be problematic. Click here for more details.

Files changed (65) hide show
  1. data/Gemfile +4 -2
  2. data/Gemfile.lock +16 -13
  3. data/README.rdoc +28 -27
  4. data/Rakefile +5 -0
  5. data/VERSION +1 -1
  6. data/lib/sorcery.rb +12 -0
  7. data/lib/sorcery/controller.rb +29 -17
  8. data/lib/sorcery/controller/submodules/activity_logging.rb +20 -7
  9. data/lib/sorcery/controller/submodules/brute_force_protection.rb +9 -2
  10. data/lib/sorcery/controller/submodules/http_basic_auth.rb +8 -3
  11. data/lib/sorcery/controller/submodules/oauth.rb +95 -0
  12. data/lib/sorcery/controller/submodules/oauth/oauth1.rb +25 -0
  13. data/lib/sorcery/controller/submodules/oauth/oauth2.rb +23 -0
  14. data/lib/sorcery/controller/submodules/oauth/providers/facebook.rb +64 -0
  15. data/lib/sorcery/controller/submodules/oauth/providers/twitter.rb +61 -0
  16. data/lib/sorcery/controller/submodules/remember_me.rb +14 -5
  17. data/lib/sorcery/controller/submodules/session_timeout.rb +6 -1
  18. data/lib/sorcery/engine.rb +9 -2
  19. data/lib/sorcery/model.rb +10 -3
  20. data/lib/sorcery/model/submodules/activity_logging.rb +12 -7
  21. data/lib/sorcery/model/submodules/brute_force_protection.rb +11 -4
  22. data/lib/sorcery/model/submodules/oauth.rb +53 -0
  23. data/lib/sorcery/model/submodules/remember_me.rb +5 -3
  24. data/lib/sorcery/model/submodules/reset_password.rb +16 -13
  25. data/lib/sorcery/model/submodules/user_activation.rb +38 -19
  26. data/lib/sorcery/model/temporary_token.rb +22 -0
  27. data/lib/sorcery/test_helpers.rb +84 -0
  28. data/sorcery.gemspec +69 -40
  29. data/spec/Gemfile +3 -2
  30. data/spec/Gemfile.lock +15 -2
  31. data/spec/rails3/app_root/.rspec +1 -0
  32. data/spec/rails3/{Gemfile → app_root/Gemfile} +5 -3
  33. data/spec/rails3/{Gemfile.lock → app_root/Gemfile.lock} +25 -2
  34. data/spec/rails3/{Rakefile → app_root/Rakefile} +0 -0
  35. data/spec/rails3/app_root/app/controllers/application_controller.rb +42 -1
  36. data/spec/rails3/app_root/app/models/authentication.rb +3 -0
  37. data/spec/rails3/app_root/app/models/user.rb +4 -1
  38. data/spec/rails3/app_root/config/application.rb +1 -3
  39. data/spec/rails3/app_root/config/routes.rb +1 -10
  40. data/spec/rails3/app_root/db/migrate/activation/20101224223622_add_activation_to_users.rb +6 -4
  41. data/spec/rails3/app_root/db/migrate/core/20101224223620_create_users.rb +4 -4
  42. data/spec/rails3/app_root/db/migrate/oauth/20101224223628_create_authentications.rb +14 -0
  43. data/spec/rails3/{controller_activity_logging_spec.rb → app_root/spec/controller_activity_logging_spec.rb} +13 -13
  44. data/spec/rails3/{controller_brute_force_protection_spec.rb → app_root/spec/controller_brute_force_protection_spec.rb} +16 -6
  45. data/spec/rails3/{controller_http_basic_auth_spec.rb → app_root/spec/controller_http_basic_auth_spec.rb} +3 -3
  46. data/spec/rails3/app_root/spec/controller_oauth2_spec.rb +117 -0
  47. data/spec/rails3/app_root/spec/controller_oauth_spec.rb +117 -0
  48. data/spec/rails3/{controller_remember_me_spec.rb → app_root/spec/controller_remember_me_spec.rb} +4 -4
  49. data/spec/rails3/{controller_session_timeout_spec.rb → app_root/spec/controller_session_timeout_spec.rb} +4 -4
  50. data/spec/rails3/{controller_spec.rb → app_root/spec/controller_spec.rb} +20 -13
  51. data/spec/rails3/app_root/spec/spec_helper.orig.rb +27 -0
  52. data/spec/rails3/app_root/spec/spec_helper.rb +61 -0
  53. data/spec/rails3/{user_activation_spec.rb → app_root/spec/user_activation_spec.rb} +60 -20
  54. data/spec/rails3/{user_activity_logging_spec.rb → app_root/spec/user_activity_logging_spec.rb} +4 -4
  55. data/spec/rails3/{user_brute_force_protection_spec.rb → app_root/spec/user_brute_force_protection_spec.rb} +7 -7
  56. data/spec/rails3/app_root/spec/user_oauth_spec.rb +39 -0
  57. data/spec/rails3/{user_remember_me_spec.rb → app_root/spec/user_remember_me_spec.rb} +4 -4
  58. data/spec/rails3/{user_reset_password_spec.rb → app_root/spec/user_reset_password_spec.rb} +21 -41
  59. data/spec/rails3/{user_spec.rb → app_root/spec/user_spec.rb} +68 -38
  60. metadata +127 -58
  61. data/spec/rails3/app_root/test/fixtures/users.yml +0 -9
  62. data/spec/rails3/app_root/test/performance/browsing_test.rb +0 -9
  63. data/spec/rails3/app_root/test/test_helper.rb +0 -13
  64. data/spec/rails3/app_root/test/unit/user_test.rb +0 -8
  65. data/spec/rails3/spec_helper.rb +0 -135
data/Gemfile CHANGED
@@ -2,11 +2,13 @@ source "http://rubygems.org"
2
2
  # Add dependencies required to use your gem here.
3
3
  # Example:
4
4
  # gem "activesupport", ">= 2.3.5"
5
-
5
+ gem "rails", ">= 3.0.0"
6
+ gem 'json', ">= 1.5.1"
7
+ gem 'oauth', ">= 0.4.4"
8
+ gem 'oauth2', ">= 0.1.1"
6
9
  # Add dependencies to develop your gem here.
7
10
  # Include everything needed to run rake, tests, features, etc.
8
11
  group :development do
9
- gem "rails", ">= 3.0.0"
10
12
  gem "rspec", "~> 2.3.0"
11
13
  gem 'rspec-rails'
12
14
  gem 'ruby-debug19'
data/Gemfile.lock CHANGED
@@ -28,29 +28,25 @@ GEM
28
28
  activemodel (= 3.0.3)
29
29
  activesupport (= 3.0.3)
30
30
  activesupport (3.0.3)
31
+ addressable (2.2.4)
31
32
  archive-tar-minitar (0.5.2)
32
33
  arel (2.0.6)
33
34
  builder (2.1.2)
34
35
  columnize (0.3.2)
35
- cucumber (0.10.0)
36
- builder (>= 2.1.2)
37
- diff-lcs (~> 1.1.2)
38
- gherkin (~> 2.3.2)
39
- json (~> 1.4.6)
40
- term-ansicolor (~> 1.0.5)
41
36
  diff-lcs (1.1.2)
42
37
  erubis (2.6.6)
43
38
  abstract (>= 1.0.0)
44
- gherkin (2.3.2)
45
- json (~> 1.4.6)
46
- term-ansicolor (~> 1.0.5)
39
+ faraday (0.5.5)
40
+ addressable (~> 2.2.4)
41
+ multipart-post (~> 1.1.0)
42
+ rack (>= 1.1.0, < 2)
47
43
  git (1.2.5)
48
44
  i18n (0.5.0)
49
45
  jeweler (1.5.2)
50
46
  bundler (~> 1.0.0)
51
47
  git (>= 1.2.5)
52
48
  rake
53
- json (1.4.6)
49
+ json (1.5.1)
54
50
  linecache19 (0.5.11)
55
51
  ruby_core_source (>= 0.1.4)
56
52
  mail (2.2.13)
@@ -59,6 +55,12 @@ GEM
59
55
  mime-types (~> 1.16)
60
56
  treetop (~> 1.4.8)
61
57
  mime-types (1.16)
58
+ multi_json (0.0.5)
59
+ multipart-post (1.1.0)
60
+ oauth (0.4.4)
61
+ oauth2 (0.1.1)
62
+ faraday (~> 0.5.0)
63
+ multi_json (~> 0.0.4)
62
64
  polyglot (0.3.1)
63
65
  rack (1.2.1)
64
66
  rack-mount (0.6.13)
@@ -106,7 +108,6 @@ GEM
106
108
  simplecov-html (>= 0.3.7)
107
109
  simplecov-html (0.3.9)
108
110
  sqlite3-ruby (1.3.2)
109
- term-ansicolor (1.0.5)
110
111
  thor (0.14.6)
111
112
  treetop (1.4.9)
112
113
  polyglot (>= 0.3.1)
@@ -118,9 +119,11 @@ PLATFORMS
118
119
 
119
120
  DEPENDENCIES
120
121
  bundler (~> 1.0.0)
121
- cucumber
122
122
  jeweler (~> 1.5.2)
123
- rails (= 3.0.3)
123
+ json (>= 1.5.1)
124
+ oauth (>= 0.4.4)
125
+ oauth2 (>= 0.1.1)
126
+ rails (>= 3.0.0)
124
127
  rspec (~> 2.3.0)
125
128
  rspec-rails
126
129
  ruby-debug19
data/README.rdoc CHANGED
@@ -3,28 +3,45 @@ Magical Authentication for Rails 3.
3
3
 
4
4
  Inspired by restful_authentication, Authlogic and Devise.
5
5
  Crypto code taken almost unchanged from Authlogic.
6
+ OAuth code inspired by OmniAuth.
6
7
 
7
- == Example app using sorcery:
8
+ == Summary
8
9
 
9
- https://github.com/NoamB/sorcery-example-app
10
+ Sorcery aims to make your life easier by giving you an easy API to write your own user authentication flow with.
11
+ It does this with a few goals in mind:
12
+
13
+ * Less is more - less than 20 simple methods to remember for the entire feature-set make the lib easy to 'get'.
14
+ * No built-in or generated code - use the API inside *your own* MVC structures, and don't fight to fix someone else's.
15
+ * Magic yes, Voodoo no - the lib should be easy to hack for most developers.
16
+ * Configuration over Confusion - Simple & short configuration as possible, not drowning in syntactic sugar.
17
+ * Keep MVC cleanly separated - DB is for models, sessions are for controllers. Models stay unaware of sessions.
18
+
19
+ Hopefully, I've achieved this. If not, let me know.
20
+
21
+ == Useful Links:
22
+
23
+ Example app using sorcery: https://github.com/NoamB/sorcery-example-app
24
+
25
+ Documentation: http://rubydoc.info/gems/sorcery/0.1.4/frames
10
26
 
11
27
  == Full Features List by module:
12
28
 
13
29
  Core (see lib/sorcery/model/model.rb and lib/sorcery/controller/controller.rb):
14
- * login/logout, optional redirect on login to where the user tried to reach before, configurable redirect for non-logged-in users.
30
+ * login/logout, optional return user to requested url on login, configurable redirect for non-logged-in users.
15
31
  * password encryption, algorithms: bcrypt(default), md5, sha1, sha256, sha512, aes256, custom(yours!), none. Configurable stretches and salt.
16
32
  * configurable attribute names for username, password and email.
17
33
 
18
34
  User Activation (see lib/sorcery/model/submodules/user_activation.rb):
19
35
  * User activation by email with optional success email.
20
36
  * configurable attribute names.
21
- * configurable mailer.
37
+ * configurable mailer, method name, and attribute name.
38
+ * configurable temporary token expiration.
22
39
  * Optionally prevent non-active users to login.
23
40
 
24
41
  Reset Password (see lib/sorcery/model/submodules/reset_password.rb):
25
42
  * Reset password with email verification.
26
43
  * configurable mailer, method name, and attribute name.
27
- * configurable expiration.
44
+ * configurable temporary token expiration.
28
45
  * configurable time between emails (hammering protection).
29
46
 
30
47
  Remember Me (see lib/sorcery/model/submodules/remember_me.rb):
@@ -49,36 +66,20 @@ Activity Logging (see lib/sorcery/model/submodules/activity_logging.rb):
49
66
  * an easy method of collecting the list of currently logged in users.
50
67
  * configurable timeout by which to decide whether to include a user in the list of logged in users.
51
68
 
52
- Other:
53
- * Modular design, load only the modules you need.
54
- * 100% TDD'd code, 100% test coverage.
69
+ Oauth (see lib/sorcery/controller/submodules/oauth.rb):
70
+ * OAuth1 and OAuth2 support (currently twitter & facebook)
71
+ * configurable db field names and authentications table.
55
72
 
56
73
  == Next Planned Features:
57
74
 
58
- I've got many plans which include:
75
+ I've got many plans which include (by priority):
76
+ * Sinatra support
77
+ * Mongoid support
59
78
  * Configurable Auto login on registration/activation
60
79
  * Other reset password strategies (security questions?)
61
80
  * Other brute force protection strategies (captcha)
62
- * Sinatra support
63
- * Mongoid support
64
- * OAuth1 and OAuth2 support
65
81
  * Have an idea? Let me know, and it might get into the gem!
66
82
 
67
- == Project Goals:
68
-
69
- This gem plugin was started out of a few personal goals which are not related to the problem solved by it at all:
70
- * I wanted to write something 100% TDD from start to finish.
71
- * I wanted to learn how to write an engine for Rails 3.
72
-
73
- In addition to the above goals, when I decided this will be an authentication plugin, and while looking at existing solutions, these goals came up:
74
- * Simple & short configuration as possible, not drowning in syntactic sugar.
75
- * Keep MVC cleanly separated - DB is for models, sessions are for controllers. Models stay unaware of sessions.
76
- * Magic yes, Voodoo no.
77
- * No generated code polluting the application's code.
78
- * No built-in controllers, models, mailers, migrations or templates; Real apps will need all of these custom made.
79
-
80
- Hopefully, I've achieved this. If not, let me know.
81
-
82
83
  == Installation:
83
84
 
84
85
  You can either git clone and then 'rake install' to live on the edge (unstable),
data/Rakefile CHANGED
@@ -1,4 +1,5 @@
1
1
  # require 'bundler'
2
+ # -- Commented because it's slow
2
3
  # begin
3
4
  # Bundler.setup(:default, :development)
4
5
  # rescue Bundler::BundlerError => e
@@ -6,6 +7,8 @@
6
7
  # $stderr.puts "Run `bundle install` to install missing gems"
7
8
  # exit e.status_code
8
9
  # end
10
+ # --
11
+
9
12
  require 'rake'
10
13
 
11
14
  require 'jeweler'
@@ -23,6 +26,8 @@ Jeweler::Tasks.new do |gem|
23
26
  # gem.add_runtime_dependency 'jabber4r', '> 0.1'
24
27
  # gem.add_development_dependency 'rspec', '> 1.2.3'
25
28
  gem.add_runtime_dependency 'bcrypt-ruby', '~> 2.1.4'
29
+ gem.add_runtime_dependency 'oauth', '>= 0.4.4'
30
+ gem.add_runtime_dependency 'oauth2', '>= 0.1.1'
26
31
  end
27
32
  Jeweler::RubygemsDotOrgTasks.new
28
33
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.4
1
+ 0.2.0
data/lib/sorcery.rb CHANGED
@@ -1,12 +1,14 @@
1
1
  module Sorcery
2
2
  autoload :Model, 'sorcery/model'
3
3
  module Model
4
+ autoload :TemporaryToken, 'sorcery/model/temporary_token'
4
5
  module Submodules
5
6
  autoload :UserActivation, 'sorcery/model/submodules/user_activation'
6
7
  autoload :ResetPassword, 'sorcery/model/submodules/reset_password'
7
8
  autoload :RememberMe, 'sorcery/model/submodules/remember_me'
8
9
  autoload :ActivityLogging, 'sorcery/model/submodules/activity_logging'
9
10
  autoload :BruteForceProtection, 'sorcery/model/submodules/brute_force_protection'
11
+ autoload :Oauth, 'sorcery/model/submodules/oauth'
10
12
  end
11
13
  end
12
14
  autoload :Controller, 'sorcery/controller'
@@ -17,6 +19,15 @@ module Sorcery
17
19
  autoload :BruteForceProtection, 'sorcery/controller/submodules/brute_force_protection'
18
20
  autoload :HttpBasicAuth, 'sorcery/controller/submodules/http_basic_auth'
19
21
  autoload :ActivityLogging, 'sorcery/controller/submodules/activity_logging'
22
+ autoload :Oauth, 'sorcery/controller/submodules/oauth'
23
+ module Oauth
24
+ autoload :Oauth1, 'sorcery/controller/submodules/oauth/oauth1'
25
+ autoload :Oauth2, 'sorcery/controller/submodules/oauth/oauth2'
26
+ module Providers
27
+ autoload :Twitter, 'sorcery/controller/submodules/oauth/providers/twitter'
28
+ autoload :Facebook, 'sorcery/controller/submodules/oauth/providers/facebook'
29
+ end
30
+ end
20
31
  end
21
32
  end
22
33
  module CryptoProviders
@@ -27,6 +38,7 @@ module Sorcery
27
38
  autoload :SHA256, 'sorcery/crypto_providers/sha256'
28
39
  autoload :SHA512, 'sorcery/crypto_providers/sha512'
29
40
  end
41
+ autoload :TestHelpers, 'sorcery/test_helpers'
30
42
 
31
43
  require 'sorcery/engine' if defined?(Rails) && Rails::VERSION::MAJOR == 3
32
44
  end
@@ -5,7 +5,7 @@ module Sorcery
5
5
  extend ClassMethods
6
6
  include InstanceMethods
7
7
  Config.submodules.each do |mod|
8
- begin
8
+ begin # FIXME: is this protection needed?
9
9
  include Submodules.const_get(mod.to_s.split("_").map {|p| p.capitalize}.join(""))
10
10
  rescue NameError
11
11
  # don't stop on a missing submodule.
@@ -32,62 +32,74 @@ module Sorcery
32
32
  # If all attempts to auto-login fail, the failure callback will be called.
33
33
  def require_login
34
34
  if !logged_in?
35
- session[:user_wanted_url] = request.url if Config.save_user_wanted_url
35
+ session[:return_to_url] = request.url if Config.save_return_to_url
36
36
  self.send(Config.not_authenticated_action)
37
37
  end
38
38
  end
39
39
 
40
+ # Takes credentials and returns a user on successful authentication.
41
+ # Runs hooks after login or failed login.
40
42
  def login(*credentials)
41
43
  user = Config.user_class.authenticate(*credentials)
42
44
  if user
45
+ return_to_url = session[:return_to_url]
43
46
  reset_session # protect from session fixation attacks
47
+ session[:return_to_url] = return_to_url
44
48
  login_user(user)
45
49
  after_login!(user, credentials)
46
- logged_in_user
50
+ current_user
47
51
  else
48
52
  after_failed_login!(credentials)
49
53
  nil
50
54
  end
51
55
  end
52
56
 
57
+ # Resets the session and runs hooks before and after.
53
58
  def logout
54
59
  if logged_in?
55
- before_logout!(logged_in_user)
60
+ before_logout!(current_user)
56
61
  reset_session
57
62
  after_logout!
58
63
  end
59
64
  end
60
65
 
61
66
  def logged_in?
62
- !!logged_in_user
67
+ !!current_user
63
68
  end
64
69
 
65
70
  # attempts to auto-login from the sources defined (session, basic_auth, cookie, etc.)
66
71
  # returns the logged in user if found, false if not (using old restful-authentication trick, nil != false).
67
- def logged_in_user
68
- @logged_in_user ||= login_from_session || login_from_other_sources unless @logged_in_user == false
72
+ def current_user
73
+ @current_user ||= login_from_session || login_from_other_sources unless @current_user == false
69
74
  end
70
75
 
71
- def login_from_other_sources
72
- result = nil
73
- Config.login_sources.find do |source|
74
- result = send(source)
75
- end
76
- result || false
76
+ def return_or_redirect_to(url, flash_hash = {})
77
+ redirect_to(session[:return_to_url] || url, :flash => flash_hash)
77
78
  end
78
79
 
80
+ # The default action for denying non-authenticated users.
81
+ # You can override this method in your controllers.
79
82
  def not_authenticated
80
83
  redirect_to root_path
81
84
  end
82
85
 
83
86
  protected
84
87
 
88
+ # Tries all available sources (methods) until one doesn't return false.
89
+ def login_from_other_sources
90
+ result = nil
91
+ Config.login_sources.find do |source|
92
+ result = send(source)
93
+ end
94
+ result || false
95
+ end
96
+
85
97
  def login_user(user)
86
98
  session[:user_id] = user.id
87
99
  end
88
100
 
89
101
  def login_from_session
90
- @logged_in_user = (Config.user_class.find_by_id(session[:user_id]) if session[:user_id]) || false
102
+ @current_user = (Config.user_class.find_by_id(session[:user_id]) if session[:user_id]) || false
91
103
  end
92
104
 
93
105
  def after_login!(user, credentials)
@@ -112,11 +124,11 @@ module Sorcery
112
124
  class << self
113
125
  attr_accessor :submodules,
114
126
 
115
- :user_class, # what class to use as the user class.
127
+ :user_class, # what class to use as the user class. Set automatically when you call activate_sorcery! in the User class.
116
128
 
117
129
  :not_authenticated_action, # what controller action to call for non-authenticated users.
118
130
 
119
- :save_user_wanted_url, # when a non logged in user tries to enter a page that requires login, save the URL he wanted to reach,
131
+ :save_return_to_url, # when a non logged in user tries to enter a page that requires login, save the URL he wanted to reach,
120
132
  # and send him there after login.
121
133
 
122
134
  :login_sources,
@@ -138,7 +150,7 @@ module Sorcery
138
150
  :@before_logout => [],
139
151
  :@after_logout => [],
140
152
  :@after_config => [],
141
- :@save_user_wanted_url => true
153
+ :@save_return_to_url => true
142
154
  }
143
155
  end
144
156
 
@@ -1,6 +1,13 @@
1
1
  module Sorcery
2
2
  module Controller
3
3
  module Submodules
4
+ # This submodule keeps track of events such as login, logout, and last activity time, per user.
5
+ # It helps in estimating which users are active now in the site.
6
+ # This cannot be determined absolutely because a user might be reading a page without clicking anything for a while.
7
+
8
+ # This is the controller part of the submodule, which adds hooks to register user events,
9
+ # and methods to collect active users data for use in the app.
10
+ # see Socery::Model::Submodules::ActivityLogging for configuration options.
4
11
  module ActivityLogging
5
12
  def self.included(base)
6
13
  base.send(:include, InstanceMethods)
@@ -10,33 +17,39 @@ module Sorcery
10
17
  end
11
18
 
12
19
  module InstanceMethods
13
- def logged_in_users
14
- Config.user_class.logged_in_users
20
+ # Returns an array of the active users.
21
+ def current_users
22
+ Config.user_class.current_users
15
23
  # A possible patch here:
16
- # we'll add the logged_in_user to the users list if he's not in it (can happen when he was inactive for more than activity timeout):
24
+ # we'll add the current_user to the users list if he's not in it (can happen when he was inactive for more than activity timeout):
17
25
  #
18
- # users.unshift!(logged_in_user) if logged_in? && users.find {|u| u.id == logged_in_user.id}.nil?
26
+ # users.unshift!(current_user) if logged_in? && users.find {|u| u.id == current_user.id}.nil?
19
27
  #
20
28
  # disadvantages: can hurt performance.
21
29
  end
22
30
 
23
31
  protected
24
32
 
33
+ # registers last login time on every login.
34
+ # This runs as a hook just after a successful login.
25
35
  def register_login_time_to_db(user, credentials)
26
36
  user.send(:"#{user.sorcery_config.last_login_at_attribute_name}=", Time.now.utc.to_s(:db))
27
37
  user.save!(:validate => false)
28
38
  end
29
39
 
40
+ # registers last logout time on every logout.
41
+ # This runs as a hook just before a logout.
30
42
  def register_logout_time_to_db(user)
31
43
  user.send(:"#{user.sorcery_config.last_logout_at_attribute_name}=", Time.now.utc.to_s(:db))
32
44
  user.save!(:validate => false)
33
45
  end
34
46
 
35
- # we do not update activity on logout
47
+ # Updates last activity time on every request.
48
+ # The only exception is logout - we do not update activity on logout
36
49
  def register_last_activity_time_to_db
37
50
  return if !logged_in?
38
- logged_in_user.send(:"#{logged_in_user.sorcery_config.last_activity_at_attribute_name}=", Time.now.utc.to_s(:db))
39
- logged_in_user.save!(:validate => false)
51
+ current_user.send(:"#{current_user.sorcery_config.last_activity_at_attribute_name}=", Time.now.utc.to_s(:db))
52
+ current_user.save!(:validate => false)
40
53
  end
41
54
  end
42
55
  end
@@ -1,6 +1,9 @@
1
1
  module Sorcery
2
2
  module Controller
3
3
  module Submodules
4
+ # This module helps protect user accounts by locking them down after too many failed attemps to login were detected.
5
+ # This is the controller part of the submodule which takes care of updating the failed logins and resetting them.
6
+ # See Sorcery::Model::Submodules::BruteForceProtection for configuration options.
4
7
  module BruteForceProtection
5
8
  def self.included(base)
6
9
  base.send(:include, InstanceMethods)
@@ -13,13 +16,17 @@ module Sorcery
13
16
 
14
17
  protected
15
18
 
19
+ # Increments the failed logins counter on every failed login.
20
+ # Runs as a hook after a failed login.
16
21
  def update_failed_logins_count!(credentials)
17
- user = User.where("#{User.sorcery_config.username_attribute_name} = ?", credentials[0]).first
22
+ user = Config.user_class.where("#{Config.user_class.sorcery_config.username_attribute_name} = ?", credentials[0]).first
18
23
  user.register_failed_login! if user
19
24
  end
20
25
 
26
+ # Resets the failed logins counter.
27
+ # Runs as a hook after a successful login.
21
28
  def reset_failed_logins_count!(user, credentials)
22
- user.update_attributes!(User.sorcery_config.failed_logins_count_attribute_name => 0)
29
+ user.update_attributes!(Config.user_class.sorcery_config.failed_logins_count_attribute_name => 0)
23
30
  end
24
31
  end
25
32
  end