devise-security 0.15.0 → 0.16.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +27 -19
  3. data/app/controllers/devise/password_expired_controller.rb +1 -5
  4. data/config/locales/by.yml +1 -0
  5. data/config/locales/cs.yml +1 -0
  6. data/config/locales/de.yml +1 -0
  7. data/config/locales/en.yml +1 -0
  8. data/config/locales/es.yml +1 -0
  9. data/config/locales/fa.yml +1 -0
  10. data/config/locales/fr.yml +1 -0
  11. data/config/locales/hi.yml +21 -20
  12. data/config/locales/it.yml +1 -0
  13. data/config/locales/ja.yml +1 -0
  14. data/config/locales/nl.yml +1 -0
  15. data/config/locales/pt.yml +1 -0
  16. data/config/locales/ru.yml +1 -0
  17. data/config/locales/tr.yml +1 -0
  18. data/config/locales/uk.yml +1 -0
  19. data/config/locales/zh_CN.yml +1 -0
  20. data/config/locales/zh_TW.yml +1 -0
  21. data/lib/devise-security.rb +6 -3
  22. data/lib/devise-security/controllers/helpers.rb +2 -2
  23. data/lib/devise-security/hooks/session_limitable.rb +10 -6
  24. data/lib/devise-security/models/secure_validatable.rb +15 -1
  25. data/lib/devise-security/version.rb +1 -1
  26. data/lib/generators/devise_security/install_generator.rb +3 -3
  27. data/lib/generators/templates/{devise-security.rb → devise_security.rb} +3 -0
  28. data/test/controllers/test_password_expired_controller.rb +67 -98
  29. data/test/controllers/test_security_question_controller.rb +16 -40
  30. data/test/dummy/config/environments/test.rb +3 -13
  31. data/test/dummy/config/initializers/migration_class.rb +1 -8
  32. data/test/dummy/config/mongoid.yml +1 -1
  33. data/test/dummy/log/development.log +883 -0
  34. data/test/dummy/log/test.log +19890 -0
  35. data/test/integration/test_password_expirable_workflow.rb +0 -4
  36. data/test/orm/mongoid.rb +2 -1
  37. data/test/support/integration_helpers.rb +14 -32
  38. data/test/support/mongoid.yml +1 -1
  39. data/test/test_helper.rb +4 -4
  40. data/test/test_install_generator.rb +1 -1
  41. data/test/test_secure_validatable.rb +76 -0
  42. data/test/tmp/config/initializers/devise-security.rb +3 -0
  43. data/test/tmp/config/locales/devise.security_extension.by.yml +49 -0
  44. data/test/tmp/config/locales/devise.security_extension.cs.yml +41 -0
  45. data/test/tmp/config/locales/devise.security_extension.de.yml +1 -0
  46. data/test/tmp/config/locales/devise.security_extension.en.yml +1 -0
  47. data/test/tmp/config/locales/devise.security_extension.es.yml +10 -9
  48. data/test/tmp/config/locales/devise.security_extension.fa.yml +1 -0
  49. data/test/tmp/config/locales/devise.security_extension.fr.yml +1 -0
  50. data/test/tmp/config/locales/devise.security_extension.hi.yml +42 -0
  51. data/test/tmp/config/locales/devise.security_extension.it.yml +1 -0
  52. data/test/tmp/config/locales/devise.security_extension.ja.yml +1 -0
  53. data/test/tmp/config/locales/devise.security_extension.nl.yml +1 -0
  54. data/test/tmp/config/locales/devise.security_extension.pt.yml +1 -0
  55. data/test/tmp/config/locales/devise.security_extension.ru.yml +1 -0
  56. data/test/tmp/config/locales/devise.security_extension.tr.yml +1 -0
  57. data/test/tmp/config/locales/devise.security_extension.uk.yml +1 -0
  58. data/test/tmp/config/locales/devise.security_extension.zh_CN.yml +1 -0
  59. data/test/tmp/config/locales/devise.security_extension.zh_TW.yml +41 -0
  60. metadata +19 -40
  61. data/lib/devise-security/orm/active_record.rb +0 -20
  62. data/lib/devise-security/schema.rb +0 -66
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9172082dca0b721f493e44d5183a0e660c9dd67d3893bd86b03638b039c34935
4
- data.tar.gz: 80b4649313476c6ae926fabf1db2a58abd9c8796fe639927743ab8ba8f53be97
3
+ metadata.gz: 1d065158ce85c823918ca0fb7ad40382ca9957f7c5e0847e1fec86e1eaed0ffb
4
+ data.tar.gz: fa07606b583076da6b68ceeddf70f74f80c05f3adf752a057b8f935c9af68fb6
5
5
  SHA512:
6
- metadata.gz: 10f1e3243f77003658cdc377d13fe56d92fe6cf7713f3a658d01ea61ffc18788ce6508f3d894c664edf6847242e863174696f3ef810527d4d4889212a258baab
7
- data.tar.gz: dc5802511d5c406923a541ea1d10f7d3ffff715b9278adc407a1ee87c18659eccf6b1ea9328b06b08cd0f30ae6b523236ff27164ae7c44f5608b7d5c31706fbb
6
+ metadata.gz: 7f18a70374b20c80908006811184fc4757c4f678e11ff226d60b78ff0a3c1cf2612382185911b23692c6c7ed1553914f1361ab1243948ad1e1ff3ac91fdb5ab7
7
+ data.tar.gz: 68e392e9f0049659ad62977a0bb31910d4942b26ab24fab11b28e1e875286f2b48e9da20dd952f94bc4ac8350b1cd5199d9984e431d4664c865544a095b274b8
data/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
  [![Coverage Status](https://coveralls.io/repos/github/devise-security/devise-security/badge.svg?branch=master)](https://coveralls.io/github/devise-security/devise-security?branch=master)
5
5
  [![Maintainability](https://api.codeclimate.com/v1/badges/ace7cd003a0db8bffa5a/maintainability)](https://codeclimate.com/github/devise-security/devise-security/maintainability)
6
6
 
7
- A [Devise](https://github.com/plataformatec/devise) extension to add additional
7
+ A [Devise](https://github.com/heartcombo/devise) extension to add additional
8
8
  security features required by modern web applications. Forked from
9
9
  [Devise Security Extension](https://github.com/phatworx/devise_security_extension)
10
10
 
@@ -37,9 +37,9 @@ automated mass creation and brute forcing of accounts harder)
37
37
 
38
38
  ## Getting started
39
39
 
40
- Devise Security works with Devise on Rails 4.2 onwards. You can add it to your
40
+ Devise Security works with Devise on Rails >= 5.0. You can add it to your
41
41
  Gemfile after you successfully set up Devise (see
42
- [Devise documentation](https://github.com/plataformatec/devise)) with:
42
+ [Devise documentation](https://github.com/heartcombo/devise)) with:
43
43
 
44
44
  ```ruby
45
45
  gem 'devise-security'
@@ -54,7 +54,7 @@ rails generate devise_security:install
54
54
  ```
55
55
 
56
56
  The generator adds optional configurations to
57
- `config/initializers/devise-security.rb`. Enable the modules you wish to use in
57
+ `config/initializers/devise_security.rb`. Enable the modules you wish to use in
58
58
  the initializer you are ready to add Devise Security modules on top of Devise
59
59
  modules to any of your Devise models:
60
60
 
@@ -124,6 +124,9 @@ Devise.setup do |config|
124
124
  # ==> Configuration for :expirable
125
125
  # Time period for account expiry from last_activity_at
126
126
  # config.expire_after = 90.days
127
+
128
+ # Allow passwords to be equal to email (false, true)
129
+ # config.allow_passwords_equal_to_email = false
127
130
  end
128
131
  ```
129
132
 
@@ -187,10 +190,10 @@ documentation there.
187
190
  4. Add the captcha in the generated devise views for each controller you have
188
191
  activated.
189
192
 
190
- ```erb
191
- <p><%= captcha_tag %></p>
192
- <p><%= text_field_tag :captcha %></p>
193
- ```
193
+ ```erb
194
+ <p><%= captcha_tag %></p>
195
+ <p><%= text_field_tag :captcha %></p>
196
+ ```
194
197
 
195
198
  ## Schema
196
199
 
@@ -231,6 +234,20 @@ create_table :the_resources do |t|
231
234
  end
232
235
  ```
233
236
 
237
+ #### Bypassing session limitable
238
+
239
+ Sometimes it's useful to impersonate a user without authentication (e.g.
240
+ [administrator impersonating a user](https://github.com/heartcombo/devise/wiki/How-To:-Sign-in-as-another-user-if-you-are-an-admin)),
241
+ in this case the `session_limitable` strategy will log out the user, and if the
242
+ user logs in while the administrator is still logged in, the administrator will
243
+ be logged out.
244
+
245
+ For such cases the following can be used:
246
+
247
+ ```ruby
248
+ sign_in(User.find(params[:id]), scope: :user, skip_session_limitable: true)
249
+ ```
250
+
234
251
  ### Expirable
235
252
 
236
253
  ```ruby
@@ -303,8 +320,8 @@ end
303
320
 
304
321
  ## Requirements
305
322
 
306
- - Devise (<https://github.com/plataformatec/devise>)
307
- - Rails 4.2 onwards (<http://github.com/rails/rails>)
323
+ - Devise (<https://github.com/heartcombo/devise>)
324
+ - Rails 5.0 onwards (<http://github.com/rails/rails>)
308
325
  - recommendations:
309
326
  - `autocomplete-off` (<http://github.com/phatworx/autocomplete-off>)
310
327
  - `easy_captcha` (<http://github.com/phatworx/easy_captcha>)
@@ -356,13 +373,6 @@ See also
356
373
  Standard tests can be invoked using `rake`. To run the tests against the
357
374
  `mongoid` ORM, use `DEVISE_ORM=mongoid rake` while `mongodb` is running.
358
375
 
359
- To locally simulate what travis-ci will run when you push code use:
360
-
361
- ```bash
362
- gem install bundler -v '1.17.3'
363
- BUNDLER_VERSION=1.17.3 wwtd
364
- ```
365
-
366
376
  ## Maintenance Policy
367
377
 
368
378
  We are committed to maintain support for `devise-security` for all normal or
@@ -371,8 +381,6 @@ security maintenance versions of the Ruby language
371
381
  Ruby on Rails framework
372
382
  [as per their maintenance policy](https://rubyonrails.org/maintenance/).
373
383
 
374
- Support for Rails 4.2 will be dropped in version 0.16.0.
375
-
376
384
  In order to avoid introducing bugs caused by backwardly incompatible Ruby
377
385
  language features, it is highly recommended that all development work be done
378
386
  using the oldest supported ruby version. The contents of the `.ruby-version`
@@ -41,11 +41,7 @@ class Devise::PasswordExpiredController < DeviseController
41
41
  def resource_params
42
42
  permitted_params = [:current_password, :password, :password_confirmation]
43
43
 
44
- if params.respond_to?(:permit)
45
- params.require(resource_name).permit(*permitted_params)
46
- else
47
- params[scope].slice(*permitted_params)
48
- end
44
+ params.require(resource_name).permit(*permitted_params)
49
45
  end
50
46
 
51
47
  def scope
@@ -3,6 +3,7 @@ by:
3
3
  messages:
4
4
  taken_in_past: 'ужо раней выкарыстоўваўся.'
5
5
  equal_to_current_password: 'павінен адрознівацца ад сучаснага пароля.'
6
+ equal_to_email: 'павінна адрознівацца ад электроннай пошты.'
6
7
  password_complexity:
7
8
  digit:
8
9
  one: 'павінен утрымліваць хоць адну лічбу'
@@ -3,6 +3,7 @@ cs:
3
3
  messages:
4
4
  taken_in_past: bylo již použito v minulosti.
5
5
  equal_to_current_password: se musí lišit od aktuálního hesla.
6
+ equal_to_email: musí být jiný než e-mail.
6
7
  password_complexity:
7
8
  digit:
8
9
  one: musí obsahovat alespoň jednu číslici
@@ -3,6 +3,7 @@ de:
3
3
  messages:
4
4
  taken_in_past: 'wurde bereits in der Vergangenheit verwendet.'
5
5
  equal_to_current_password: 'darf nicht dem aktuellen Passwort entsprechen.'
6
+ equal_to_email: 'darf nicht dem E-mail entsprechen.'
6
7
  password_complexity:
7
8
  digit:
8
9
  one: muss mindestens eine Ziffer enthalten
@@ -3,6 +3,7 @@ en:
3
3
  messages:
4
4
  taken_in_past: 'was used previously.'
5
5
  equal_to_current_password: 'must be different than the current password.'
6
+ equal_to_email: 'must be different than the email.'
6
7
  password_complexity:
7
8
  digit:
8
9
  one: must contain at least one digit
@@ -3,6 +3,7 @@ es:
3
3
  messages:
4
4
  taken_in_past: 'la contraseña fue usada previamente, por favor elige otra.'
5
5
  equal_to_current_password: 'tiene que ser diferente a la contraseña actual.'
6
+ equal_to_email: 'tiene que ser diferente al email'
6
7
  password_complexity:
7
8
  digit:
8
9
  one: tiene que contener al menos un dígito
@@ -3,6 +3,7 @@ fa:
3
3
  messages:
4
4
  taken_in_past: 'قبلا استفاده شده است'
5
5
  equal_to_current_password: 'باید متفاوت با رمز عبور فعلی باشد'
6
+ equal_to_email: 'باید متفاوت از ایمیل باشد'
6
7
  password_complexity:
7
8
  digit:
8
9
  one: باید حداقل یک رقم داشته باشد
@@ -3,6 +3,7 @@ fr:
3
3
  messages:
4
4
  taken_in_past: a été utilisé trop récemment. Veuillez en choisir un autre
5
5
  equal_to_current_password: doit être différent de l'actuel
6
+ equal_to_email: doit être différent de l'e-mail
6
7
  password_complexity:
7
8
  digit:
8
9
  one: doit contenir au moins un chiffre
@@ -2,40 +2,41 @@
2
2
  hi:
3
3
  errors:
4
4
  messages:
5
- taken_in_past: यह पासवर्ड, आपके द्वारा पूर्व मे प्रयोग किया जा चुका है
6
- equal_to_current_password: नया पासवर्ड, वर्तमान पासवर्ड से भिन्न होना चाहिए
5
+ taken_in_past: यह पासवर्ड, आपके द्वारा पूर्व मे प्रयोग किया जा चुका है
6
+ equal_to_current_password: नया पासवर्ड, वर्तमान पासवर्ड से भिन्न होना चाहिए
7
+ equal_to_email: ईमेल से अलग होना चाहिए
7
8
  password_complexity:
8
9
  digit:
9
- one: एक अंक होना चाहिए
10
- other: कम से कम %{count} अंक होने चाहिए
10
+ one: एक अंक होना चाहिए
11
+ other: कम से कम %{count} अंक होने चाहिए
11
12
  lower:
12
- one: एक लोअर-केस अक्षर होना चाहिए
13
- other: कम से कम %{count} अक्षर होने चाहिए
13
+ one: एक लोअर-केस अक्षर होना चाहिए
14
+ other: कम से कम %{count} अक्षर होने चाहिए
14
15
  symbol:
15
- one: एक चिन्ह होना चाहिए
16
- other: कम से कम %{count} चिन्ह होने चाहिए
16
+ one: एक चिन्ह होना चाहिए
17
+ other: कम से कम %{count} चिन्ह होने चाहिए
17
18
  upper:
18
- one: एक अपर-केस अक्षर होना चाहिए
19
- other: कम से कम %{count} अपर-केस अक्षर होने चाहिए
19
+ one: एक अपर-केस अक्षर होना चाहिए
20
+ other: कम से कम %{count} अपर-केस अक्षर होने चाहिए
20
21
  devise:
21
22
  invalid_captcha: अमान्य कॅप्टचा
22
23
  invalid_security_question: अमान्य सुरक्षा उत्तर
23
24
  paranoid_verify:
24
- code_required: सपोर्ट टीम द्वारा दिया गया कोड डाले
25
+ code_required: सपोर्ट टीम द्वारा दिया गया कोड डाले
25
26
  paranoid_verification_code:
26
27
  show:
27
- submit_verification_code: वेरिफिकेशन कोड डाले
28
- verification_code: वेरिफिकेशन कोड
29
- submit: सबमिट
28
+ submit_verification_code: वेरिफिकेशन कोड डाले
29
+ verification_code: वेरिफिकेशन कोड
30
+ submit: सबमिट
30
31
  password_expired:
31
32
  updated: पासवर्ड अद्यतन किया गया
32
- change_required: पासवर्ड अमान्य हो चुका, पासवर्ड बदले
33
+ change_required: पासवर्ड अमान्य हो चुका, पासवर्ड बदले
33
34
  show:
34
- renew_your_password: पासवर्ड बदले
35
+ renew_your_password: पासवर्ड बदले
35
36
  current_password: वर्तमान पासवर्ड
36
- new_password: नया पासवर्ड
37
- new_password_confirmation: नए पासवर्ड की पुष्टि करें
38
- change_my_password: पासवर्ड बदले
37
+ new_password: नया पासवर्ड
38
+ new_password_confirmation: नए पासवर्ड की पुष्टि करें
39
+ change_my_password: पासवर्ड बदले
39
40
  failure:
40
- session_limited: जानकारी, दूसरे ब्राउज़र में उपयोग की गयी थी जारी रखने फिर से साइन-इन करे
41
+ session_limited: जानकारी, दूसरे ब्राउज़र में उपयोग की गयी थी जारी रखने फिर से साइन-इन करे
41
42
  expired: कोई गतिविधि न होने के कारण खाता बंद हो गया, सिस्टम व्यवस्थापक से संपर्क करें
@@ -3,6 +3,7 @@ it:
3
3
  messages:
4
4
  taken_in_past: "è stata gia' utilizzata in passato!"
5
5
  equal_to_current_password: " deve essere differente dalla password corrente!"
6
+ equal_to_email: "deve essere differente dall'email"
6
7
  password_complexity:
7
8
  digit:
8
9
  one: deve contenere almeno una cifra
@@ -3,6 +3,7 @@ ja:
3
3
  messages:
4
4
  taken_in_past: 'は既に使われています。'
5
5
  equal_to_current_password: 'は現在のパスワードと異なるものである必要があります。'
6
+ equal_to_email: 'メールとは異なる必要があります'
6
7
  password_complexity:
7
8
  digit:
8
9
  one: は最低1つの数字を含む必要があります。
@@ -3,6 +3,7 @@ nl:
3
3
  messages:
4
4
  taken_in_past: is eerder gebruikt.
5
5
  equal_to_current_password: moet verschillen van het huidige wachtwoord.
6
+ equal_to_email: moet anders zijn dan de e-mail
6
7
  password_complexity:
7
8
  digit:
8
9
  one: moet minimaal 1 cijfer bevatten
@@ -3,6 +3,7 @@ pt:
3
3
  messages:
4
4
  taken_in_past: 'foi usada anteriormente.'
5
5
  equal_to_current_password: 'deve ser diferente da senha atual.'
6
+ equal_to_email: 'deve ser diferente do e-mail.'
6
7
  password_complexity:
7
8
  digit:
8
9
  one: deve conter ao menos um dígito
@@ -3,6 +3,7 @@ ru:
3
3
  messages:
4
4
  taken_in_past: 'уже ранее использовался.'
5
5
  equal_to_current_password: 'должен отличаться от текущего пароля.'
6
+ equal_to_email: 'должно отличаться от адреса электронной почты.'
6
7
  password_complexity:
7
8
  digit:
8
9
  one: 'должен содержать хотя бы одну цифру'
@@ -3,6 +3,7 @@ tr:
3
3
  messages:
4
4
  taken_in_past: "daha önce kullanıldı."
5
5
  equal_to_current_password: "mevcut paroladan farklı olmalı."
6
+ equal_to_email: "e-postadan farklı olmalı."
6
7
  password_format: "büyük, küçük harfler ve sayılar içermeli."
7
8
  devise:
8
9
  invalid_captcha: "Captcha hatalı."
@@ -3,6 +3,7 @@ uk:
3
3
  messages:
4
4
  taken_in_past: 'раніше використовувався.'
5
5
  equal_to_current_password: 'має відрізнятися від поточного паролю.'
6
+ equal_to_email: 'має відрізнятися від електронної пошти.'
6
7
  password_complexity:
7
8
  digit:
8
9
  one: 'повинен включати хоча б одну цифру'
@@ -3,6 +3,7 @@ zh_CN:
3
3
  messages:
4
4
  taken_in_past: '曾被使用过。'
5
5
  equal_to_current_password: '必须与当前密码不同。'
6
+ equal_to_email: '必须与电子邮件地址不同。'
6
7
  password_complexity:
7
8
  digit:
8
9
  one: 必须包含至少1个数字
@@ -3,6 +3,7 @@ zh_TW:
3
3
  messages:
4
4
  taken_in_past: '曾被使用過。'
5
5
  equal_to_current_password: '必須與目前密碼不同。'
6
+ equal_to_email: '必須與電子郵件地址不同。'
6
7
  password_complexity:
7
8
  digit:
8
9
  one: 必須包含至少一個數字
@@ -79,11 +79,14 @@ module Devise
79
79
  # paranoid_verification will regenerate verifacation code after faild attempt
80
80
  mattr_accessor :paranoid_code_regenerate_after_attempt
81
81
  @@paranoid_code_regenerate_after_attempt = 10
82
+
83
+ # Whether to allow passwords that are equal (case insensitive) to the email
84
+ mattr_accessor :allow_passwords_equal_to_email
85
+ @@allow_passwords_equal_to_email = false
82
86
  end
83
87
 
84
- # an security extension for devise
88
+ # a security extension for devise
85
89
  module DeviseSecurity
86
- autoload :Schema, 'devise-security/schema'
87
90
  autoload :Patches, 'devise-security/patches'
88
91
 
89
92
  module Controllers
@@ -104,6 +107,6 @@ Devise.add_module :paranoid_verification, controller: :paranoid_verification_cod
104
107
  # requires
105
108
  require 'devise-security/routes'
106
109
  require 'devise-security/rails'
107
- require "devise-security/orm/#{DEVISE_ORM}"
110
+ require "devise-security/orm/#{DEVISE_ORM}" if DEVISE_ORM == :mongoid
108
111
  require 'devise-security/models/database_authenticatable_patch'
109
112
  require 'devise-security/models/paranoid_verification'
@@ -88,11 +88,11 @@ module DeviseSecurity
88
88
 
89
89
  # redirect for password update with alert message
90
90
  def redirect_for_password_change(scope)
91
- redirect_to change_password_required_path_for(scope), alert: I18n.t('change_required', { scope: 'devise.password_expired' })
91
+ redirect_to change_password_required_path_for(scope), alert: I18n.t('change_required', scope: 'devise.password_expired')
92
92
  end
93
93
 
94
94
  def redirect_for_paranoid_verification(scope)
95
- redirect_to paranoid_verification_code_path_for(scope), alert: I18n.t('code_required', { scope: 'devise.paranoid_verify' })
95
+ redirect_to paranoid_verification_code_path_for(scope), alert: I18n.t('code_required', scope: 'devise.paranoid_verify')
96
96
  end
97
97
 
98
98
  # path for change password
@@ -7,9 +7,14 @@ Warden::Manager.after_set_user except: :fetch do |record, warden, options|
7
7
  if record.devise_modules.include?(:session_limitable) &&
8
8
  warden.authenticated?(options[:scope]) &&
9
9
  !record.skip_session_limitable?
10
- unique_session_id = Devise.friendly_token
11
- warden.session(options[:scope])['unique_session_id'] = unique_session_id
12
- record.update_unique_session_id!(unique_session_id)
10
+
11
+ if !options[:skip_session_limitable]
12
+ unique_session_id = Devise.friendly_token
13
+ warden.session(options[:scope])['unique_session_id'] = unique_session_id
14
+ record.update_unique_session_id!(unique_session_id)
15
+ else
16
+ warden.session(options[:scope])['devise.skip_session_limitable'] = true
17
+ end
13
18
  end
14
19
  end
15
20
 
@@ -19,14 +24,13 @@ end
19
24
  # page on the next request.
20
25
  Warden::Manager.after_set_user only: :fetch do |record, warden, options|
21
26
  scope = options[:scope]
22
- env = warden.request.env
23
27
 
24
28
  if record.devise_modules.include?(:session_limitable) &&
25
29
  warden.authenticated?(scope) &&
26
30
  options[:store] != false
27
31
  if record.unique_session_id != warden.session(scope)['unique_session_id'] &&
28
- !env['devise.skip_session_limitable'] &&
29
- !record.skip_session_limitable?
32
+ !record.skip_session_limitable? &&
33
+ !warden.session(scope)['devise.skip_session_limitable']
30
34
  Rails.logger.warn do
31
35
  '[devise-security][session_limitable] session id mismatch: '\
32
36
  "expected=#{record.unique_session_id.inspect} "\
@@ -55,6 +55,9 @@ module Devise
55
55
 
56
56
  # don't allow use same password
57
57
  validate :current_equal_password_validation
58
+
59
+ # don't allow email to equal password
60
+ validate :email_not_equal_password_validation unless allow_passwords_equal_to_email
58
61
  end
59
62
  end
60
63
 
@@ -70,6 +73,17 @@ module Devise
70
73
  self.errors.add(:password, :equal_to_current_password) if dummy.valid_password?(password)
71
74
  end
72
75
 
76
+ def email_not_equal_password_validation
77
+ return if password.blank? || (!new_record? && !will_save_change_to_encrypted_password?)
78
+ dummy = self.class.new.tap do |user|
79
+ user.password_salt = password_salt if respond_to?(:password_salt)
80
+ # whether case_insensitive_keys or strip_whitespace_keys include email or not, any
81
+ # variation of the email should not be a supported password
82
+ user.password = email.downcase.strip
83
+ end
84
+ self.errors.add(:password, :equal_to_email) if dummy.valid_password?(password.downcase.strip)
85
+ end
86
+
73
87
  protected
74
88
 
75
89
  # Checks whether a password is needed or not. For validations only.
@@ -84,7 +98,7 @@ module Devise
84
98
  end
85
99
 
86
100
  module ClassMethods
87
- Devise::Models.config(self, :password_complexity, :password_length, :email_validation)
101
+ Devise::Models.config(self, :password_complexity, :password_length, :email_validation, :allow_passwords_equal_to_email)
88
102
 
89
103
  private
90
104