devise_security_extension 0.6.2 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
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: