sorcery 0.4.1 → 0.5.2

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.
Files changed (142) hide show
  1. data/Gemfile +5 -2
  2. data/Gemfile.lock +12 -0
  3. data/README.rdoc +12 -7
  4. data/VERSION +1 -1
  5. data/lib/sorcery/controller/adapters/sinatra.rb +35 -28
  6. data/lib/sorcery/controller/submodules/brute_force_protection.rb +1 -1
  7. data/lib/sorcery/controller/submodules/http_basic_auth.rb +1 -1
  8. data/lib/sorcery/crypto_providers/bcrypt.rb +2 -4
  9. data/lib/sorcery/crypto_providers/common.rb +2 -2
  10. data/lib/sorcery/engine.rb +0 -11
  11. data/lib/sorcery/initializers/initializer.rb +5 -1
  12. data/lib/sorcery/model/adapters/active_record.rb +28 -0
  13. data/lib/sorcery/model/adapters/mongoid.rb +64 -0
  14. data/lib/sorcery/model/submodules/activity_logging.rb +12 -3
  15. data/lib/sorcery/model/submodules/brute_force_protection.rb +6 -1
  16. data/lib/sorcery/model/submodules/external.rb +1 -0
  17. data/lib/sorcery/model/submodules/remember_me.rb +15 -1
  18. data/lib/sorcery/model/submodules/reset_password.rb +14 -5
  19. data/lib/sorcery/model/submodules/user_activation.rb +11 -1
  20. data/lib/sorcery/model/temporary_token.rb +1 -1
  21. data/lib/sorcery/model.rb +37 -10
  22. data/lib/sorcery/sinatra.rb +0 -1
  23. data/lib/sorcery/test_helpers/internal/rails.rb +53 -0
  24. data/lib/sorcery/test_helpers/internal/sinatra.rb +74 -0
  25. data/lib/sorcery/test_helpers/internal/sinatra_modular.rb +74 -0
  26. data/lib/sorcery/test_helpers/internal.rb +56 -0
  27. data/lib/sorcery/test_helpers/rails.rb +5 -43
  28. data/lib/sorcery/test_helpers/sinatra.rb +62 -102
  29. data/lib/sorcery/test_helpers.rb +0 -47
  30. data/lib/sorcery.rb +27 -1
  31. data/sorcery.gemspec +162 -10
  32. data/spec/Gemfile +1 -1
  33. data/spec/Gemfile.lock +9 -4
  34. data/spec/rails3/Gemfile +1 -1
  35. data/spec/rails3/Gemfile.lock +6 -9
  36. data/spec/rails3/spec/controller_activity_logging_spec.rb +2 -4
  37. data/spec/rails3/spec/controller_oauth_spec.rb +3 -3
  38. data/spec/rails3/spec/controller_session_timeout_spec.rb +20 -19
  39. data/spec/rails3/spec/controller_spec.rb +6 -16
  40. data/spec/rails3/spec/spec_helper.rb +2 -2
  41. data/spec/rails3/spec/user_activation_spec.rb +2 -12
  42. data/spec/rails3/spec/user_brute_force_protection_spec.rb +2 -30
  43. data/spec/rails3/spec/user_remember_me_spec.rb +3 -11
  44. data/spec/rails3/spec/user_reset_password_spec.rb +15 -16
  45. data/spec/rails3/spec/user_spec.rb +18 -13
  46. data/spec/rails3_mongoid/.gitignore +4 -0
  47. data/spec/rails3_mongoid/.rspec +1 -0
  48. data/spec/rails3_mongoid/Gemfile +14 -0
  49. data/spec/rails3_mongoid/Gemfile.lock +143 -0
  50. data/spec/rails3_mongoid/Rakefile +11 -0
  51. data/spec/rails3_mongoid/app/controllers/application_controller.rb +108 -0
  52. data/spec/rails3_mongoid/app/helpers/application_helper.rb +2 -0
  53. data/spec/rails3_mongoid/app/mailers/sorcery_mailer.rb +25 -0
  54. data/spec/rails3_mongoid/app/models/authentication.rb +7 -0
  55. data/spec/rails3_mongoid/app/models/user.rb +5 -0
  56. data/spec/rails3_mongoid/app/views/layouts/application.html.erb +14 -0
  57. data/spec/rails3_mongoid/app/views/sorcery_mailer/activation_email.html.erb +17 -0
  58. data/spec/rails3_mongoid/app/views/sorcery_mailer/activation_email.text.erb +9 -0
  59. data/spec/rails3_mongoid/app/views/sorcery_mailer/activation_success_email.html.erb +17 -0
  60. data/spec/rails3_mongoid/app/views/sorcery_mailer/activation_success_email.text.erb +9 -0
  61. data/spec/rails3_mongoid/app/views/sorcery_mailer/reset_password_email.html.erb +16 -0
  62. data/spec/rails3_mongoid/app/views/sorcery_mailer/reset_password_email.text.erb +8 -0
  63. data/spec/rails3_mongoid/config/application.rb +51 -0
  64. data/spec/rails3_mongoid/config/boot.rb +13 -0
  65. data/spec/rails3_mongoid/config/environment.rb +5 -0
  66. data/spec/rails3_mongoid/config/environments/development.rb +26 -0
  67. data/spec/rails3_mongoid/config/environments/in_memory.rb +0 -0
  68. data/spec/rails3_mongoid/config/environments/production.rb +49 -0
  69. data/spec/rails3_mongoid/config/environments/test.rb +35 -0
  70. data/spec/rails3_mongoid/config/initializers/backtrace_silencers.rb +7 -0
  71. data/spec/rails3_mongoid/config/initializers/inflections.rb +10 -0
  72. data/spec/rails3_mongoid/config/initializers/mime_types.rb +5 -0
  73. data/spec/rails3_mongoid/config/initializers/secret_token.rb +7 -0
  74. data/spec/rails3_mongoid/config/initializers/session_store.rb +8 -0
  75. data/spec/rails3_mongoid/config/locales/en.yml +5 -0
  76. data/spec/rails3_mongoid/config/mongoid.yml +7 -0
  77. data/spec/rails3_mongoid/config/routes.rb +59 -0
  78. data/spec/rails3_mongoid/config.ru +4 -0
  79. data/spec/rails3_mongoid/db/schema.rb +23 -0
  80. data/spec/rails3_mongoid/db/seeds.rb +7 -0
  81. data/spec/rails3_mongoid/lib/tasks/.gitkeep +0 -0
  82. data/spec/rails3_mongoid/public/404.html +26 -0
  83. data/spec/rails3_mongoid/public/422.html +26 -0
  84. data/spec/rails3_mongoid/public/500.html +26 -0
  85. data/spec/rails3_mongoid/public/favicon.ico +0 -0
  86. data/spec/rails3_mongoid/public/images/rails.png +0 -0
  87. data/spec/rails3_mongoid/public/javascripts/application.js +2 -0
  88. data/spec/rails3_mongoid/public/javascripts/controls.js +965 -0
  89. data/spec/rails3_mongoid/public/javascripts/dragdrop.js +974 -0
  90. data/spec/rails3_mongoid/public/javascripts/effects.js +1123 -0
  91. data/spec/rails3_mongoid/public/javascripts/prototype.js +6001 -0
  92. data/spec/rails3_mongoid/public/javascripts/rails.js +175 -0
  93. data/spec/rails3_mongoid/public/robots.txt +5 -0
  94. data/spec/rails3_mongoid/public/stylesheets/.gitkeep +0 -0
  95. data/spec/rails3_mongoid/script/rails +6 -0
  96. data/spec/rails3_mongoid/spec/spec.opts +2 -0
  97. data/spec/rails3_mongoid/spec/spec_helper.orig.rb +27 -0
  98. data/spec/rails3_mongoid/spec/spec_helper.rb +55 -0
  99. data/spec/rails3_mongoid/spec/user_activation_spec.rb +178 -0
  100. data/spec/rails3_mongoid/spec/user_activity_logging_spec.rb +31 -0
  101. data/spec/rails3_mongoid/spec/user_brute_force_protection_spec.rb +41 -0
  102. data/spec/rails3_mongoid/spec/user_oauth_spec.rb +34 -0
  103. data/spec/rails3_mongoid/spec/user_remember_me_spec.rb +51 -0
  104. data/spec/rails3_mongoid/spec/user_reset_password_spec.rb +182 -0
  105. data/spec/rails3_mongoid/spec/user_spec.rb +319 -0
  106. data/spec/rails3_mongoid/vendor/plugins/.gitkeep +0 -0
  107. data/spec/sinatra/Gemfile +4 -1
  108. data/spec/sinatra/Gemfile.lock +22 -39
  109. data/spec/sinatra/Rakefile +1 -1
  110. data/spec/sinatra/filters.rb +20 -14
  111. data/spec/sinatra/modular.rb +157 -0
  112. data/spec/sinatra/spec/controller_session_timeout_spec.rb +23 -22
  113. data/spec/sinatra/spec/spec_helper.rb +2 -2
  114. data/spec/sinatra_modular/Gemfile +15 -0
  115. data/spec/sinatra_modular/Gemfile.lock +117 -0
  116. data/spec/sinatra_modular/Rakefile +11 -0
  117. data/spec/sinatra_modular/authentication.rb +3 -0
  118. data/spec/sinatra_modular/db/migrate/activation/20101224223622_add_activation_to_users.rb +17 -0
  119. data/spec/sinatra_modular/db/migrate/activity_logging/20101224223624_add_activity_logging_to_users.rb +17 -0
  120. data/spec/sinatra_modular/db/migrate/brute_force_protection/20101224223626_add_brute_force_protection_to_users.rb +11 -0
  121. data/spec/sinatra_modular/db/migrate/core/20101224223620_create_users.rb +16 -0
  122. data/spec/sinatra_modular/db/migrate/external/20101224223628_create_authentications.rb +14 -0
  123. data/spec/sinatra_modular/db/migrate/remember_me/20101224223623_add_remember_me_token_to_users.rb +15 -0
  124. data/spec/sinatra_modular/db/migrate/reset_password/20101224223622_add_reset_password_to_users.rb +13 -0
  125. data/spec/sinatra_modular/filters.rb +27 -0
  126. data/spec/sinatra_modular/modular.rb +157 -0
  127. data/spec/sinatra_modular/myapp.rb +133 -0
  128. data/spec/sinatra_modular/sorcery_mailer.rb +25 -0
  129. data/spec/sinatra_modular/spec_modular/controller_activity_logging_spec.rb +85 -0
  130. data/spec/sinatra_modular/spec_modular/controller_brute_force_protection_spec.rb +70 -0
  131. data/spec/sinatra_modular/spec_modular/controller_http_basic_auth_spec.rb +53 -0
  132. data/spec/sinatra_modular/spec_modular/controller_oauth2_spec.rb +120 -0
  133. data/spec/sinatra_modular/spec_modular/controller_oauth_spec.rb +121 -0
  134. data/spec/sinatra_modular/spec_modular/controller_remember_me_spec.rb +64 -0
  135. data/spec/sinatra_modular/spec_modular/controller_session_timeout_spec.rb +57 -0
  136. data/spec/sinatra_modular/spec_modular/controller_spec.rb +116 -0
  137. data/spec/sinatra_modular/spec_modular/spec.opts +2 -0
  138. data/spec/sinatra_modular/spec_modular/spec_helper.rb +51 -0
  139. data/spec/sinatra_modular/user.rb +6 -0
  140. data/spec/sinatra_modular/views/test_login.erb +4 -0
  141. metadata +205 -37
  142. data/spec/untitled folder +0 -18
data/Gemfile CHANGED
@@ -2,13 +2,16 @@ 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
- gem "rails", ">= 3.0.0"
6
- gem 'json', ">= 1.5.1"
7
5
  gem 'oauth', ">= 0.4.4"
8
6
  gem 'oauth2', ">= 0.1.1"
7
+
9
8
  # Add dependencies to develop your gem here.
10
9
  # Include everything needed to run rake, tests, features, etc.
11
10
  group :development do
11
+ gem "rails", ">= 3.0.0"
12
+ gem 'json', ">= 1.5.1"
13
+ gem "mongoid", "~> 2.0"
14
+ gem "bson_ext", "~> 1.3"
12
15
  gem "rspec", "~> 2.5.0"
13
16
  gem 'rspec-rails', "~> 2.5.0"
14
17
  gem 'ruby-debug19'
data/Gemfile.lock CHANGED
@@ -31,6 +31,8 @@ GEM
31
31
  addressable (2.2.4)
32
32
  archive-tar-minitar (0.5.2)
33
33
  arel (2.0.6)
34
+ bson (1.3.0)
35
+ bson_ext (1.3.0)
34
36
  builder (2.1.2)
35
37
  columnize (0.3.2)
36
38
  diff-lcs (1.1.2)
@@ -55,6 +57,13 @@ GEM
55
57
  mime-types (~> 1.16)
56
58
  treetop (~> 1.4.8)
57
59
  mime-types (1.16)
60
+ mongo (1.3.0)
61
+ bson (>= 1.3.0)
62
+ mongoid (2.0.1)
63
+ activemodel (~> 3.0)
64
+ mongo (~> 1.3)
65
+ tzinfo (~> 0.3.22)
66
+ will_paginate (~> 3.0.pre)
58
67
  multi_json (0.0.5)
59
68
  multipart-post (1.1.0)
60
69
  oauth (0.4.4)
@@ -113,15 +122,18 @@ GEM
113
122
  treetop (1.4.9)
114
123
  polyglot (>= 0.3.1)
115
124
  tzinfo (0.3.23)
125
+ will_paginate (3.0.pre2)
116
126
  yard (0.6.4)
117
127
 
118
128
  PLATFORMS
119
129
  ruby
120
130
 
121
131
  DEPENDENCIES
132
+ bson_ext (~> 1.3)
122
133
  bundler (~> 1.0.0)
123
134
  jeweler (~> 1.5.2)
124
135
  json (>= 1.5.1)
136
+ mongoid (~> 2.0)
125
137
  oauth (>= 0.4.4)
126
138
  oauth2 (>= 0.1.1)
127
139
  rails (>= 3.0.0)
data/README.rdoc CHANGED
@@ -1,5 +1,6 @@
1
1
  = sorcery
2
2
  Magical Authentication for Rails 3 and Sinatra.
3
+ Supports ActiveRecord and Mongoid.
3
4
 
4
5
  Inspired by restful_authentication, Authlogic and Devise.
5
6
  Crypto code taken almost unchanged from Authlogic.
@@ -15,7 +16,7 @@ It was built with a few goals in mind:
15
16
  * Less is more - less than 20 public methods to remember for the entire feature-set make the lib easy to 'get'.
16
17
  * No built-in or generated code - use the library's methods inside *your own* MVC structures, and don't fight to fix someone else's.
17
18
  * Magic yes, Voodoo no - the lib should be easy to hack for most developers.
18
- * Configuration over Confusion - Simple & short configuration as possible, not drowning in syntactic sugar.
19
+ * Configuration over Confusion - Centralized (1 file), Simple & short configuration as possible, not drowning in syntactic sugar.
19
20
  * Keep MVC cleanly separated - DB is for models, sessions are for controllers. Models stay unaware of sessions.
20
21
 
21
22
  Hopefully, I've achieved this. If not, let me know.
@@ -28,7 +29,7 @@ Example Rails 3 app using sorcery: https://github.com/NoamB/sorcery-example-app
28
29
 
29
30
  Example Sinatra app using sorcery: https://github.com/NoamB/sorcery-example-app-sinatra
30
31
 
31
- Documentation: http://rubydoc.info/gems/sorcery/0.4.1/frames
32
+ Documentation: http://rubydoc.info/gems/sorcery/0.5.2/frames
32
33
 
33
34
  Check out the tutorials in the github wiki!
34
35
 
@@ -66,7 +67,7 @@ Below is a summary of the library methods. Most method names are self explaining
66
67
  # reset password
67
68
  User.load_from_reset_password_token(token)
68
69
  @user.deliver_reset_password_instructions!
69
- @user.reset_password!(params)
70
+ @user.change_password!(new_password)
70
71
 
71
72
  # user activation
72
73
  User.load_from_activation_token(token)
@@ -193,19 +194,23 @@ External (see lib/sorcery/controller/submodules/external.rb):
193
194
  == Next Planned Features:
194
195
 
195
196
 
196
- I've got many plans which include (by priority):
197
+ I've got some thoughts which include (unordered):
198
+ * Passing a block to encrypt, allowing the developer to define his own mix of salting and encrypting
197
199
  * Forgot username, maybe as part of the reset_password module
198
200
  * Scoping logins (to a subdomain or another arbitrary field)
199
- * Mongoid support
201
+ * Allowing storing the salt and crypted password in the same DB field for extra security
200
202
  * Other reset password strategies (security questions?)
201
203
  * Other brute force protection strategies (captcha)
202
- * Have an idea? Let me know, and it might get into the gem!
204
+
205
+
206
+ Have an idea? Let me know, and it might get into the gem!
207
+
203
208
 
204
209
  Other stuff:
205
210
  * Improve specs speed
206
211
  * Provide an easy way to run specs after install
207
212
  * Improve documentation
208
- * Tty to reduce the number of library methods, and find better names to some
213
+ * Try to reduce the number of library methods, and find better names to some
209
214
 
210
215
 
211
216
  == Backward compatibility
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.4.1
1
+ 0.5.2
@@ -16,7 +16,7 @@ module Sorcery
16
16
  process_route(*arguments) { instance_eval(&block) }
17
17
  end
18
18
  end
19
-
19
+
20
20
  def after_filter(filter)
21
21
  after do
22
22
  send(filter)
@@ -24,66 +24,73 @@ module Sorcery
24
24
  end
25
25
  end
26
26
  end
27
-
27
+
28
28
  ::Sinatra::Request.class_eval do
29
29
  def authorization
30
- env['HTTP_AUTHORIZATION'] ||
31
- env['X-HTTP_AUTHORIZATION'] ||
32
- env['X_HTTP_AUTHORIZATION'] ||
33
- env['REDIRECT_X_HTTP_AUTHORIZATION'] || nil
30
+ env['HTTP_AUTHORIZATION'] ||
31
+ env['X-HTTP_AUTHORIZATION'] ||
32
+ env['X_HTTP_AUTHORIZATION'] ||
33
+ env['REDIRECT_X_HTTP_AUTHORIZATION'] || nil
34
34
  end
35
35
  end
36
-
36
+
37
+ base.send(:include, SorceryHelpers)
37
38
  base.send(:include, InstanceMethods)
38
39
  base.extend(ClassMethods)
39
40
  end
40
-
41
+
42
+ module SorceryHelpers
43
+
44
+ def request_http_basic_authentication(realm)
45
+ response.header['WWW-Authenticate'] = %(Basic realm="#{realm}")
46
+ response.status = 401
47
+ end
48
+
49
+ def authenticate_with_http_basic(&blk)
50
+ @auth ||= Rack::Auth::Basic::Request.new(request.env)
51
+ yield @auth.credentials if (@auth.provided? && @auth.basic? && @auth.credentials)
52
+ end
53
+
54
+ end
55
+
41
56
  module InstanceMethods
42
57
  def reset_session
43
58
  session.clear
44
59
  end
45
-
60
+
46
61
  def redirect_to(*args)
47
62
  args.pop if args.last.is_a?(Hash)
48
63
  redirect(*args)
49
64
  end
50
-
65
+
51
66
  def root_path
52
67
  '/'
53
68
  end
54
-
55
- helpers do
56
- def request_http_basic_authentication(realm)
57
- response.header['WWW-Authenticate'] = %(Basic realm="#{realm}")
58
- response.status = 401
59
- end
60
-
61
- def authenticate_with_http_basic(&blk)
62
- @auth ||= Rack::Auth::Basic::Request.new(request.env)
63
- yield @auth.credentials if ( @auth.provided? && @auth.basic? && @auth.credentials )
64
- end
69
+
70
+ ::Sinatra.helpers do
71
+ include SorceryHelpers
65
72
  end
66
-
73
+
67
74
  def cookies
68
- @cookie_proxy ||= CookieProxy.new(request,response)
75
+ @cookie_proxy ||= CookieProxy.new(request, response)
69
76
  end
70
77
  end
71
-
78
+
72
79
  class CookieProxy
73
- def initialize(request,response)
80
+ def initialize(request, response)
74
81
  @request = request
75
82
  @response = response
76
83
  end
77
-
84
+
78
85
  def [](key)
79
86
  @request.cookies[key.to_s]
80
87
  end
81
-
88
+
82
89
  def []=(key, value)
83
90
  @response.set_cookie(key, value)
84
91
  end
85
92
  end
86
-
93
+
87
94
  module ClassMethods
88
95
  def prepend_before_filter(filter)
89
96
  prepend_filter(:before) do
@@ -19,7 +19,7 @@ module Sorcery
19
19
  # Increments the failed logins counter on every failed login.
20
20
  # Runs as a hook after a failed login.
21
21
  def update_failed_logins_count!(credentials)
22
- user = Config.user_class.where("#{Config.user_class.sorcery_config.username_attribute_name} = ?", credentials[0]).first
22
+ user = Config.user_class.find_by_credentials(credentials)
23
23
  user.register_failed_login! if user
24
24
  end
25
25
 
@@ -21,7 +21,7 @@ module Sorcery
21
21
  end
22
22
 
23
23
  module InstanceMethods
24
-
24
+
25
25
  protected
26
26
 
27
27
  # to be used as a before_filter.
@@ -30,11 +30,9 @@ module Sorcery
30
30
  #
31
31
  # gem install bcrypt-ruby
32
32
  #
33
- # Tell activate_sorcery! to use it:
33
+ # Update your initializer to use it:
34
34
  #
35
- # activate_sorcery! do |c|
36
- # c.encryption_algorithm = :bcrypt
37
- # end
35
+ # config.encryption_algorithm = :bcrypt
38
36
  #
39
37
  # You are good to go!
40
38
  class BCrypt
@@ -13,14 +13,14 @@ module Sorcery
13
13
  attr_writer :stretches
14
14
 
15
15
  def encrypt(*tokens)
16
- digest = tokens.flatten.join(join_token)
16
+ digest = tokens.flatten.compact.join(join_token)
17
17
  stretches.times { digest = secure_digest(digest) }
18
18
  digest
19
19
  end
20
20
 
21
21
  # Does the crypted password match the tokens? Uses the same tokens that were used to encrypt.
22
22
  def matches?(crypted, *tokens)
23
- encrypt(*tokens) == crypted
23
+ encrypt(*tokens.compact) == crypted
24
24
  end
25
25
 
26
26
  def reset!
@@ -7,22 +7,11 @@ module Sorcery
7
7
  class Engine < Rails::Engine
8
8
  config.sorcery = ::Sorcery::Controller::Config
9
9
 
10
- initializer "extend Model with sorcery" do |app|
11
- ActiveRecord::Base.send(:include, Sorcery::Model) if defined?(ActiveRecord)
12
- end
13
-
14
10
  initializer "extend Controller with sorcery" do |app|
15
11
  ActionController::Base.send(:include, Sorcery::Controller)
16
12
  ActionController::Base.helper_method :current_user
17
13
  end
18
14
 
19
- initializer "attempt to preload user model" do |app|
20
- begin
21
- require Rails.root + "app/models/user.rb"
22
- rescue LoadError
23
- end
24
- end
25
-
26
15
  rake_tasks do
27
16
  load "sorcery/railties/tasks.rake"
28
17
  end
@@ -9,7 +9,7 @@ Rails.application.config.sorcery.configure do |config|
9
9
  # config.not_authenticated_action = :not_authenticated # what controller action to call for non-authenticated users. You can also override 'not_authenticated' instead.
10
10
  # config.save_return_to_url = true # when a non logged in user tries to enter a page that requires login, save the URL he wanted to reach,
11
11
  # and send him there after login, using 'redirect_back_or_to'.
12
-
12
+
13
13
  # -- session timeout --
14
14
  # config.session_timeout = 3600 # how long in seconds to keep the session alive.
15
15
  # config.session_timeout_from_last_action = false # use the last action as the beginning of session timeout.
@@ -44,6 +44,7 @@ Rails.application.config.sorcery.configure do |config|
44
44
  # user.encryption_key = nil # encryption key used to encrypt reversible encryptions such as AES256.
45
45
  # user.custom_encryption_provider = nil # use an external encryption class.
46
46
  # user.encryption_algorithm = :bcrypt # encryption algorithm name. See 'encryption_algorithm=' for available options.
47
+ # user.subclasses_inherit_config = false # make this configuration inheritable for subclasses. Useful for ActiveRecord's STI.
47
48
 
48
49
  # -- user_activation --
49
50
  # user.activation_state_attribute_name = :activation_state # the attribute name to hold activation state (active/pending).
@@ -82,4 +83,7 @@ Rails.application.config.sorcery.configure do |config|
82
83
  # user.provider_attribute_name = :provider # provider's identifier in authentications class.
83
84
  # user.provider_uid_attribute_name = :uid # user's external unique identifier in authentications class.
84
85
  end
86
+
87
+ # This line must come after the 'user config' block.
88
+ config.user_class_name = User # define which model authenticates with sorcery.
85
89
  end
@@ -0,0 +1,28 @@
1
+ module Sorcery
2
+ module Model
3
+ module Adapters
4
+ module ActiveRecord
5
+ def self.included(klass)
6
+ klass.extend ClassMethods
7
+ end
8
+
9
+ module ClassMethods
10
+ def find_by_credentials(credentials)
11
+ where("#{@sorcery_config.username_attribute_name} = ?", credentials[0]).first
12
+ end
13
+
14
+ def find_by_token(token_attr_name, token)
15
+ where("#{token_attr_name} = ?", token).first
16
+ end
17
+
18
+ def get_current_users
19
+ config = sorcery_config
20
+ where("#{config.last_activity_at_attribute_name} IS NOT NULL") \
21
+ .where("#{config.last_logout_at_attribute_name} IS NULL OR #{config.last_activity_at_attribute_name} > #{config.last_logout_at_attribute_name}") \
22
+ .where("#{config.last_activity_at_attribute_name} > ? ", config.activity_timeout.seconds.ago.utc.to_s(:db))
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,64 @@
1
+ module Sorcery
2
+ module Model
3
+ module Adapters
4
+ module Mongoid
5
+ def self.included(klass)
6
+ klass.extend ClassMethods
7
+ klass.send(:include, InstanceMethods)
8
+ end
9
+
10
+ module InstanceMethods
11
+ def increment(attr)
12
+ self.inc(attr,1)
13
+ end
14
+ end
15
+
16
+ module ClassMethods
17
+ def find_by_credentials(credentials)
18
+ where(sorcery_config.username_attribute_name => credentials[0]).first
19
+ end
20
+
21
+ def find_by_provider_and_uid(provider, uid)
22
+ user_klass = ::Sorcery::Controller::Config.user_class
23
+ where(user_klass.sorcery_config.provider_attribute_name => provider, user_klass.sorcery_config.provider_uid_attribute_name => uid).first
24
+ end
25
+
26
+ def find_by_id(id)
27
+ find(id)
28
+ end
29
+
30
+ def find_by_activation_token(token)
31
+ where(sorcery_config.activation_token_attribute_name => token).first
32
+ end
33
+
34
+ def find_by_remember_me_token(token)
35
+ where(sorcery_config.remember_me_token_attribute_name => token).first
36
+ end
37
+
38
+ def find_by_username(username)
39
+ where(sorcery_config.username_attribute_name => username).first
40
+ end
41
+
42
+ def transaction(&blk)
43
+ tap(&blk)
44
+ end
45
+
46
+ def find_by_token(token_attr_name, token)
47
+ where(token_attr_name => token).first
48
+ end
49
+
50
+ def find_by_email(email)
51
+ where(sorcery_config.email_attribute_name => email).first
52
+ end
53
+
54
+ def get_current_users
55
+ config = sorcery_config
56
+ where(config.last_activity_at_attribute_name.ne => nil) \
57
+ .any_of({config.last_logout_at_attribute_name => nil},{config.last_activity_at_attribute_name.gt => config.last_logout_at_attribute_name}) \
58
+ .and(config.last_activity_at_attribute_name.gt => config.activity_timeout.seconds.ago.utc.to_s(:db)).order_by([:_id,:asc])
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
@@ -9,6 +9,7 @@ module Sorcery
9
9
  module ActivityLogging
10
10
  def self.included(base)
11
11
  base.extend(ClassMethods)
12
+
12
13
  base.sorcery_config.class_eval do
13
14
  attr_accessor :last_login_at_attribute_name, # last login attribute name.
14
15
  :last_logout_at_attribute_name, # last logout attribute name.
@@ -23,15 +24,23 @@ module Sorcery
23
24
  :@activity_timeout => 10 * 60)
24
25
  reset!
25
26
  end
27
+
28
+ base.sorcery_config.after_config << :define_activity_logging_mongoid_fields if defined?(Mongoid) and base.ancestors.include?(Mongoid::Document)
26
29
  end
27
30
 
28
31
  module ClassMethods
29
32
  # get all users with last_activity within timeout
30
33
  def current_users
31
34
  config = sorcery_config
32
- where("#{config.last_activity_at_attribute_name} IS NOT NULL") \
33
- .where("#{config.last_logout_at_attribute_name} IS NULL OR #{config.last_activity_at_attribute_name} > #{config.last_logout_at_attribute_name}") \
34
- .where("#{config.last_activity_at_attribute_name} > ? ", config.activity_timeout.seconds.ago.utc.to_s(:db))
35
+ get_current_users
36
+ end
37
+
38
+ protected
39
+
40
+ def define_activity_logging_mongoid_fields
41
+ field sorcery_config.last_login_at_attribute_name, type: DateTime
42
+ field sorcery_config.last_logout_at_attribute_name, type: DateTime
43
+ field sorcery_config.last_activity_at_attribute_name, type: DateTime
35
44
  end
36
45
  end
37
46
  end
@@ -21,13 +21,18 @@ module Sorcery
21
21
  end
22
22
 
23
23
  base.sorcery_config.before_authenticate << :prevent_locked_user_login
24
+ base.sorcery_config.after_config << :define_brute_force_protection_mongoid_fields if defined?(Mongoid) and base.ancestors.include?(Mongoid::Document)
24
25
  base.extend(ClassMethods)
25
26
  base.send(:include, InstanceMethods)
26
27
  end
27
28
 
28
29
  module ClassMethods
29
30
  protected
30
-
31
+
32
+ def define_brute_force_protection_mongoid_fields
33
+ field sorcery_config.failed_logins_count_attribute_name, type: Integer
34
+ field sorcery_config.lock_expires_at_attribute_name, type: DateTime
35
+ end
31
36
  end
32
37
 
33
38
  module InstanceMethods
@@ -32,6 +32,7 @@ module Sorcery
32
32
 
33
33
  base.send(:include, InstanceMethods)
34
34
  base.extend(ClassMethods)
35
+
35
36
  end
36
37
 
37
38
  module ClassMethods
@@ -21,8 +21,22 @@ module Sorcery
21
21
  end
22
22
 
23
23
  base.send(:include, InstanceMethods)
24
+
25
+ base.sorcery_config.after_config << :define_remember_me_mongoid_fields if defined?(Mongoid) and base.ancestors.include?(Mongoid::Document)
26
+
27
+ base.extend(ClassMethods)
28
+ end
29
+
30
+ module ClassMethods
31
+ protected
32
+
33
+ def define_remember_me_mongoid_fields
34
+ field sorcery_config.remember_me_token_attribute_name, type: String
35
+ field sorcery_config.remember_me_token_expires_at_attribute_name, type: DateTime
36
+ end
37
+
24
38
  end
25
-
39
+
26
40
  module InstanceMethods
27
41
  # You shouldn't really use this one yourself - it's called by the controller's 'remember_me!' method.
28
42
  def remember_me!
@@ -32,12 +32,15 @@ module Sorcery
32
32
 
33
33
  reset!
34
34
  end
35
-
36
- base.sorcery_config.after_config << :validate_mailer_defined
37
-
35
+
38
36
  base.extend(ClassMethods)
37
+
38
+ base.sorcery_config.after_config << :validate_mailer_defined
39
+ base.sorcery_config.after_config << :define_reset_password_mongoid_fields if defined?(Mongoid) and base.ancestors.include?(Mongoid::Document)
40
+
39
41
  base.send(:include, TemporaryToken)
40
42
  base.send(:include, InstanceMethods)
43
+
41
44
  end
42
45
 
43
46
  module ClassMethods
@@ -57,6 +60,11 @@ module Sorcery
57
60
  raise ArgumentError, msg if @sorcery_config.reset_password_mailer == nil
58
61
  end
59
62
 
63
+ def define_reset_password_mongoid_fields
64
+ field sorcery_config.reset_password_token_attribute_name, type: String
65
+ field sorcery_config.reset_password_token_expires_at_attribute_name, type: DateTime
66
+ field sorcery_config.reset_password_email_sent_at_attribute_name, type: DateTime
67
+ end
60
68
  end
61
69
 
62
70
  module InstanceMethods
@@ -75,9 +83,10 @@ module Sorcery
75
83
  end
76
84
 
77
85
  # Clears token and tries to update the new password for the user.
78
- def reset_password!(params)
86
+ def change_password!(new_password)
79
87
  clear_reset_password_token
80
- update_attributes(params)
88
+ self.send(:"#{sorcery_config.password_attribute_name}=", new_password)
89
+ save
81
90
  end
82
91
 
83
92
  protected
@@ -38,12 +38,14 @@ module Sorcery
38
38
  end
39
39
 
40
40
  base.sorcery_config.after_config << :validate_mailer_defined
41
-
41
+ base.sorcery_config.after_config << :define_user_activation_mongoid_fields if defined?(Mongoid) and base.ancestors.include?(Mongoid::Document)
42
42
  base.sorcery_config.before_authenticate << :prevent_non_active_login
43
43
 
44
44
  base.extend(ClassMethods)
45
45
  base.send(:include, TemporaryToken)
46
46
  base.send(:include, InstanceMethods)
47
+
48
+
47
49
  end
48
50
 
49
51
  module ClassMethods
@@ -62,6 +64,14 @@ module Sorcery
62
64
  msg = "To use user_activation submodule, you must define a mailer (config.user_activation_mailer = YourMailerClass)."
63
65
  raise ArgumentError, msg if @sorcery_config.user_activation_mailer == nil
64
66
  end
67
+
68
+ def define_user_activation_mongoid_fields
69
+ self.class_eval do
70
+ field sorcery_config.activation_state_attribute_name, type: String
71
+ field sorcery_config.activation_token_attribute_name, type: String
72
+ field sorcery_config.activation_token_expires_at_attribute_name, type: DateTime
73
+ end
74
+ end
65
75
  end
66
76
 
67
77
  module InstanceMethods
@@ -10,7 +10,7 @@ module Sorcery
10
10
  module ClassMethods
11
11
  def load_from_token(token, token_attr_name, token_expiration_date_attr)
12
12
  return nil if token.blank?
13
- user = where("#{token_attr_name} = ?", token).first
13
+ user = find_by_token(token_attr_name,token)
14
14
  if !user.blank? && !user.send(token_expiration_date_attr).nil?
15
15
  return Time.now.utc < user.send(token_expiration_date_attr) ? user : nil
16
16
  end