devise_security_extension 0.6.0 → 0.6.1
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/Gemfile +1 -1
- data/Gemfile.lock +68 -44
- data/README.rdoc +17 -14
- data/VERSION +1 -1
- data/app/controllers/devise/password_expired_controller.rb +4 -4
- data/devise_security_extension.gemspec +11 -7
- data/lib/devise_security_extension.rb +5 -1
- data/lib/devise_security_extension/controllers/helpers.rb +4 -8
- data/lib/devise_security_extension/models/expirable.rb +38 -41
- data/lib/devise_security_extension/models/old_password.rb +3 -1
- data/lib/devise_security_extension/models/password_archivable.rb +39 -46
- data/lib/devise_security_extension/models/password_expirable.rb +29 -35
- data/lib/devise_security_extension/models/secure_validatable.rb +3 -1
- data/lib/devise_security_extension/models/session_limitable.rb +2 -2
- data/lib/devise_security_extension/patches.rb +10 -5
- data/lib/devise_security_extension/patches/confirmations_controller_captcha.rb +21 -0
- data/lib/devise_security_extension/patches/passwords_controller_captcha.rb +20 -0
- data/lib/devise_security_extension/patches/registrations_controller_captcha.rb +33 -0
- data/lib/devise_security_extension/patches/sessions_controller_captcha.rb +23 -0
- data/lib/devise_security_extension/patches/unlocks_controller_captcha.rb +20 -0
- data/lib/devise_security_extension/rails.rb +1 -1
- data/lib/devise_security_extension/routes.rb +2 -2
- data/lib/generators/devise_security_extension/install_generator.rb +4 -3
- metadata +52 -18
- data/lib/devise_security_extension/patches/controller_captcha.rb +0 -21
data/Gemfile
CHANGED
|
@@ -2,7 +2,7 @@ source "http://rubygems.org"
|
|
|
2
2
|
# Add dependencies required to use your gem here.
|
|
3
3
|
# Example:
|
|
4
4
|
gem "rails", ">= 3.1.1"
|
|
5
|
-
gem "devise"
|
|
5
|
+
gem "devise", ">= 2.0.0"
|
|
6
6
|
|
|
7
7
|
# Add dependencies to develop your gem here.
|
|
8
8
|
# Include everything needed to run rake, tests, features, etc.
|
data/Gemfile.lock
CHANGED
|
@@ -1,43 +1,49 @@
|
|
|
1
1
|
GEM
|
|
2
2
|
remote: http://rubygems.org/
|
|
3
3
|
specs:
|
|
4
|
-
actionmailer (3.1
|
|
5
|
-
actionpack (= 3.1
|
|
6
|
-
mail (~> 2.
|
|
7
|
-
actionpack (3.1
|
|
8
|
-
activemodel (= 3.1
|
|
9
|
-
activesupport (= 3.1
|
|
4
|
+
actionmailer (3.2.1)
|
|
5
|
+
actionpack (= 3.2.1)
|
|
6
|
+
mail (~> 2.4.0)
|
|
7
|
+
actionpack (3.2.1)
|
|
8
|
+
activemodel (= 3.2.1)
|
|
9
|
+
activesupport (= 3.2.1)
|
|
10
10
|
builder (~> 3.0.0)
|
|
11
11
|
erubis (~> 2.7.0)
|
|
12
|
-
|
|
13
|
-
rack (~> 1.
|
|
12
|
+
journey (~> 1.0.1)
|
|
13
|
+
rack (~> 1.4.0)
|
|
14
14
|
rack-cache (~> 1.1)
|
|
15
|
-
rack-mount (~> 0.8.2)
|
|
16
15
|
rack-test (~> 0.6.1)
|
|
17
|
-
sprockets (~> 2.
|
|
18
|
-
activemodel (3.1
|
|
19
|
-
activesupport (= 3.1
|
|
16
|
+
sprockets (~> 2.1.2)
|
|
17
|
+
activemodel (3.2.1)
|
|
18
|
+
activesupport (= 3.2.1)
|
|
20
19
|
builder (~> 3.0.0)
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
arel (~> 2.2.1)
|
|
20
|
+
activerecord (3.2.1)
|
|
21
|
+
activemodel (= 3.2.1)
|
|
22
|
+
activesupport (= 3.2.1)
|
|
23
|
+
arel (~> 3.0.0)
|
|
26
24
|
tzinfo (~> 0.3.29)
|
|
27
|
-
activeresource (3.1
|
|
28
|
-
activemodel (= 3.1
|
|
29
|
-
activesupport (= 3.1
|
|
30
|
-
activesupport (3.1
|
|
25
|
+
activeresource (3.2.1)
|
|
26
|
+
activemodel (= 3.2.1)
|
|
27
|
+
activesupport (= 3.2.1)
|
|
28
|
+
activesupport (3.2.1)
|
|
29
|
+
i18n (~> 0.6)
|
|
31
30
|
multi_json (~> 1.0)
|
|
32
|
-
arel (
|
|
31
|
+
arel (3.0.0)
|
|
33
32
|
bcrypt-ruby (3.0.1)
|
|
34
33
|
builder (3.0.0)
|
|
35
|
-
devise (
|
|
34
|
+
devise (2.0.0)
|
|
36
35
|
bcrypt-ruby (~> 3.0)
|
|
37
36
|
orm_adapter (~> 0.0.3)
|
|
37
|
+
railties (~> 3.1)
|
|
38
38
|
warden (~> 1.1)
|
|
39
|
-
|
|
39
|
+
diff-lcs (1.1.3)
|
|
40
|
+
easy_captcha (0.4.7)
|
|
41
|
+
bundler (~> 1.0.0)
|
|
40
42
|
rails (>= 3.0.0)
|
|
43
|
+
rmagick (>= 2.13.1)
|
|
44
|
+
rspec-rails (~> 2.8.1)
|
|
45
|
+
simplecov (>= 0.3.8)
|
|
46
|
+
yard (>= 0.7.0)
|
|
41
47
|
erubis (2.7.0)
|
|
42
48
|
git (1.2.5)
|
|
43
49
|
hike (1.2.1)
|
|
@@ -46,45 +52,62 @@ GEM
|
|
|
46
52
|
bundler (~> 1.0.0)
|
|
47
53
|
git (>= 1.2.5)
|
|
48
54
|
rake
|
|
49
|
-
|
|
50
|
-
|
|
55
|
+
journey (1.0.1)
|
|
56
|
+
json (1.6.5)
|
|
57
|
+
mail (2.4.1)
|
|
51
58
|
i18n (>= 0.4.0)
|
|
52
59
|
mime-types (~> 1.16)
|
|
53
60
|
treetop (~> 1.4.8)
|
|
54
61
|
mime-types (1.17.2)
|
|
55
|
-
multi_json (1.0.
|
|
56
|
-
orm_adapter (0.0.
|
|
62
|
+
multi_json (1.0.4)
|
|
63
|
+
orm_adapter (0.0.6)
|
|
57
64
|
polyglot (0.3.3)
|
|
58
|
-
rack (1.
|
|
65
|
+
rack (1.4.1)
|
|
59
66
|
rack-cache (1.1)
|
|
60
67
|
rack (>= 0.4)
|
|
61
|
-
rack-mount (0.8.3)
|
|
62
|
-
rack (>= 1.0.0)
|
|
63
68
|
rack-ssl (1.3.2)
|
|
64
69
|
rack
|
|
65
70
|
rack-test (0.6.1)
|
|
66
71
|
rack (>= 1.0)
|
|
67
|
-
rails (3.1
|
|
68
|
-
actionmailer (= 3.1
|
|
69
|
-
actionpack (= 3.1
|
|
70
|
-
activerecord (= 3.1
|
|
71
|
-
activeresource (= 3.1
|
|
72
|
-
activesupport (= 3.1
|
|
72
|
+
rails (3.2.1)
|
|
73
|
+
actionmailer (= 3.2.1)
|
|
74
|
+
actionpack (= 3.2.1)
|
|
75
|
+
activerecord (= 3.2.1)
|
|
76
|
+
activeresource (= 3.2.1)
|
|
77
|
+
activesupport (= 3.2.1)
|
|
73
78
|
bundler (~> 1.0)
|
|
74
|
-
railties (= 3.1
|
|
79
|
+
railties (= 3.2.1)
|
|
75
80
|
rails_email_validator (0.1.4)
|
|
76
81
|
activemodel (>= 3.0.0)
|
|
77
|
-
railties (3.1
|
|
78
|
-
actionpack (= 3.1
|
|
79
|
-
activesupport (= 3.1
|
|
82
|
+
railties (3.2.1)
|
|
83
|
+
actionpack (= 3.2.1)
|
|
84
|
+
activesupport (= 3.2.1)
|
|
80
85
|
rack-ssl (~> 1.3.2)
|
|
81
86
|
rake (>= 0.8.7)
|
|
82
87
|
rdoc (~> 3.4)
|
|
83
88
|
thor (~> 0.14.6)
|
|
84
89
|
rake (0.9.2.2)
|
|
85
|
-
rdoc (3.
|
|
90
|
+
rdoc (3.12)
|
|
86
91
|
json (~> 1.4)
|
|
87
|
-
|
|
92
|
+
rmagick (2.13.1)
|
|
93
|
+
rspec (2.8.0)
|
|
94
|
+
rspec-core (~> 2.8.0)
|
|
95
|
+
rspec-expectations (~> 2.8.0)
|
|
96
|
+
rspec-mocks (~> 2.8.0)
|
|
97
|
+
rspec-core (2.8.0)
|
|
98
|
+
rspec-expectations (2.8.0)
|
|
99
|
+
diff-lcs (~> 1.1.2)
|
|
100
|
+
rspec-mocks (2.8.0)
|
|
101
|
+
rspec-rails (2.8.1)
|
|
102
|
+
actionpack (>= 3.0)
|
|
103
|
+
activesupport (>= 3.0)
|
|
104
|
+
railties (>= 3.0)
|
|
105
|
+
rspec (~> 2.8.0)
|
|
106
|
+
simplecov (0.5.4)
|
|
107
|
+
multi_json (~> 1.0.3)
|
|
108
|
+
simplecov-html (~> 0.5.3)
|
|
109
|
+
simplecov-html (0.5.3)
|
|
110
|
+
sprockets (2.1.2)
|
|
88
111
|
hike (~> 1.2)
|
|
89
112
|
rack (~> 1.0)
|
|
90
113
|
tilt (~> 1.1, != 1.3.0)
|
|
@@ -96,13 +119,14 @@ GEM
|
|
|
96
119
|
tzinfo (0.3.31)
|
|
97
120
|
warden (1.1.0)
|
|
98
121
|
rack (>= 1.0)
|
|
122
|
+
yard (0.7.5)
|
|
99
123
|
|
|
100
124
|
PLATFORMS
|
|
101
125
|
ruby
|
|
102
126
|
|
|
103
127
|
DEPENDENCIES
|
|
104
128
|
bundler (~> 1.0.0)
|
|
105
|
-
devise
|
|
129
|
+
devise (>= 2.0.0)
|
|
106
130
|
easy_captcha
|
|
107
131
|
jeweler (~> 1.5.2)
|
|
108
132
|
rails (>= 3.1.1)
|
data/README.rdoc
CHANGED
|
@@ -76,39 +76,41 @@ That's it!
|
|
|
76
76
|
=== Password expirable
|
|
77
77
|
|
|
78
78
|
create_table :the_resources do |t|
|
|
79
|
-
|
|
79
|
+
# other devise fields
|
|
80
|
+
|
|
81
|
+
t.datetime :password_changed_at
|
|
80
82
|
end
|
|
83
|
+
add_index :the_resources, :password_changed_at
|
|
81
84
|
|
|
82
85
|
=== Password archivable
|
|
83
86
|
|
|
84
87
|
create_table :old_passwords do |t|
|
|
85
|
-
t.
|
|
88
|
+
t.string :encrypted_password, :null => false
|
|
89
|
+
t.string :password_salt
|
|
90
|
+
t.string :password_archivable_type, :null => false
|
|
91
|
+
t.integer :password_archivable_id, :null => false
|
|
92
|
+
t.datetime :created_at
|
|
86
93
|
end
|
|
87
94
|
add_index :old_passwords, [:password_archivable_type, :password_archivable_id], :name => :index_password_archivable
|
|
88
95
|
|
|
89
96
|
=== Session limitable
|
|
90
97
|
|
|
91
98
|
create_table :the_resources do |t|
|
|
92
|
-
|
|
99
|
+
# other devise fields
|
|
100
|
+
|
|
101
|
+
t.string :unique_session_id, :limit => 20
|
|
93
102
|
end
|
|
94
103
|
|
|
95
104
|
=== Expirable
|
|
96
|
-
Devise 2.0 style migrations on new resource:
|
|
97
105
|
|
|
98
106
|
create_table :the_resources do |t|
|
|
99
|
-
|
|
100
|
-
t.datetime :last_activity_at
|
|
101
|
-
t.datetime :expired_at
|
|
102
|
-
...
|
|
103
|
-
end
|
|
107
|
+
# other devise fields
|
|
104
108
|
|
|
105
|
-
Add module to existing resource with
|
|
106
|
-
|
|
107
|
-
change_table :the_resources do |t|
|
|
108
109
|
t.datetime :last_activity_at
|
|
109
110
|
t.datetime :expired_at
|
|
110
111
|
end
|
|
111
|
-
|
|
112
|
+
add_index :the_resources, :last_activity_at
|
|
113
|
+
add_index :the_resources, :expired_at
|
|
112
114
|
|
|
113
115
|
== Requirements
|
|
114
116
|
|
|
@@ -133,6 +135,7 @@ Add module to existing resource with
|
|
|
133
135
|
* Team Phatworx (http://github.com/phatworx)
|
|
134
136
|
* Marco Scholl (http://github.com/traxanos)
|
|
135
137
|
* Alexander Dreher (http://github.com/alexdreher)
|
|
138
|
+
* Christoph Chilian (http://github.com/cc-web)
|
|
136
139
|
|
|
137
140
|
== Contributing to devise_security_extension
|
|
138
141
|
|
|
@@ -146,4 +149,4 @@ Add module to existing resource with
|
|
|
146
149
|
|
|
147
150
|
== Copyright
|
|
148
151
|
|
|
149
|
-
Copyright (c) 2011 Marco Scholl. See LICENSE.txt for further details.
|
|
152
|
+
Copyright (c) 2011-2012 Marco Scholl. See LICENSE.txt for further details.
|
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.6.
|
|
1
|
+
0.6.1
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
class Devise::PasswordExpiredController <
|
|
1
|
+
class Devise::PasswordExpiredController < DeviseController
|
|
2
2
|
skip_before_filter :handle_password_change
|
|
3
3
|
prepend_before_filter :authenticate_scope!, :only => [:show, :update]
|
|
4
|
-
include Devise::Controllers::
|
|
4
|
+
include Devise::Controllers::Helpers
|
|
5
5
|
|
|
6
6
|
def show
|
|
7
7
|
if not resource.nil? and resource.need_change_password?
|
|
8
|
-
|
|
8
|
+
render 'devise/password_expired/show'
|
|
9
9
|
else
|
|
10
10
|
redirect_to :root
|
|
11
11
|
end
|
|
@@ -19,7 +19,7 @@ class Devise::PasswordExpiredController < ApplicationController
|
|
|
19
19
|
redirect_to stored_location_for(scope) || :root
|
|
20
20
|
else
|
|
21
21
|
clean_up_passwords(resource)
|
|
22
|
-
|
|
22
|
+
render 'devise/password_expired/show'
|
|
23
23
|
end
|
|
24
24
|
end
|
|
25
25
|
|
|
@@ -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.
|
|
8
|
+
s.version = "0.6.1"
|
|
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 = "
|
|
12
|
+
s.date = "2012-06-06"
|
|
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 = [
|
|
@@ -42,7 +42,11 @@ Gem::Specification.new do |s|
|
|
|
42
42
|
"lib/devise_security_extension/models/session_limitable.rb",
|
|
43
43
|
"lib/devise_security_extension/orm/active_record.rb",
|
|
44
44
|
"lib/devise_security_extension/patches.rb",
|
|
45
|
-
"lib/devise_security_extension/patches/
|
|
45
|
+
"lib/devise_security_extension/patches/confirmations_controller_captcha.rb",
|
|
46
|
+
"lib/devise_security_extension/patches/passwords_controller_captcha.rb",
|
|
47
|
+
"lib/devise_security_extension/patches/registrations_controller_captcha.rb",
|
|
48
|
+
"lib/devise_security_extension/patches/sessions_controller_captcha.rb",
|
|
49
|
+
"lib/devise_security_extension/patches/unlocks_controller_captcha.rb",
|
|
46
50
|
"lib/devise_security_extension/rails.rb",
|
|
47
51
|
"lib/devise_security_extension/routes.rb",
|
|
48
52
|
"lib/devise_security_extension/schema.rb",
|
|
@@ -53,7 +57,7 @@ Gem::Specification.new do |s|
|
|
|
53
57
|
s.homepage = "http://github.com/phatworx/devise_security_extension"
|
|
54
58
|
s.licenses = ["MIT"]
|
|
55
59
|
s.require_paths = ["lib"]
|
|
56
|
-
s.rubygems_version = "1.8.
|
|
60
|
+
s.rubygems_version = "1.8.21"
|
|
57
61
|
s.summary = "Security extension for devise"
|
|
58
62
|
s.test_files = [
|
|
59
63
|
"test/helper.rb",
|
|
@@ -65,14 +69,14 @@ Gem::Specification.new do |s|
|
|
|
65
69
|
|
|
66
70
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
|
67
71
|
s.add_runtime_dependency(%q<rails>, [">= 3.1.1"])
|
|
68
|
-
s.add_runtime_dependency(%q<devise>, [">= 0"])
|
|
72
|
+
s.add_runtime_dependency(%q<devise>, [">= 2.0.0"])
|
|
69
73
|
s.add_development_dependency(%q<rails_email_validator>, [">= 0"])
|
|
70
74
|
s.add_development_dependency(%q<easy_captcha>, [">= 0"])
|
|
71
75
|
s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
|
|
72
76
|
s.add_development_dependency(%q<jeweler>, ["~> 1.5.2"])
|
|
73
77
|
else
|
|
74
78
|
s.add_dependency(%q<rails>, [">= 3.1.1"])
|
|
75
|
-
s.add_dependency(%q<devise>, [">= 0"])
|
|
79
|
+
s.add_dependency(%q<devise>, [">= 2.0.0"])
|
|
76
80
|
s.add_dependency(%q<rails_email_validator>, [">= 0"])
|
|
77
81
|
s.add_dependency(%q<easy_captcha>, [">= 0"])
|
|
78
82
|
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
|
@@ -80,7 +84,7 @@ Gem::Specification.new do |s|
|
|
|
80
84
|
end
|
|
81
85
|
else
|
|
82
86
|
s.add_dependency(%q<rails>, [">= 3.1.1"])
|
|
83
|
-
s.add_dependency(%q<devise>, [">= 0"])
|
|
87
|
+
s.add_dependency(%q<devise>, [">= 2.0.0"])
|
|
84
88
|
s.add_dependency(%q<rails_email_validator>, [">= 0"])
|
|
85
89
|
s.add_dependency(%q<easy_captcha>, [">= 0"])
|
|
86
90
|
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
|
@@ -5,7 +5,7 @@ require 'active_support/ordered_hash'
|
|
|
5
5
|
require 'active_support/concern'
|
|
6
6
|
require 'devise'
|
|
7
7
|
|
|
8
|
-
module Devise
|
|
8
|
+
module Devise
|
|
9
9
|
|
|
10
10
|
# Should the password expire (e.g 3.months)
|
|
11
11
|
mattr_accessor :expire_password_after
|
|
@@ -43,6 +43,10 @@ module Devise # :nodoc:
|
|
|
43
43
|
# captcha integration for unlock form
|
|
44
44
|
mattr_accessor :captcha_for_unlock
|
|
45
45
|
@@captcha_for_unlock = false
|
|
46
|
+
|
|
47
|
+
# captcha integration for confirmation form
|
|
48
|
+
mattr_accessor :captcha_for_confirmation
|
|
49
|
+
@@captcha_for_confirmation = false
|
|
46
50
|
|
|
47
51
|
# Time period for account expiry from last_activity_at
|
|
48
52
|
mattr_accessor :expire_after
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
module DeviseSecurityExtension
|
|
2
|
-
module Controllers
|
|
3
|
-
module Helpers
|
|
2
|
+
module Controllers
|
|
3
|
+
module Helpers
|
|
4
4
|
extend ActiveSupport::Concern
|
|
5
5
|
|
|
6
6
|
included do
|
|
@@ -10,22 +10,18 @@ module DeviseSecurityExtension
|
|
|
10
10
|
module ClassMethods
|
|
11
11
|
# helper for captcha
|
|
12
12
|
def init_recover_password_captcha
|
|
13
|
-
p "init"
|
|
14
|
-
p self.inspect
|
|
15
|
-
|
|
16
13
|
include RecoverPasswordCaptcha
|
|
17
14
|
end
|
|
18
15
|
end
|
|
19
16
|
|
|
20
17
|
module RecoverPasswordCaptcha
|
|
21
18
|
def new
|
|
22
|
-
p "Check here captcha"
|
|
23
19
|
super
|
|
24
20
|
end
|
|
25
21
|
end
|
|
26
22
|
|
|
27
23
|
# controller instance methods
|
|
28
|
-
|
|
24
|
+
|
|
29
25
|
private
|
|
30
26
|
|
|
31
27
|
# lookup if an password change needed
|
|
@@ -60,7 +56,7 @@ module DeviseSecurityExtension
|
|
|
60
56
|
false
|
|
61
57
|
end
|
|
62
58
|
|
|
63
|
-
|
|
59
|
+
|
|
64
60
|
end
|
|
65
61
|
end
|
|
66
62
|
|
|
@@ -18,51 +18,48 @@ module Devise
|
|
|
18
18
|
module Expirable
|
|
19
19
|
extend ActiveSupport::Concern
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
# Tells if the account has expired
|
|
29
|
-
#
|
|
30
|
-
# @return [bool]
|
|
31
|
-
def expired?
|
|
32
|
-
# expired_at set (manually, via cron, etc.)
|
|
33
|
-
return self.expired_at < Time.now.utc unless self.expired_at.nil?
|
|
34
|
-
# if it is not set, check the last activity against configured expire_after time range
|
|
35
|
-
return self.last_activity_at < self.class.expire_after.ago unless self.last_activity_at.nil?
|
|
36
|
-
# if last_activity_at is nil as well, the user has to be 'fresh' and is therefore not expired
|
|
37
|
-
false
|
|
38
|
-
end
|
|
21
|
+
# Updates +last_activity_at+, called from a Warden::Manager.after_set_user hook.
|
|
22
|
+
def update_last_activitiy!
|
|
23
|
+
self.last_activity_at = Time.now.utc
|
|
24
|
+
save(:validate => false)
|
|
25
|
+
end
|
|
39
26
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
#
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
27
|
+
# Tells if the account has expired
|
|
28
|
+
#
|
|
29
|
+
# @return [bool]
|
|
30
|
+
def expired?
|
|
31
|
+
# expired_at set (manually, via cron, etc.)
|
|
32
|
+
return self.expired_at < Time.now.utc unless self.expired_at.nil?
|
|
33
|
+
# if it is not set, check the last activity against configured expire_after time range
|
|
34
|
+
return self.last_activity_at < self.class.expire_after.ago unless self.last_activity_at.nil?
|
|
35
|
+
# if last_activity_at is nil as well, the user has to be 'fresh' and is therefore not expired
|
|
36
|
+
false
|
|
37
|
+
end
|
|
50
38
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
39
|
+
# Expire an account. This is for cron jobs and manually expiring of accounts.
|
|
40
|
+
#
|
|
41
|
+
# @example
|
|
42
|
+
# User.expire!
|
|
43
|
+
# User.expire! 1.week.from_now
|
|
44
|
+
# @note +expired_at+ can be in the future as well
|
|
45
|
+
def expire!(at = Time.now.utc)
|
|
46
|
+
self.expired_at = at
|
|
47
|
+
save(:validate => false)
|
|
48
|
+
end
|
|
59
49
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
50
|
+
# Overwrites active_for_authentication? from Devise::Models::Activatable
|
|
51
|
+
# for verifying whether a user is active to sign in or not. If the account
|
|
52
|
+
# is expired, it should never be allowed.
|
|
53
|
+
#
|
|
54
|
+
# @return [bool]
|
|
55
|
+
def active_for_authentication?
|
|
56
|
+
super && !self.expired?
|
|
57
|
+
end
|
|
65
58
|
|
|
59
|
+
# The message sym, if {#active_for_authentication?} returns +false+. E.g. needed
|
|
60
|
+
# for i18n.
|
|
61
|
+
def inactive_message
|
|
62
|
+
!self.expired? ? super : :expired
|
|
66
63
|
end
|
|
67
64
|
|
|
68
65
|
module ClassMethods
|
|
@@ -1,68 +1,61 @@
|
|
|
1
|
-
module Devise
|
|
2
|
-
module Models
|
|
1
|
+
module Devise
|
|
2
|
+
module Models
|
|
3
3
|
|
|
4
4
|
# PasswordArchivable
|
|
5
5
|
module PasswordArchivable
|
|
6
|
+
extend ActiveSupport::Concern
|
|
6
7
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
include InstanceMethods
|
|
12
|
-
has_many :old_passwords, :as => :password_archivable, :dependent => :destroy
|
|
13
|
-
before_update :archive_password
|
|
14
|
-
validate :validate_password_archive
|
|
15
|
-
end
|
|
8
|
+
included do
|
|
9
|
+
has_many :old_passwords, :as => :password_archivable, :dependent => :destroy
|
|
10
|
+
before_update :archive_password
|
|
11
|
+
validate :validate_password_archive
|
|
16
12
|
end
|
|
17
13
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
self.errors.add(:password, :taken_in_past) if encrypted_password_changed? and password_archive_included?
|
|
22
|
-
end
|
|
14
|
+
def validate_password_archive
|
|
15
|
+
self.errors.add(:password, :taken_in_past) if encrypted_password_changed? and password_archive_included?
|
|
16
|
+
end
|
|
23
17
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
end
|
|
18
|
+
# validate is the password used in the past
|
|
19
|
+
def password_archive_included?
|
|
20
|
+
unless self.class.deny_old_passwords.is_a? Fixnum
|
|
21
|
+
if self.class.deny_old_passwords.is_a? TrueClass and self.class.password_archiving_count > 0
|
|
22
|
+
self.class.deny_old_passwords = self.class.password_archiving_count
|
|
23
|
+
else
|
|
24
|
+
self.class.deny_old_passwords = 0
|
|
32
25
|
end
|
|
26
|
+
end
|
|
33
27
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
end
|
|
28
|
+
if self.class.deny_old_passwords > 0 and not self.password.nil?
|
|
29
|
+
self.old_passwords.reverse_order(:id).limit(self.class.deny_old_passwords).each do |old_password|
|
|
30
|
+
dummy = self.class.new
|
|
31
|
+
dummy.encrypted_password = old_password.encrypted_password
|
|
32
|
+
dummy.password_salt = old_password.password_salt if dummy.respond_to?(:password_salt)
|
|
33
|
+
return true if dummy.valid_password?(self.password)
|
|
41
34
|
end
|
|
42
|
-
|
|
43
|
-
false
|
|
44
35
|
end
|
|
45
36
|
|
|
46
|
-
|
|
37
|
+
false
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
private
|
|
47
41
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
else
|
|
55
|
-
self.old_passwords.create! :encrypted_password => self.encrypted_password_change.first
|
|
56
|
-
end
|
|
57
|
-
self.old_passwords.order('created_at DESC').offset(self.class.password_archiving_count).destroy_all
|
|
42
|
+
# archive the last password before save and delete all to old passwords from archive
|
|
43
|
+
def archive_password
|
|
44
|
+
if self.encrypted_password_changed?
|
|
45
|
+
if self.class.password_archiving_count.to_i > 0
|
|
46
|
+
if self.respond_to?(:password_salt_change) and not self.password_salt_change.nil?
|
|
47
|
+
self.old_passwords.create! :encrypted_password => self.encrypted_password_change.first, :password_salt => self.password_salt_change.first
|
|
58
48
|
else
|
|
59
|
-
self.old_passwords.
|
|
49
|
+
self.old_passwords.create! :encrypted_password => self.encrypted_password_change.first
|
|
60
50
|
end
|
|
51
|
+
self.old_passwords.reverse_order(:id).offset(self.class.password_archiving_count).destroy_all
|
|
52
|
+
else
|
|
53
|
+
self.old_passwords.destroy_all
|
|
61
54
|
end
|
|
62
55
|
end
|
|
63
56
|
end
|
|
64
57
|
|
|
65
|
-
module ClassMethods
|
|
58
|
+
module ClassMethods
|
|
66
59
|
::Devise::Models.config(self, :password_archiving_count, :deny_old_passwords)
|
|
67
60
|
end
|
|
68
61
|
end
|
|
@@ -1,63 +1,57 @@
|
|
|
1
1
|
require 'devise_security_extension/hooks/password_expirable'
|
|
2
2
|
|
|
3
|
-
module Devise
|
|
4
|
-
module Models
|
|
3
|
+
module Devise
|
|
4
|
+
module Models
|
|
5
5
|
|
|
6
6
|
# PasswordExpirable takes care of change password after
|
|
7
7
|
module PasswordExpirable
|
|
8
|
+
extend ActiveSupport::Concern
|
|
8
9
|
|
|
9
|
-
|
|
10
|
-
|
|
10
|
+
included do
|
|
11
|
+
before_save :update_password_changed
|
|
12
|
+
end
|
|
11
13
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
14
|
+
# is an password change required?
|
|
15
|
+
def need_change_password?
|
|
16
|
+
if self.class.expire_password_after.is_a? Fixnum or self.class.expire_password_after.is_a? Float
|
|
17
|
+
self.password_changed_at.nil? or self.password_changed_at < self.class.expire_password_after.ago
|
|
18
|
+
else
|
|
19
|
+
false
|
|
15
20
|
end
|
|
16
21
|
end
|
|
17
22
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
self.password_changed_at.nil? or self.password_changed_at < self.class.expire_password_after.ago
|
|
24
|
-
else
|
|
25
|
-
false
|
|
26
|
-
end
|
|
23
|
+
# set a fake datetime so a password change is needed and save the record
|
|
24
|
+
def need_change_password!
|
|
25
|
+
if self.class.expire_password_after.is_a? Fixnum or self.class.expire_password_after.is_a? Float
|
|
26
|
+
need_change_password
|
|
27
|
+
self.save(:validate => false)
|
|
27
28
|
end
|
|
29
|
+
end
|
|
28
30
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
self.save(:validate => false)
|
|
34
|
-
end
|
|
31
|
+
# set a fake datetime so a password change is needed
|
|
32
|
+
def need_change_password
|
|
33
|
+
if self.class.expire_password_after.is_a? Fixnum or self.class.expire_password_after.is_a? Float
|
|
34
|
+
self.password_changed_at = self.class.expire_password_after.ago
|
|
35
35
|
end
|
|
36
36
|
|
|
37
|
-
# set
|
|
38
|
-
|
|
39
|
-
if self.class.expire_password_after.is_a? Fixnum
|
|
40
|
-
self.password_changed_at = self.class.expire_password_after.ago
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
# is date not set it will set default to need set new password next login
|
|
44
|
-
need_change_password if self.password_changed_at.nil?
|
|
37
|
+
# is date not set it will set default to need set new password next login
|
|
38
|
+
need_change_password if self.password_changed_at.nil?
|
|
45
39
|
|
|
46
|
-
|
|
47
|
-
|
|
40
|
+
self.password_changed_at
|
|
41
|
+
end
|
|
48
42
|
|
|
49
|
-
|
|
43
|
+
private
|
|
50
44
|
|
|
51
45
|
# is password changed then update password_cahanged_at
|
|
52
46
|
def update_password_changed
|
|
53
47
|
self.password_changed_at = Time.now if (self.new_record? or self.encrypted_password_changed?) and not self.password_changed_at_changed?
|
|
54
48
|
end
|
|
55
|
-
end
|
|
56
49
|
|
|
57
|
-
module ClassMethods
|
|
50
|
+
module ClassMethods
|
|
58
51
|
::Devise::Models.config(self, :expire_password_after)
|
|
59
52
|
end
|
|
60
53
|
end
|
|
54
|
+
|
|
61
55
|
end
|
|
62
56
|
|
|
63
57
|
end
|
|
@@ -11,6 +11,7 @@ module Devise
|
|
|
11
11
|
# * +password_regex+: need strong password. Defaults to /(?=.*\d)(?=.*[a-z])(?=.*[A-Z])/
|
|
12
12
|
#
|
|
13
13
|
module SecureValidatable
|
|
14
|
+
|
|
14
15
|
def self.included(base)
|
|
15
16
|
base.extend ClassMethods
|
|
16
17
|
assert_secure_validations_api!(base)
|
|
@@ -22,6 +23,7 @@ module Devise
|
|
|
22
23
|
|
|
23
24
|
# validates email
|
|
24
25
|
validates :email, :presence => true, :if => :email_required?
|
|
26
|
+
validates :email, :uniqueness => true, :allow_blank => true, :if => :email_changed? # check uniq for email ever
|
|
25
27
|
validates :email, :email => email_validation if email_validation # use rails_email_validator or similar
|
|
26
28
|
|
|
27
29
|
# validates password
|
|
@@ -32,7 +34,7 @@ module Devise
|
|
|
32
34
|
end
|
|
33
35
|
end
|
|
34
36
|
|
|
35
|
-
def self.assert_secure_validations_api!(base)
|
|
37
|
+
def self.assert_secure_validations_api!(base)
|
|
36
38
|
raise "Could not use SecureValidatable on #{base}" unless base.respond_to?(:validates)
|
|
37
39
|
end
|
|
38
40
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
require 'devise_security_extension/hooks/session_limitable'
|
|
2
2
|
|
|
3
|
-
module Devise
|
|
4
|
-
module Models
|
|
3
|
+
module Devise
|
|
4
|
+
module Models
|
|
5
5
|
# SessionLimited ensures, that there is only one session usable per account at once.
|
|
6
6
|
# If someone logs in, and some other is logging in with the same credentials,
|
|
7
7
|
# the session from the first one is invalidated and not usable anymore.
|
|
@@ -1,13 +1,18 @@
|
|
|
1
1
|
module DeviseSecurityExtension
|
|
2
2
|
module Patches
|
|
3
|
-
autoload :
|
|
3
|
+
autoload :UnlocksControllerCaptcha, 'devise_security_extension/patches/unlocks_controller_captcha'
|
|
4
|
+
autoload :PasswordsControllerCaptcha, 'devise_security_extension/patches/passwords_controller_captcha'
|
|
5
|
+
autoload :SessionsControllerCaptcha, 'devise_security_extension/patches/sessions_controller_captcha'
|
|
6
|
+
autoload :RegistrationsControllerCaptcha, 'devise_security_extension/patches/registrations_controller_captcha'
|
|
7
|
+
autoload :ConfirmationsControllerCaptcha, 'devise_security_extension/patches/confirmations_controller_captcha'
|
|
4
8
|
|
|
5
9
|
class << self
|
|
6
10
|
def apply
|
|
7
|
-
Devise::PasswordsController.send(:include, Patches::
|
|
8
|
-
Devise::UnlocksController.send(:include, Patches::
|
|
9
|
-
Devise::RegistrationsController.send(:include, Patches::
|
|
10
|
-
Devise::SessionsController.send(:include, Patches::
|
|
11
|
+
Devise::PasswordsController.send(:include, Patches::PasswordsControllerCaptcha) if Devise.captcha_for_recover
|
|
12
|
+
Devise::UnlocksController.send(:include, Patches::UnlocksControllerCaptcha) if Devise.captcha_for_unlock
|
|
13
|
+
Devise::RegistrationsController.send(:include, Patches::RegistrationsControllerCaptcha) if Devise.captcha_for_sign_up
|
|
14
|
+
Devise::SessionsController.send(:include, Patches::SessionsControllerCaptcha) if Devise.captcha_for_sign_in
|
|
15
|
+
Devise::ConfirmationsController.send(:include, Patches::ConfirmationsControllerCaptcha) if Devise.captcha_for_confirmation
|
|
11
16
|
end
|
|
12
17
|
end
|
|
13
18
|
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
module DeviseSecurityExtension::Patches
|
|
2
|
+
module ConfirmationsControllerCaptcha
|
|
3
|
+
extend ActiveSupport::Concern
|
|
4
|
+
included do
|
|
5
|
+
define_method :create do
|
|
6
|
+
if 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,20 @@
|
|
|
1
|
+
module DeviseSecurityExtension::Patches
|
|
2
|
+
module PasswordsControllerCaptcha
|
|
3
|
+
extend ActiveSupport::Concern
|
|
4
|
+
included do
|
|
5
|
+
define_method :create do
|
|
6
|
+
if 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,33 @@
|
|
|
1
|
+
module DeviseSecurityExtension::Patches
|
|
2
|
+
module RegistrationsControllerCaptcha
|
|
3
|
+
extend ActiveSupport::Concern
|
|
4
|
+
included do
|
|
5
|
+
define_method :create do
|
|
6
|
+
build_resource
|
|
7
|
+
|
|
8
|
+
if valid_captcha? params[:captcha]
|
|
9
|
+
|
|
10
|
+
if resource.save
|
|
11
|
+
if resource.active_for_authentication?
|
|
12
|
+
set_flash_message :notice, :signed_up if is_navigational_format?
|
|
13
|
+
sign_in(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_navigational_format?
|
|
17
|
+
expire_session_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,23 @@
|
|
|
1
|
+
module DeviseSecurityExtension::Patches
|
|
2
|
+
module SessionsControllerCaptcha
|
|
3
|
+
extend ActiveSupport::Concern
|
|
4
|
+
included do
|
|
5
|
+
define_method :create do
|
|
6
|
+
if valid_captcha? params[:captcha]
|
|
7
|
+
resource = warden.authenticate!(auth_options)
|
|
8
|
+
set_flash_message(:notice, :signed_in) if is_navigational_format?
|
|
9
|
+
sign_in(resource_name, resource)
|
|
10
|
+
respond_with resource, :location => after_sign_in_path_for(resource)
|
|
11
|
+
else
|
|
12
|
+
flash[:alert] = t('devise.invalid_captcha') if is_navigational_format?
|
|
13
|
+
respond_with({}, :location => new_session_path(resource_name))
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# for bad protected use in controller
|
|
18
|
+
define_method :auth_options do
|
|
19
|
+
{ :scope => resource_name, :recall => "#{controller_path}#new" }
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
module DeviseSecurityExtension::Patches
|
|
2
|
+
module UnlocksControllerCaptcha
|
|
3
|
+
extend ActiveSupport::Concern
|
|
4
|
+
included do
|
|
5
|
+
define_method :create do
|
|
6
|
+
if 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
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
module DeviseSecurityExtension
|
|
2
|
-
module Generators
|
|
2
|
+
module Generators
|
|
3
3
|
# Install Generator
|
|
4
4
|
class InstallGenerator < Rails::Generators::Base
|
|
5
5
|
source_root File.expand_path("../../templates", __FILE__)
|
|
@@ -27,9 +27,10 @@ module DeviseSecurityExtension
|
|
|
27
27
|
" # config.captcha_for_sign_in = true\n\n" +
|
|
28
28
|
" # captcha integration for unlock form\n" +
|
|
29
29
|
" # config.captcha_for_unlock = true\n\n" +
|
|
30
|
-
" #
|
|
30
|
+
" # captcha integration for confirmation form\n" +
|
|
31
|
+
" # config.captcha_for_confirmation = true\n\n" +
|
|
31
32
|
" # Time period for account expiry from last_activity_at\n" +
|
|
32
|
-
" config.expire_after = 90.days\n" +
|
|
33
|
+
" # config.expire_after = 90.days\n\n" +
|
|
33
34
|
"", :before => /end[ |\n|]+\Z/
|
|
34
35
|
end
|
|
35
36
|
|
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.
|
|
4
|
+
version: 0.6.1
|
|
5
5
|
prerelease:
|
|
6
6
|
platform: ruby
|
|
7
7
|
authors:
|
|
@@ -10,11 +10,11 @@ authors:
|
|
|
10
10
|
autorequire:
|
|
11
11
|
bindir: bin
|
|
12
12
|
cert_chain: []
|
|
13
|
-
date:
|
|
13
|
+
date: 2012-06-06 00:00:00.000000000 Z
|
|
14
14
|
dependencies:
|
|
15
15
|
- !ruby/object:Gem::Dependency
|
|
16
16
|
name: rails
|
|
17
|
-
requirement:
|
|
17
|
+
requirement: !ruby/object:Gem::Requirement
|
|
18
18
|
none: false
|
|
19
19
|
requirements:
|
|
20
20
|
- - ! '>='
|
|
@@ -22,21 +22,31 @@ dependencies:
|
|
|
22
22
|
version: 3.1.1
|
|
23
23
|
type: :runtime
|
|
24
24
|
prerelease: false
|
|
25
|
-
version_requirements:
|
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
26
|
+
none: false
|
|
27
|
+
requirements:
|
|
28
|
+
- - ! '>='
|
|
29
|
+
- !ruby/object:Gem::Version
|
|
30
|
+
version: 3.1.1
|
|
26
31
|
- !ruby/object:Gem::Dependency
|
|
27
32
|
name: devise
|
|
28
|
-
requirement:
|
|
33
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
34
|
none: false
|
|
30
35
|
requirements:
|
|
31
36
|
- - ! '>='
|
|
32
37
|
- !ruby/object:Gem::Version
|
|
33
|
-
version:
|
|
38
|
+
version: 2.0.0
|
|
34
39
|
type: :runtime
|
|
35
40
|
prerelease: false
|
|
36
|
-
version_requirements:
|
|
41
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
42
|
+
none: false
|
|
43
|
+
requirements:
|
|
44
|
+
- - ! '>='
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: 2.0.0
|
|
37
47
|
- !ruby/object:Gem::Dependency
|
|
38
48
|
name: rails_email_validator
|
|
39
|
-
requirement:
|
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
|
40
50
|
none: false
|
|
41
51
|
requirements:
|
|
42
52
|
- - ! '>='
|
|
@@ -44,10 +54,15 @@ dependencies:
|
|
|
44
54
|
version: '0'
|
|
45
55
|
type: :development
|
|
46
56
|
prerelease: false
|
|
47
|
-
version_requirements:
|
|
57
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
58
|
+
none: false
|
|
59
|
+
requirements:
|
|
60
|
+
- - ! '>='
|
|
61
|
+
- !ruby/object:Gem::Version
|
|
62
|
+
version: '0'
|
|
48
63
|
- !ruby/object:Gem::Dependency
|
|
49
64
|
name: easy_captcha
|
|
50
|
-
requirement:
|
|
65
|
+
requirement: !ruby/object:Gem::Requirement
|
|
51
66
|
none: false
|
|
52
67
|
requirements:
|
|
53
68
|
- - ! '>='
|
|
@@ -55,10 +70,15 @@ dependencies:
|
|
|
55
70
|
version: '0'
|
|
56
71
|
type: :development
|
|
57
72
|
prerelease: false
|
|
58
|
-
version_requirements:
|
|
73
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
74
|
+
none: false
|
|
75
|
+
requirements:
|
|
76
|
+
- - ! '>='
|
|
77
|
+
- !ruby/object:Gem::Version
|
|
78
|
+
version: '0'
|
|
59
79
|
- !ruby/object:Gem::Dependency
|
|
60
80
|
name: bundler
|
|
61
|
-
requirement:
|
|
81
|
+
requirement: !ruby/object:Gem::Requirement
|
|
62
82
|
none: false
|
|
63
83
|
requirements:
|
|
64
84
|
- - ~>
|
|
@@ -66,10 +86,15 @@ dependencies:
|
|
|
66
86
|
version: 1.0.0
|
|
67
87
|
type: :development
|
|
68
88
|
prerelease: false
|
|
69
|
-
version_requirements:
|
|
89
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
90
|
+
none: false
|
|
91
|
+
requirements:
|
|
92
|
+
- - ~>
|
|
93
|
+
- !ruby/object:Gem::Version
|
|
94
|
+
version: 1.0.0
|
|
70
95
|
- !ruby/object:Gem::Dependency
|
|
71
96
|
name: jeweler
|
|
72
|
-
requirement:
|
|
97
|
+
requirement: !ruby/object:Gem::Requirement
|
|
73
98
|
none: false
|
|
74
99
|
requirements:
|
|
75
100
|
- - ~>
|
|
@@ -77,7 +102,12 @@ dependencies:
|
|
|
77
102
|
version: 1.5.2
|
|
78
103
|
type: :development
|
|
79
104
|
prerelease: false
|
|
80
|
-
version_requirements:
|
|
105
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
106
|
+
none: false
|
|
107
|
+
requirements:
|
|
108
|
+
- - ~>
|
|
109
|
+
- !ruby/object:Gem::Version
|
|
110
|
+
version: 1.5.2
|
|
81
111
|
description: An enterprise security extension for devise, trying to meet industrial
|
|
82
112
|
standard security demands for web applications.
|
|
83
113
|
email: team@phatworx.de
|
|
@@ -112,7 +142,11 @@ files:
|
|
|
112
142
|
- lib/devise_security_extension/models/session_limitable.rb
|
|
113
143
|
- lib/devise_security_extension/orm/active_record.rb
|
|
114
144
|
- lib/devise_security_extension/patches.rb
|
|
115
|
-
- lib/devise_security_extension/patches/
|
|
145
|
+
- lib/devise_security_extension/patches/confirmations_controller_captcha.rb
|
|
146
|
+
- lib/devise_security_extension/patches/passwords_controller_captcha.rb
|
|
147
|
+
- lib/devise_security_extension/patches/registrations_controller_captcha.rb
|
|
148
|
+
- lib/devise_security_extension/patches/sessions_controller_captcha.rb
|
|
149
|
+
- lib/devise_security_extension/patches/unlocks_controller_captcha.rb
|
|
116
150
|
- lib/devise_security_extension/rails.rb
|
|
117
151
|
- lib/devise_security_extension/routes.rb
|
|
118
152
|
- lib/devise_security_extension/schema.rb
|
|
@@ -134,7 +168,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
134
168
|
version: '0'
|
|
135
169
|
segments:
|
|
136
170
|
- 0
|
|
137
|
-
hash: -
|
|
171
|
+
hash: -3249260859492066288
|
|
138
172
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
139
173
|
none: false
|
|
140
174
|
requirements:
|
|
@@ -143,7 +177,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
143
177
|
version: '0'
|
|
144
178
|
requirements: []
|
|
145
179
|
rubyforge_project:
|
|
146
|
-
rubygems_version: 1.8.
|
|
180
|
+
rubygems_version: 1.8.21
|
|
147
181
|
signing_key:
|
|
148
182
|
specification_version: 3
|
|
149
183
|
summary: Security extension for devise
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
module DeviseSecurityExtension::Patches
|
|
2
|
-
# patch passwords controller for captcha
|
|
3
|
-
module ControllerCaptcha
|
|
4
|
-
extend ActiveSupport::Concern
|
|
5
|
-
included do
|
|
6
|
-
# here the patch
|
|
7
|
-
|
|
8
|
-
alias_method :create_without_captcha_check, :create
|
|
9
|
-
define_method :create do
|
|
10
|
-
if valid_captcha? params[:captcha]
|
|
11
|
-
create_without_captcha_check
|
|
12
|
-
else
|
|
13
|
-
build_resource
|
|
14
|
-
clean_up_passwords(resource)
|
|
15
|
-
flash[:alert] = I18n.translate('devise.invalid_captcha')
|
|
16
|
-
render_with_scope :new
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
end
|