devise-security 0.11.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.
- checksums.yaml +7 -0
- data/.document +5 -0
- data/.gitignore +38 -0
- data/.rubocop.yml +42 -0
- data/.travis.yml +14 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +199 -0
- data/LICENSE.txt +20 -0
- data/README.md +263 -0
- data/Rakefile +26 -0
- data/app/controllers/devise/paranoid_verification_code_controller.rb +42 -0
- data/app/controllers/devise/password_expired_controller.rb +48 -0
- data/app/views/devise/paranoid_verification_code/show.html.erb +10 -0
- data/app/views/devise/password_expired/show.html.erb +16 -0
- data/config/locales/de.yml +16 -0
- data/config/locales/en.yml +17 -0
- data/config/locales/es.yml +17 -0
- data/config/locales/it.yml +10 -0
- data/devise-security.gemspec +34 -0
- data/lib/devise-security.rb +106 -0
- data/lib/devise-security/controllers/helpers.rb +96 -0
- data/lib/devise-security/hooks/expirable.rb +10 -0
- data/lib/devise-security/hooks/paranoid_verification.rb +5 -0
- data/lib/devise-security/hooks/password_expirable.rb +5 -0
- data/lib/devise-security/hooks/session_limitable.rb +27 -0
- data/lib/devise-security/models/database_authenticatable_patch.rb +26 -0
- data/lib/devise-security/models/expirable.rb +120 -0
- data/lib/devise-security/models/old_password.rb +4 -0
- data/lib/devise-security/models/paranoid_verification.rb +35 -0
- data/lib/devise-security/models/password_archivable.rb +80 -0
- data/lib/devise-security/models/password_expirable.rb +67 -0
- data/lib/devise-security/models/secure_validatable.rb +100 -0
- data/lib/devise-security/models/security_questionable.rb +18 -0
- data/lib/devise-security/models/session_limitable.rb +21 -0
- data/lib/devise-security/orm/active_record.rb +20 -0
- data/lib/devise-security/patches.rb +21 -0
- data/lib/devise-security/patches/confirmations_controller_captcha.rb +21 -0
- data/lib/devise-security/patches/confirmations_controller_security_question.rb +25 -0
- data/lib/devise-security/patches/controller_captcha.rb +17 -0
- data/lib/devise-security/patches/controller_security_question.rb +20 -0
- data/lib/devise-security/patches/passwords_controller_captcha.rb +20 -0
- data/lib/devise-security/patches/passwords_controller_security_question.rb +24 -0
- data/lib/devise-security/patches/registrations_controller_captcha.rb +33 -0
- data/lib/devise-security/patches/sessions_controller_captcha.rb +24 -0
- data/lib/devise-security/patches/unlocks_controller_captcha.rb +20 -0
- data/lib/devise-security/patches/unlocks_controller_security_question.rb +24 -0
- data/lib/devise-security/rails.rb +17 -0
- data/lib/devise-security/routes.rb +17 -0
- data/lib/devise-security/schema.rb +59 -0
- data/lib/devise-security/version.rb +3 -0
- data/lib/generators/devise-security/install_generator.rb +26 -0
- data/lib/generators/templates/devise-security.rb +38 -0
- data/test/dummy/Rakefile +6 -0
- data/test/dummy/app/controllers/application_controller.rb +2 -0
- data/test/dummy/app/controllers/captcha/sessions_controller.rb +3 -0
- data/test/dummy/app/controllers/foos_controller.rb +0 -0
- data/test/dummy/app/controllers/security_question/unlocks_controller.rb +3 -0
- data/test/dummy/app/models/.gitkeep +0 -0
- data/test/dummy/app/models/captcha_user.rb +5 -0
- data/test/dummy/app/models/secure_user.rb +3 -0
- data/test/dummy/app/models/security_question_user.rb +6 -0
- data/test/dummy/app/models/user.rb +5 -0
- data/test/dummy/app/views/foos/index.html.erb +0 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/config/application.rb +24 -0
- data/test/dummy/config/boot.rb +6 -0
- data/test/dummy/config/database.yml +7 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/test.rb +27 -0
- data/test/dummy/config/initializers/devise.rb +9 -0
- data/test/dummy/config/initializers/migration_class.rb +6 -0
- data/test/dummy/config/routes.rb +10 -0
- data/test/dummy/config/secrets.yml +3 -0
- data/test/dummy/db/migrate/20120508165529_create_tables.rb +33 -0
- data/test/dummy/db/migrate/20150402165590_add_verification_columns.rb +11 -0
- data/test/dummy/db/migrate/20150407162345_add_verification_attempt_column.rb +9 -0
- data/test/dummy/db/migrate/20160320162345_add_security_questions_fields.rb +8 -0
- data/test/test_captcha_controller.rb +58 -0
- data/test/test_helper.rb +13 -0
- data/test/test_install_generator.rb +16 -0
- data/test/test_paranoid_verification.rb +124 -0
- data/test/test_password_archivable.rb +61 -0
- data/test/test_password_expirable.rb +32 -0
- data/test/test_password_expired_controller.rb +29 -0
- data/test/test_secure_validatable.rb +85 -0
- data/test/test_security_question_controller.rb +60 -0
- metadata +315 -0
@@ -0,0 +1,18 @@
|
|
1
|
+
module Devise
|
2
|
+
module Models
|
3
|
+
# SecurityQuestionable is an accessible add-on for visually handicapped people,
|
4
|
+
# to ship around the captcha with screenreader compatibility.
|
5
|
+
#
|
6
|
+
# You need to add two text_field_tags to the associated forms (unlock,
|
7
|
+
# password, confirmation):
|
8
|
+
# :security_question_answer and :captcha
|
9
|
+
#
|
10
|
+
# And add the security_question to the register/edit form.
|
11
|
+
# f.select :security_question_id, SecurityQuestion.where(locale: I18n.locale).map{|s| [s.name, s.id]}
|
12
|
+
# f.text_field :security_question_answer
|
13
|
+
module SecurityQuestionable
|
14
|
+
extend ActiveSupport::Concern
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'devise-security/hooks/session_limitable'
|
2
|
+
|
3
|
+
module Devise
|
4
|
+
module Models
|
5
|
+
# SessionLimited ensures, that there is only one session usable per account at once.
|
6
|
+
# If someone logs in, and some other is logging in with the same credentials,
|
7
|
+
# the session from the first one is invalidated and not usable anymore.
|
8
|
+
# The first one is redirected to the sign page with a message, telling that
|
9
|
+
# someone used his credentials to sign in.
|
10
|
+
module SessionLimitable
|
11
|
+
extend ActiveSupport::Concern
|
12
|
+
|
13
|
+
def update_unique_session_id!(unique_session_id)
|
14
|
+
self.unique_session_id = unique_session_id
|
15
|
+
|
16
|
+
save(:validate => false)
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module DeviseSecurity
|
2
|
+
module Orm
|
3
|
+
# This module contains some helpers and handle schema (migrations):
|
4
|
+
#
|
5
|
+
# create_table :accounts do |t|
|
6
|
+
# t.password_expirable
|
7
|
+
# end
|
8
|
+
#
|
9
|
+
module ActiveRecord
|
10
|
+
module Schema
|
11
|
+
include DeviseSecurity::Schema
|
12
|
+
|
13
|
+
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
ActiveRecord::ConnectionAdapters::Table.send :include, DeviseSecurity::Orm::ActiveRecord::Schema
|
20
|
+
ActiveRecord::ConnectionAdapters::TableDefinition.send :include, DeviseSecurity::Orm::ActiveRecord::Schema
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module DeviseSecurity
|
2
|
+
module Patches
|
3
|
+
autoload :ControllerCaptcha, 'devise-security/patches/controller_captcha'
|
4
|
+
autoload :ControllerSecurityQuestion, 'devise-security/patches/controller_security_question'
|
5
|
+
|
6
|
+
class << self
|
7
|
+
def apply
|
8
|
+
Devise::PasswordsController.send(:include, Patches::ControllerCaptcha) if Devise.captcha_for_recover || Devise.security_question_for_recover
|
9
|
+
Devise::UnlocksController.send(:include, Patches::ControllerCaptcha) if Devise.captcha_for_unlock || Devise.security_question_for_unlock
|
10
|
+
Devise::ConfirmationsController.send(:include, Patches::ControllerCaptcha) if Devise.captcha_for_confirmation
|
11
|
+
|
12
|
+
Devise::PasswordsController.send(:include, Patches::ControllerSecurityQuestion) if Devise.security_question_for_recover
|
13
|
+
Devise::UnlocksController.send(:include, Patches::ControllerSecurityQuestion) if Devise.security_question_for_unlock
|
14
|
+
Devise::ConfirmationsController.send(:include, Patches::ControllerSecurityQuestion) if Devise.security_question_for_confirmation
|
15
|
+
|
16
|
+
Devise::RegistrationsController.send(:include, Patches::ControllerCaptcha) if Devise.captcha_for_sign_up
|
17
|
+
Devise::SessionsController.send(:include, Patches::ControllerCaptcha) if Devise.captcha_for_sign_in
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module DeviseSecurity::Patches
|
2
|
+
module ConfirmationsControllerCaptcha
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
included do
|
5
|
+
define_method :create do
|
6
|
+
if ((defined? verify_recaptcha) && (verify_recaptcha)) or ((defined? valid_captcha?) && (valid_captcha? params[:captcha]))
|
7
|
+
self.resource = resource_class.send_confirmation_instructions(params[resource_name])
|
8
|
+
|
9
|
+
if successfully_sent?(resource)
|
10
|
+
respond_with({}, :location => after_resending_confirmation_instructions_path_for(resource_name))
|
11
|
+
else
|
12
|
+
respond_with(resource)
|
13
|
+
end
|
14
|
+
else
|
15
|
+
flash[:alert] = t('devise.invalid_captcha') if is_navigational_format?
|
16
|
+
respond_with({}, :location => new_confirmation_path(resource_name))
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module DeviseSecurity::Patches
|
2
|
+
module ConfirmationsControllerSecurityQuestion
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
included do
|
5
|
+
define_method :create do
|
6
|
+
# only find via email, not login
|
7
|
+
resource = resource_class.find_or_initialize_with_error_by(:email, params[resource_name][:email], :not_found)
|
8
|
+
|
9
|
+
if ((defined? verify_recaptcha) && (verify_recaptcha)) or ((defined? valid_captcha?) && (valid_captcha? params[:captcha])) or
|
10
|
+
(resource.security_question_answer.present? and resource.security_question_answer == params[:security_question_answer])
|
11
|
+
self.resource = resource_class.send_confirmation_instructions(params[resource_name])
|
12
|
+
|
13
|
+
if successfully_sent?(resource)
|
14
|
+
respond_with({}, :location => after_resending_confirmation_instructions_path_for(resource_name))
|
15
|
+
else
|
16
|
+
respond_with(resource)
|
17
|
+
end
|
18
|
+
else
|
19
|
+
flash[:alert] = t('devise.invalid_security_question') if is_navigational_format?
|
20
|
+
respond_with({}, :location => new_confirmation_path(resource_name))
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module DeviseSecurity::Patches
|
2
|
+
module ControllerCaptcha
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
included do
|
6
|
+
prepend_before_action :check_captcha, only: [:create]
|
7
|
+
end
|
8
|
+
|
9
|
+
private
|
10
|
+
def check_captcha
|
11
|
+
return if ((defined? verify_recaptcha) && (verify_recaptcha)) || ((defined? valid_captcha?) && (valid_captcha? params[:captcha]))
|
12
|
+
|
13
|
+
flash[:alert] = t('devise.invalid_captcha') if is_navigational_format?
|
14
|
+
respond_with({}, location: url_for(action: :new))
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module DeviseSecurity::Patches
|
2
|
+
module ControllerSecurityQuestion
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
included do
|
6
|
+
prepend_before_action :check_security_question, only: [:create]
|
7
|
+
end
|
8
|
+
|
9
|
+
private
|
10
|
+
def check_security_question
|
11
|
+
# only find via email, not login
|
12
|
+
resource = resource_class.find_or_initialize_with_error_by(:email, params[resource_name][:email], :not_found)
|
13
|
+
return if (resource.security_question_answer.present? && resource.security_question_answer == params[:security_question_answer])
|
14
|
+
|
15
|
+
flash[:alert] = t('devise.invalid_security_question') if is_navigational_format?
|
16
|
+
respond_with({}, location: url_for(action: :new))
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module DeviseSecurity::Patches
|
2
|
+
module PasswordsControllerCaptcha
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
included do
|
5
|
+
define_method :create do
|
6
|
+
if ((defined? verify_recaptcha) && (verify_recaptcha)) or ((defined? valid_captcha?) && (valid_captcha? params[:captcha]))
|
7
|
+
self.resource = resource_class.send_reset_password_instructions(params[resource_name])
|
8
|
+
if successfully_sent?(resource)
|
9
|
+
respond_with({}, :location => new_session_path(resource_name))
|
10
|
+
else
|
11
|
+
respond_with(resource)
|
12
|
+
end
|
13
|
+
else
|
14
|
+
flash[:alert] = t('devise.invalid_captcha') if is_navigational_format?
|
15
|
+
respond_with({}, :location => new_password_path(resource_name))
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module DeviseSecurity::Patches
|
2
|
+
module PasswordsControllerSecurityQuestion
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
included do
|
5
|
+
define_method :create do
|
6
|
+
# only find via email, not login
|
7
|
+
resource = resource_class.find_or_initialize_with_error_by(:email, params[resource_name][:email], :not_found)
|
8
|
+
|
9
|
+
if ((defined? verify_recaptcha) && (verify_recaptcha)) or ((defined? valid_captcha?) && (valid_captcha? params[:captcha]))
|
10
|
+
(resource.security_question_answer.present? and resource.security_question_answer == params[:security_question_answer])
|
11
|
+
self.resource = resource_class.send_reset_password_instructions(params[resource_name])
|
12
|
+
if successfully_sent?(resource)
|
13
|
+
respond_with({}, :location => new_session_path(resource_name))
|
14
|
+
else
|
15
|
+
respond_with(resource)
|
16
|
+
end
|
17
|
+
else
|
18
|
+
flash[:alert] = t('devise.invalid_security_question') if is_navigational_format?
|
19
|
+
respond_with({}, :location => new_password_path(resource_name))
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module DeviseSecurity::Patches
|
2
|
+
module RegistrationsControllerCaptcha
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
included do
|
5
|
+
define_method :create do |&block|
|
6
|
+
build_resource(sign_up_params)
|
7
|
+
|
8
|
+
if ((defined? verify_recaptcha) && (verify_recaptcha)) or ((defined? valid_captcha?) && (valid_captcha? params[:captcha]))
|
9
|
+
if resource.save
|
10
|
+
block.call(resource) if block
|
11
|
+
if resource.active_for_authentication?
|
12
|
+
set_flash_message :notice, :signed_up if is_flashing_format?
|
13
|
+
sign_up(resource_name, resource)
|
14
|
+
respond_with resource, :location => after_sign_up_path_for(resource)
|
15
|
+
else
|
16
|
+
set_flash_message :notice, :"signed_up_but_#{resource.inactive_message}" if is_flashing_format?
|
17
|
+
expire_data_after_sign_in!
|
18
|
+
respond_with resource, :location => after_inactive_sign_up_path_for(resource)
|
19
|
+
end
|
20
|
+
else
|
21
|
+
clean_up_passwords resource
|
22
|
+
respond_with resource
|
23
|
+
end
|
24
|
+
|
25
|
+
else
|
26
|
+
resource.errors.add :base, t('devise.invalid_captcha')
|
27
|
+
clean_up_passwords resource
|
28
|
+
respond_with resource
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module DeviseSecurity::Patches
|
2
|
+
module SessionsControllerCaptcha
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
included do
|
5
|
+
define_method :create do |&block|
|
6
|
+
if ((defined? verify_recaptcha) && (verify_recaptcha)) or ((defined? valid_captcha?) && (valid_captcha? params[:captcha]))
|
7
|
+
self.resource = warden.authenticate!(auth_options)
|
8
|
+
set_flash_message(:notice, :signed_in) if is_flashing_format?
|
9
|
+
sign_in(resource_name, resource)
|
10
|
+
block.call(resource) if block
|
11
|
+
respond_with resource, :location => after_sign_in_path_for(resource)
|
12
|
+
else
|
13
|
+
flash[:alert] = t('devise.invalid_captcha') if is_flashing_format?
|
14
|
+
respond_with({}, :location => new_session_path(resource_name))
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
# for bad protected use in controller
|
19
|
+
define_method :auth_options do
|
20
|
+
{ :scope => resource_name, :recall => "#{controller_path}#new" }
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module DeviseSecurity::Patches
|
2
|
+
module UnlocksControllerCaptcha
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
included do
|
5
|
+
define_method :create do
|
6
|
+
if ((defined? verify_recaptcha) && (verify_recaptcha)) or ((defined? valid_captcha?) && (valid_captcha? params[:captcha]))
|
7
|
+
self.resource = resource_class.send_unlock_instructions(params[resource_name])
|
8
|
+
if successfully_sent?(resource)
|
9
|
+
respond_with({}, :location => new_session_path(resource_name))
|
10
|
+
else
|
11
|
+
respond_with(resource)
|
12
|
+
end
|
13
|
+
else
|
14
|
+
flash[:alert] = t('devise.invalid_captcha') if is_navigational_format?
|
15
|
+
respond_with({}, :location => new_unlock_path(resource_name))
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module DeviseSecurity::Patches
|
2
|
+
module UnlocksControllerSecurityQuestion
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
included do
|
5
|
+
define_method :create do
|
6
|
+
# only find via email, not login
|
7
|
+
resource = resource_class.find_or_initialize_with_error_by(:email, params[resource_name][:email], :not_found)
|
8
|
+
|
9
|
+
if ((defined? verify_recaptcha) && (verify_recaptcha)) or ((defined? valid_captcha?) && (valid_captcha? params[:captcha]))
|
10
|
+
(resource.security_question_answer.present? and resource.security_question_answer == params[:security_question_answer])
|
11
|
+
self.resource = resource_class.send_unlock_instructions(params[resource_name])
|
12
|
+
if successfully_sent?(resource)
|
13
|
+
respond_with({}, :location => new_session_path(resource_name))
|
14
|
+
else
|
15
|
+
respond_with(resource)
|
16
|
+
end
|
17
|
+
else
|
18
|
+
flash[:alert] = t('devise.invalid_security_question') if is_navigational_format?
|
19
|
+
respond_with({}, :location => new_unlock_path(resource_name))
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module DeviseSecurity
|
2
|
+
class Engine < ::Rails::Engine
|
3
|
+
ActiveSupport.on_load(:action_controller) do
|
4
|
+
include DeviseSecurity::Controllers::Helpers
|
5
|
+
end
|
6
|
+
|
7
|
+
if Rails.version > "5"
|
8
|
+
ActiveSupport::Reloader.to_prepare do
|
9
|
+
DeviseSecurity::Patches.apply
|
10
|
+
end
|
11
|
+
else
|
12
|
+
ActionDispatch::Callbacks.to_prepare do
|
13
|
+
DeviseSecurity::Patches.apply
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module ActionDispatch::Routing
|
2
|
+
class Mapper
|
3
|
+
|
4
|
+
protected
|
5
|
+
|
6
|
+
# route for handle expired passwords
|
7
|
+
def devise_password_expired(mapping, controllers)
|
8
|
+
resource :password_expired, :only => [:show, :update], :path => mapping.path_names[:password_expired], :controller => controllers[:password_expired]
|
9
|
+
end
|
10
|
+
|
11
|
+
# route for handle paranoid verification
|
12
|
+
def devise_verification_code(mapping, controllers)
|
13
|
+
resource :paranoid_verification_code, :only => [:show, :update], :path => mapping.path_names[:verification_code], :controller => controllers[:paranoid_verification_code]
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module DeviseSecurity
|
2
|
+
# add schema helper for migrations
|
3
|
+
module Schema
|
4
|
+
# Add password_changed_at columns in the resource's database table.
|
5
|
+
#
|
6
|
+
# Examples
|
7
|
+
#
|
8
|
+
# # For a new resource migration:
|
9
|
+
# create_table :the_resources do |t|
|
10
|
+
# t.password_expirable
|
11
|
+
# ...
|
12
|
+
# end
|
13
|
+
#
|
14
|
+
# # or if the resource's table already exists, define a migration and put this in:
|
15
|
+
# change_table :the_resources do |t|
|
16
|
+
# t.datetime :password_changed_at
|
17
|
+
# end
|
18
|
+
#
|
19
|
+
def password_expirable
|
20
|
+
apply_devise_schema :password_changed_at, DateTime
|
21
|
+
end
|
22
|
+
|
23
|
+
# Add password_archivable columns
|
24
|
+
#
|
25
|
+
# Examples
|
26
|
+
#
|
27
|
+
# create_table :old_passwords do
|
28
|
+
# t.password_archivable
|
29
|
+
# end
|
30
|
+
# add_index :old_passwords, [:password_archivable_type, :password_archivable_id], :name => :index_password_archivable
|
31
|
+
#
|
32
|
+
def password_archivable
|
33
|
+
apply_devise_schema :encrypted_password, String, :limit => 128, :null => false
|
34
|
+
apply_devise_schema :password_salt, String
|
35
|
+
apply_devise_schema :password_archivable_id, Integer, :null => false
|
36
|
+
apply_devise_schema :password_archivable_type, String, :null => false
|
37
|
+
apply_devise_schema :created_at, DateTime
|
38
|
+
end
|
39
|
+
|
40
|
+
# Add session_limitable columns in the resource's database table.
|
41
|
+
#
|
42
|
+
# Examples
|
43
|
+
#
|
44
|
+
# # For a new resource migration:
|
45
|
+
# create_table :the_resources do |t|
|
46
|
+
# t.session_limitable
|
47
|
+
# ...
|
48
|
+
# end
|
49
|
+
#
|
50
|
+
# # or if the resource's table already exists, define a migration and put this in:
|
51
|
+
# change_table :the_resources do |t|
|
52
|
+
# t.string :unique_session_id, :limit => 20
|
53
|
+
# end
|
54
|
+
#
|
55
|
+
def session_limitable
|
56
|
+
apply_devise_schema :unique_session_id, String, :limit => 20
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module DeviseSecurity
|
2
|
+
module Generators
|
3
|
+
# Generator for Rails to create or append to a Devise initializer.
|
4
|
+
class InstallGenerator < Rails::Generators::Base
|
5
|
+
LOCALES = %w[ en de it ]
|
6
|
+
|
7
|
+
source_root File.expand_path('../../templates', __FILE__)
|
8
|
+
desc 'Install the devise security extension'
|
9
|
+
|
10
|
+
def copy_initializer
|
11
|
+
template('devise-security.rb',
|
12
|
+
'config/initializers/devise-security.rb',
|
13
|
+
)
|
14
|
+
end
|
15
|
+
|
16
|
+
def copy_locales
|
17
|
+
LOCALES.each do |locale|
|
18
|
+
copy_file(
|
19
|
+
"../../../config/locales/#{locale}.yml",
|
20
|
+
"config/locales/devise.security_extension.#{locale}.yml",
|
21
|
+
)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|