devise_security_extension 0.6.2 → 0.7.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.
data/README.rdoc CHANGED
@@ -5,7 +5,7 @@ An enterprise security extension for devise, trying to meet industrial standard
5
5
  == Features
6
6
 
7
7
  * captcha support for sign_up, sign_in, recover and unlock (to make automated mass creation and brute forcing of accounts harder)
8
-
8
+
9
9
  === Model modules
10
10
 
11
11
  * :password_expirable - passwords will expire after a configured time (and will need an update)
@@ -13,6 +13,7 @@ An enterprise security extension for devise, trying to meet industrial standard
13
13
  * :password_archivable - save used passwords in an old_passwords table for history checks (don't be able to use a formerly used password)
14
14
  * :session_limitable - ensures, that there is only one session usable per account at once
15
15
  * :expirable - expires a user account after x days of inactivity (default 90 days)
16
+ * :security_questionable - as accessible substitution for captchas (security question with captcha fallback)
16
17
 
17
18
  == Installation
18
19
  Add to Gemfile
@@ -22,7 +23,7 @@ after bundle install
22
23
  rails g devise_security_extension:install
23
24
 
24
25
  for :secure_validatable you need to add
25
- gem 'rails_email_validator'
26
+ gem 'rails_email_validator'
26
27
 
27
28
  == Configuration
28
29
 
@@ -39,23 +40,35 @@ for :secure_validatable you need to add
39
40
  # Deny old password (true, false, count)
40
41
  # config.deny_old_passwords = true
41
42
 
42
- # captcha integration for recover form
43
+ # captcha integration for recover form
43
44
  # config.captcha_for_recover = true
44
-
45
+
45
46
  # captcha integration for sign up form
46
47
  # config.captcha_for_sign_up = true
47
-
48
+
48
49
  # captcha integration for sign in form
49
50
  # config.captcha_for_sign_in = true
50
-
51
+
51
52
  # captcha integration for unlock form
52
53
  # config.captcha_for_unlock = true
53
54
 
55
+ # security_question integration for recover form
56
+ # this automatically enables captchas (captcha_for_recover, as fallback)
57
+ # config.security_question_for_recover = false
58
+
59
+ # security_question integration for unlock form
60
+ # this automatically enables captchas (captcha_for_unlock, as fallback)
61
+ # config.security_question_for_unlock = false
62
+
63
+ # security_question integration for confirmation form
64
+ # this automatically enables captchas (captcha_for_confirmation, as fallback)
65
+ # config.security_question_for_confirmation = false
66
+
54
67
  # ==> Configuration for :expirable
55
68
  # Time period for account expiry from last_activity_at
56
69
  config.expire_after = 90.days
57
70
  end
58
-
71
+
59
72
  == Captcha-Support
60
73
 
61
74
  === Installation
@@ -112,6 +125,33 @@ That's it!
112
125
  add_index :the_resources, :last_activity_at
113
126
  add_index :the_resources, :expired_at
114
127
 
128
+ === Security questionable
129
+
130
+ create_table :security_questions do |t|
131
+ t.string :locale, :null => false
132
+ t.string :name, :null => false
133
+ end
134
+
135
+ SecurityQuestion.create! locale: :de, name: 'Wie lautet der Geburstname Ihrer Mutter?'
136
+ SecurityQuestion.create! locale: :de, name: 'Wo sind sie geboren?'
137
+ SecurityQuestion.create! locale: :de, name: 'Wie lautet der Name Ihres ersten Haustieres?'
138
+ SecurityQuestion.create! locale: :de, name: 'Was ist Ihr Lieblingsfilm?'
139
+ SecurityQuestion.create! locale: :de, name: 'Was ist Ihr Lieblingsbuch?'
140
+ SecurityQuestion.create! locale: :de, name: 'Was ist Ihr Lieblingstier?'
141
+ SecurityQuestion.create! locale: :de, name: 'Was ist Ihr Lieblings-Reiseland?'
142
+
143
+ add_column :the_resources, :security_question_id, :integer
144
+ add_column :the_resources, :security_question_answer, :string
145
+
146
+ or
147
+
148
+ create_table :the_resources do |t|
149
+ # other devise fields
150
+
151
+ t.integer :security_question_id
152
+ t.string :security_question_answer
153
+ end
154
+
115
155
  == Requirements
116
156
 
117
157
  * devise (https://github.com/plataformatec/devise)
@@ -129,6 +169,7 @@ That's it!
129
169
  * 0.4 captcha support for sign_up, sign_in, recover and unlock
130
170
  * 0.5 session_limitable module
131
171
  * 0.6 expirable module
172
+ * 0.7 security questionable module for recover and unlock
132
173
 
133
174
  == Maintainers
134
175
 
@@ -138,7 +179,7 @@ That's it!
138
179
  * Christoph Chilian (http://github.com/cc-web)
139
180
 
140
181
  == Contributing to devise_security_extension
141
-
182
+
142
183
  * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
143
184
  * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
144
185
  * Fork the project
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.6.2
1
+ 0.7.0
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "devise_security_extension"
8
- s.version = "0.6.2"
8
+ s.version = "0.7.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Marco Scholl", "Alexander Dreher"]
12
- s.date = "2012-06-12"
12
+ s.date = "2012-10-11"
13
13
  s.description = "An enterprise security extension for devise, trying to meet industrial standard security demands for web applications."
14
14
  s.email = "team@phatworx.de"
15
15
  s.extra_rdoc_files = [
@@ -39,14 +39,19 @@ Gem::Specification.new do |s|
39
39
  "lib/devise_security_extension/models/password_archivable.rb",
40
40
  "lib/devise_security_extension/models/password_expirable.rb",
41
41
  "lib/devise_security_extension/models/secure_validatable.rb",
42
+ "lib/devise_security_extension/models/security_question.rb",
43
+ "lib/devise_security_extension/models/security_questionable.rb",
42
44
  "lib/devise_security_extension/models/session_limitable.rb",
43
45
  "lib/devise_security_extension/orm/active_record.rb",
44
46
  "lib/devise_security_extension/patches.rb",
45
47
  "lib/devise_security_extension/patches/confirmations_controller_captcha.rb",
48
+ "lib/devise_security_extension/patches/confirmations_controller_security_question.rb",
46
49
  "lib/devise_security_extension/patches/passwords_controller_captcha.rb",
50
+ "lib/devise_security_extension/patches/passwords_controller_security_question.rb",
47
51
  "lib/devise_security_extension/patches/registrations_controller_captcha.rb",
48
52
  "lib/devise_security_extension/patches/sessions_controller_captcha.rb",
49
53
  "lib/devise_security_extension/patches/unlocks_controller_captcha.rb",
54
+ "lib/devise_security_extension/patches/unlocks_controller_security_question.rb",
50
55
  "lib/devise_security_extension/rails.rb",
51
56
  "lib/devise_security_extension/routes.rb",
52
57
  "lib/devise_security_extension/schema.rb",
@@ -27,23 +27,38 @@ module Devise
27
27
  # dependency: need an email validator like rails_email_validator
28
28
  mattr_accessor :email_validation
29
29
  @@email_validation = true
30
-
30
+
31
31
  # captcha integration for recover form
32
32
  mattr_accessor :captcha_for_recover
33
33
  @@captcha_for_recover = false
34
-
34
+
35
35
  # captcha integration for sign up form
36
36
  mattr_accessor :captcha_for_sign_up
37
37
  @@captcha_for_sign_up = false
38
-
38
+
39
39
  # captcha integration for sign in form
40
40
  mattr_accessor :captcha_for_sign_in
41
41
  @@captcha_for_sign_in = false
42
-
42
+
43
43
  # captcha integration for unlock form
44
44
  mattr_accessor :captcha_for_unlock
45
45
  @@captcha_for_unlock = false
46
-
46
+
47
+ # security_question integration for recover form
48
+ # this automatically enables captchas (captcha_for_recover, as fallback)
49
+ mattr_accessor :security_question_for_recover
50
+ @@security_question_for_recover = false
51
+
52
+ # security_question integration for unlock form
53
+ # this automatically enables captchas (captcha_for_unlock, as fallback)
54
+ mattr_accessor :security_question_for_unlock
55
+ @@security_question_for_unlock = false
56
+
57
+ # security_question integration for confirmation form
58
+ # this automatically enables captchas (captcha_for_confirmation, as fallback)
59
+ mattr_accessor :security_question_for_confirmation
60
+ @@security_question_for_confirmation = false
61
+
47
62
  # captcha integration for confirmation form
48
63
  mattr_accessor :captcha_for_confirmation
49
64
  @@captcha_for_confirmation = false
@@ -71,9 +86,11 @@ Devise.add_module :secure_validatable, :model => 'devise_security_extension/mode
71
86
  Devise.add_module :password_archivable, :model => 'devise_security_extension/models/password_archivable'
72
87
  Devise.add_module :session_limitable, :model => 'devise_security_extension/models/session_limitable'
73
88
  Devise.add_module :expirable, :model => 'devise_security_extension/models/expirable'
89
+ Devise.add_module :security_questionable, :model => 'devise_security_extension/models/security_questionable'
74
90
 
75
91
  # requires
76
92
  require 'devise_security_extension/routes'
77
93
  require 'devise_security_extension/rails'
78
94
  require 'devise_security_extension/orm/active_record'
79
95
  require 'devise_security_extension/models/old_password'
96
+ require 'devise_security_extension/models/security_question'
@@ -4,7 +4,7 @@
4
4
  # expired_at to the past (see Devise::Models::Expirable for this)
5
5
  Warden::Manager.after_set_user do |record, warden, options|
6
6
  if record && record.respond_to?(:active_for_authentication?) && record.active_for_authentication? &&
7
- warden.authenticated?(options[:scope]) && record.respond_to?(:update_last_activitiy!)
8
- record.update_last_activitiy!
7
+ warden.authenticated?(options[:scope]) && record.respond_to?(:update_last_activity!)
8
+ record.update_last_activity!
9
9
  end
10
10
  end
@@ -19,7 +19,7 @@ module Devise
19
19
  extend ActiveSupport::Concern
20
20
 
21
21
  # Updates +last_activity_at+, called from a Warden::Manager.after_set_user hook.
22
- def update_last_activitiy!
22
+ def update_last_activity!
23
23
  self.last_activity_at = Time.now.utc
24
24
  save(:validate => false)
25
25
  end
@@ -0,0 +1,3 @@
1
+ class SecurityQuestion < ActiveRecord::Base
2
+ attr_accessible :locale, :name
3
+ end
@@ -0,0 +1,15 @@
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 form:
7
+ # :security_question_answer and :captcha
8
+ #
9
+ # And add the security_question to the register/edit form.
10
+ module SecurityQuestionable
11
+ extend ActiveSupport::Concern
12
+
13
+ end
14
+ end
15
+ end
@@ -1,18 +1,26 @@
1
1
  module DeviseSecurityExtension
2
2
  module Patches
3
+ autoload :UnlocksControllerSecurityQuestion, 'devise_security_extension/patches/unlocks_controller_security_question'
4
+ autoload :PasswordsControllerSecurityQuestion, 'devise_security_extension/patches/passwords_controller_security_question'
5
+ autoload :ConfirmationsControllerSecurityQuestion, 'devise_security_extension/patches/confirmations_controller_security_question'
3
6
  autoload :UnlocksControllerCaptcha, 'devise_security_extension/patches/unlocks_controller_captcha'
4
7
  autoload :PasswordsControllerCaptcha, 'devise_security_extension/patches/passwords_controller_captcha'
5
8
  autoload :SessionsControllerCaptcha, 'devise_security_extension/patches/sessions_controller_captcha'
6
9
  autoload :RegistrationsControllerCaptcha, 'devise_security_extension/patches/registrations_controller_captcha'
7
10
  autoload :ConfirmationsControllerCaptcha, 'devise_security_extension/patches/confirmations_controller_captcha'
8
-
11
+
9
12
  class << self
10
13
  def apply
11
- Devise::PasswordsController.send(:include, Patches::PasswordsControllerCaptcha) if Devise.captcha_for_recover
12
- Devise::UnlocksController.send(:include, Patches::UnlocksControllerCaptcha) if Devise.captcha_for_unlock
14
+ Devise::PasswordsController.send(:include, Patches::PasswordsControllerCaptcha) if Devise.captcha_for_recover or Devise.security_question_for_recover
15
+ Devise::UnlocksController.send(:include, Patches::UnlocksControllerCaptcha) if Devise.captcha_for_unlock or Devise.security_question_for_unlock
16
+ Devise::ConfirmationsController.send(:include, Patches::ConfirmationsControllerCaptcha) if Devise.captcha_for_confirmation
17
+
18
+ Devise::PasswordsController.send(:include, Patches::PasswordsControllerSecurityQuestion) if Devise.security_question_for_recover
19
+ Devise::UnlocksController.send(:include, Patches::UnlocksControllerSecurityQuestion) if Devise.security_question_for_unlock
20
+ Devise::ConfirmationsController.send(:include, Patches::ConfirmationsControllerSecurityQuestion) if Devise.security_question_for_confirmation
21
+
13
22
  Devise::RegistrationsController.send(:include, Patches::RegistrationsControllerCaptcha) if Devise.captcha_for_sign_up
14
23
  Devise::SessionsController.send(:include, Patches::SessionsControllerCaptcha) if Devise.captcha_for_sign_in
15
- Devise::ConfirmationsController.send(:include, Patches::ConfirmationsControllerCaptcha) if Devise.captcha_for_confirmation
16
24
  end
17
25
  end
18
26
  end
@@ -0,0 +1,25 @@
1
+ module DeviseSecurityExtension::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 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,24 @@
1
+ module DeviseSecurityExtension::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 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_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,24 @@
1
+ module DeviseSecurityExtension::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 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_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
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: devise_security_extension
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.2
4
+ version: 0.7.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2012-06-12 00:00:00.000000000 Z
13
+ date: 2012-10-11 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rails
@@ -139,14 +139,19 @@ files:
139
139
  - lib/devise_security_extension/models/password_archivable.rb
140
140
  - lib/devise_security_extension/models/password_expirable.rb
141
141
  - lib/devise_security_extension/models/secure_validatable.rb
142
+ - lib/devise_security_extension/models/security_question.rb
143
+ - lib/devise_security_extension/models/security_questionable.rb
142
144
  - lib/devise_security_extension/models/session_limitable.rb
143
145
  - lib/devise_security_extension/orm/active_record.rb
144
146
  - lib/devise_security_extension/patches.rb
145
147
  - lib/devise_security_extension/patches/confirmations_controller_captcha.rb
148
+ - lib/devise_security_extension/patches/confirmations_controller_security_question.rb
146
149
  - lib/devise_security_extension/patches/passwords_controller_captcha.rb
150
+ - lib/devise_security_extension/patches/passwords_controller_security_question.rb
147
151
  - lib/devise_security_extension/patches/registrations_controller_captcha.rb
148
152
  - lib/devise_security_extension/patches/sessions_controller_captcha.rb
149
153
  - lib/devise_security_extension/patches/unlocks_controller_captcha.rb
154
+ - lib/devise_security_extension/patches/unlocks_controller_security_question.rb
150
155
  - lib/devise_security_extension/rails.rb
151
156
  - lib/devise_security_extension/routes.rb
152
157
  - lib/devise_security_extension/schema.rb
@@ -168,7 +173,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
168
173
  version: '0'
169
174
  segments:
170
175
  - 0
171
- hash: 3787897429771212555
176
+ hash: -2473272848721880190
172
177
  required_rubygems_version: !ruby/object:Gem::Requirement
173
178
  none: false
174
179
  requirements: