devise_security_extension 0.1.0 → 0.2.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/Gemfile +1 -0
- data/Gemfile.lock +4 -0
- data/README.rdoc +12 -3
- data/VERSION +1 -1
- data/devise_security_extension.gemspec +6 -2
- data/lib/devise_security_extension.rb +6 -1
- data/lib/devise_security_extension/models/secure_validatable.rb +55 -0
- data/lib/generators/devise_security_extension/install_generator.rb +4 -1
- metadata +24 -10
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -62,6 +62,9 @@ GEM
|
|
62
62
|
activesupport (= 3.0.3)
|
63
63
|
bundler (~> 1.0)
|
64
64
|
railties (= 3.0.3)
|
65
|
+
rails_email_validator (0.1.1)
|
66
|
+
activemodel (>= 3.0.0)
|
67
|
+
activemodel (>= 3.0.0)
|
65
68
|
railties (3.0.3)
|
66
69
|
actionpack (= 3.0.3)
|
67
70
|
activesupport (= 3.0.3)
|
@@ -84,4 +87,5 @@ DEPENDENCIES
|
|
84
87
|
devise
|
85
88
|
jeweler (~> 1.5.2)
|
86
89
|
rails
|
90
|
+
rails_email_validator
|
87
91
|
rcov
|
data/README.rdoc
CHANGED
@@ -12,10 +12,18 @@ after bundle execute
|
|
12
12
|
== Configuration
|
13
13
|
|
14
14
|
Devise.setup do |config|
|
15
|
-
# Should the password expire
|
16
|
-
# config.expire_password_after =
|
15
|
+
# Should the password expire
|
16
|
+
# config.expire_password_after = 3.months
|
17
|
+
|
18
|
+
# Need 1 char of A-Z, a-z and 0-9
|
19
|
+
# config.password_regex = /(?=.*\d)(?=.*[a-z])(?=.*[A-Z])/
|
17
20
|
end
|
18
21
|
|
22
|
+
== Model modules
|
23
|
+
|
24
|
+
* :password_expirable - activate that passwords will expire
|
25
|
+
* :secure_validatable - better way to validate model. don't use with :validatable!!!
|
26
|
+
|
19
27
|
== Requirements
|
20
28
|
|
21
29
|
* devise (https://github.com/plataformatec/devise)
|
@@ -24,10 +32,10 @@ after bundle execute
|
|
24
32
|
== Features
|
25
33
|
|
26
34
|
* expire passwords (update password with current password)
|
35
|
+
* strong password validation
|
27
36
|
|
28
37
|
== Todo
|
29
38
|
|
30
|
-
* password rules
|
31
39
|
* easy_captcha for registration
|
32
40
|
* easy_captcha for password forgotten
|
33
41
|
* easy_captcha for unlock instructions
|
@@ -35,6 +43,7 @@ after bundle execute
|
|
35
43
|
|
36
44
|
== History
|
37
45
|
* 0.1 expire passwords
|
46
|
+
* 0.2 strong password validation
|
38
47
|
|
39
48
|
== Maintainers
|
40
49
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.2.0
|
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{devise_security_extension}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.2.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"]
|
12
|
-
s.date = %q{2011-01
|
12
|
+
s.date = %q{2011-02-01}
|
13
13
|
s.description = %q{a gem for extend devise for more password security}
|
14
14
|
s.email = %q{develop@marco-scholl.de}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -33,6 +33,7 @@ Gem::Specification.new do |s|
|
|
33
33
|
"lib/devise_security_extension/controllers/helpers.rb",
|
34
34
|
"lib/devise_security_extension/hooks/password_expirable.rb",
|
35
35
|
"lib/devise_security_extension/models/password_expirable.rb",
|
36
|
+
"lib/devise_security_extension/models/secure_validatable.rb",
|
36
37
|
"lib/devise_security_extension/rails.rb",
|
37
38
|
"lib/devise_security_extension/routes.rb",
|
38
39
|
"lib/devise_security_extension/schema.rb",
|
@@ -57,12 +58,14 @@ Gem::Specification.new do |s|
|
|
57
58
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
58
59
|
s.add_runtime_dependency(%q<rails>, [">= 0"])
|
59
60
|
s.add_runtime_dependency(%q<devise>, [">= 0"])
|
61
|
+
s.add_runtime_dependency(%q<rails_email_validator>, [">= 0"])
|
60
62
|
s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
|
61
63
|
s.add_development_dependency(%q<jeweler>, ["~> 1.5.2"])
|
62
64
|
s.add_development_dependency(%q<rcov>, [">= 0"])
|
63
65
|
else
|
64
66
|
s.add_dependency(%q<rails>, [">= 0"])
|
65
67
|
s.add_dependency(%q<devise>, [">= 0"])
|
68
|
+
s.add_dependency(%q<rails_email_validator>, [">= 0"])
|
66
69
|
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
67
70
|
s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
|
68
71
|
s.add_dependency(%q<rcov>, [">= 0"])
|
@@ -70,6 +73,7 @@ Gem::Specification.new do |s|
|
|
70
73
|
else
|
71
74
|
s.add_dependency(%q<rails>, [">= 0"])
|
72
75
|
s.add_dependency(%q<devise>, [">= 0"])
|
76
|
+
s.add_dependency(%q<rails_email_validator>, [">= 0"])
|
73
77
|
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
74
78
|
s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
|
75
79
|
s.add_dependency(%q<rcov>, [">= 0"])
|
@@ -10,7 +10,11 @@ module Devise # :nodoc:
|
|
10
10
|
|
11
11
|
# expire password after e.g 1.year
|
12
12
|
mattr_accessor :expire_password_after
|
13
|
-
@@expire_password_after =
|
13
|
+
@@expire_password_after = 3.months
|
14
|
+
|
15
|
+
# validate password for strongness
|
16
|
+
mattr_accessor :password_regex
|
17
|
+
@@password_regex = /(?=.*\d)(?=.*[a-z])(?=.*[A-Z])/
|
14
18
|
|
15
19
|
end
|
16
20
|
|
@@ -20,3 +24,4 @@ module DeviseSecurityExtension
|
|
20
24
|
end
|
21
25
|
|
22
26
|
Devise.add_module :password_expirable, :controller => :password_expirable, :model => 'devise_security_extension/models/password_expirable', :route => :password_expired
|
27
|
+
Devise.add_module :secure_validatable, :model => 'devise_security_extension/models/secure_validatable'
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module Devise
|
2
|
+
module Models
|
3
|
+
# SecureValidatable creates better validations with more validation for security
|
4
|
+
#
|
5
|
+
# == Options
|
6
|
+
#
|
7
|
+
# SecureValidatable adds the following options to devise_for:
|
8
|
+
#
|
9
|
+
# * +email_regexp+: the regular expression used to validate e-mails;
|
10
|
+
# * +password_length+: a range expressing password length. Defaults from devise
|
11
|
+
# * +password_regex+: need strong password. Defaults to /(?=.*\d)(?=.*[a-z])(?=.*[A-Z])/
|
12
|
+
#
|
13
|
+
module SecureValidatable
|
14
|
+
|
15
|
+
def self.included(base)
|
16
|
+
base.extend ClassMethods
|
17
|
+
assert_secure_validations_api!(base)
|
18
|
+
|
19
|
+
base.class_eval do
|
20
|
+
|
21
|
+
# uniq login
|
22
|
+
validates authentication_keys[0], :uniqueness => {:scope => authentication_keys[1..-1]}#, :case_sensitive => case_insensitive_keys.exclude?(authentication_keys[0])
|
23
|
+
|
24
|
+
# validates email
|
25
|
+
validates :email, :presence => true, :if => :email_required?
|
26
|
+
validates :email, :email => true # use rails_email_validator
|
27
|
+
|
28
|
+
# validates password
|
29
|
+
validates :password, :presence => true, :length => password_length, :format => password_regex, :confirmation => true, :if => :password_required?
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.assert_secure_validations_api!(base) #:nodoc:
|
34
|
+
raise "Could not use SecureValidatable on #{base}" unless base.respond_to?(:validates)
|
35
|
+
end
|
36
|
+
|
37
|
+
protected
|
38
|
+
|
39
|
+
# Checks whether a password is needed or not. For validations only.
|
40
|
+
# Passwords are always required if it's a new record, or if the password
|
41
|
+
# or confirmation are being set somewhere.
|
42
|
+
def password_required?
|
43
|
+
!persisted? || !password.nil? || !password_confirmation.nil?
|
44
|
+
end
|
45
|
+
|
46
|
+
def email_required?
|
47
|
+
true
|
48
|
+
end
|
49
|
+
|
50
|
+
module ClassMethods
|
51
|
+
Devise::Models.config(self, :password_regex, :password_length)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -7,7 +7,10 @@ module DeviseSecurityExtension
|
|
7
7
|
desc "Install the devise security extension"
|
8
8
|
|
9
9
|
def add_configs
|
10
|
-
inject_into_file "config/initializers/devise.rb", "\n\n # ==> Security Extension\n # Configure security extension for devise\n\n
|
10
|
+
inject_into_file "config/initializers/devise.rb", "\n\n # ==> Security Extension\n # Configure security extension for devise\n\n" +
|
11
|
+
" # Should the password expire (e.g 3.months)\n # config.expire_password_after = false\n" +
|
12
|
+
" # Need 1 char of A-Z, a-z and 0-9\n # config.password_regex = /(?=.*\\d)(?=.*[a-z])(?=.*[A-Z])/\n" +
|
13
|
+
"\n", :before => /end[ |\n|]+\Z/
|
11
14
|
end
|
12
15
|
|
13
16
|
def copy_locale
|
metadata
CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 0
|
7
|
-
-
|
7
|
+
- 2
|
8
8
|
- 0
|
9
|
-
version: 0.
|
9
|
+
version: 0.2.0
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Marco Scholl
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2011-01
|
17
|
+
date: 2011-02-01 00:00:00 +01:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -44,8 +44,21 @@ dependencies:
|
|
44
44
|
prerelease: false
|
45
45
|
version_requirements: *id002
|
46
46
|
- !ruby/object:Gem::Dependency
|
47
|
-
name:
|
47
|
+
name: rails_email_validator
|
48
48
|
requirement: &id003 !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
segments:
|
54
|
+
- 0
|
55
|
+
version: "0"
|
56
|
+
type: :runtime
|
57
|
+
prerelease: false
|
58
|
+
version_requirements: *id003
|
59
|
+
- !ruby/object:Gem::Dependency
|
60
|
+
name: bundler
|
61
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
49
62
|
none: false
|
50
63
|
requirements:
|
51
64
|
- - ~>
|
@@ -57,10 +70,10 @@ dependencies:
|
|
57
70
|
version: 1.0.0
|
58
71
|
type: :development
|
59
72
|
prerelease: false
|
60
|
-
version_requirements: *
|
73
|
+
version_requirements: *id004
|
61
74
|
- !ruby/object:Gem::Dependency
|
62
75
|
name: jeweler
|
63
|
-
requirement: &
|
76
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
64
77
|
none: false
|
65
78
|
requirements:
|
66
79
|
- - ~>
|
@@ -72,10 +85,10 @@ dependencies:
|
|
72
85
|
version: 1.5.2
|
73
86
|
type: :development
|
74
87
|
prerelease: false
|
75
|
-
version_requirements: *
|
88
|
+
version_requirements: *id005
|
76
89
|
- !ruby/object:Gem::Dependency
|
77
90
|
name: rcov
|
78
|
-
requirement: &
|
91
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
79
92
|
none: false
|
80
93
|
requirements:
|
81
94
|
- - ">="
|
@@ -85,7 +98,7 @@ dependencies:
|
|
85
98
|
version: "0"
|
86
99
|
type: :development
|
87
100
|
prerelease: false
|
88
|
-
version_requirements: *
|
101
|
+
version_requirements: *id006
|
89
102
|
description: a gem for extend devise for more password security
|
90
103
|
email: develop@marco-scholl.de
|
91
104
|
executables: []
|
@@ -112,6 +125,7 @@ files:
|
|
112
125
|
- lib/devise_security_extension/controllers/helpers.rb
|
113
126
|
- lib/devise_security_extension/hooks/password_expirable.rb
|
114
127
|
- lib/devise_security_extension/models/password_expirable.rb
|
128
|
+
- lib/devise_security_extension/models/secure_validatable.rb
|
115
129
|
- lib/devise_security_extension/rails.rb
|
116
130
|
- lib/devise_security_extension/routes.rb
|
117
131
|
- lib/devise_security_extension/schema.rb
|
@@ -132,7 +146,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
132
146
|
requirements:
|
133
147
|
- - ">="
|
134
148
|
- !ruby/object:Gem::Version
|
135
|
-
hash:
|
149
|
+
hash: -2724377088242008292
|
136
150
|
segments:
|
137
151
|
- 0
|
138
152
|
version: "0"
|