devise_password_history 0.1.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -1,4 +1,10 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- # Specify your gem's dependencies in devise_password_history.gemspec
4
3
  gemspec
4
+
5
+ group :test do
6
+ gem "rake"
7
+ gem "turn"
8
+ gem "mocha"
9
+ gem "minitest"
10
+ end
data/README.md CHANGED
@@ -30,6 +30,7 @@ That generator will do three things:
30
30
  1. Modifies the `config/initializers/devise.rb` file with two new config options:
31
31
  - `config.deny_old_passwords`: turns the validations on/off
32
32
  - `config.password_history_count`: the threshold of how many passwords to store
33
+ - `config.password_age`: ability to force password expiration (ex: `90.days`)
33
34
  2. Creates an `OldPassword` polymorphic model in `app/models`
34
35
  3. Creates the migration for the `old_passwords` table
35
36
 
@@ -44,6 +45,30 @@ any of the other extensions:
44
45
  devise :database_authenticatable, :password_history
45
46
  end
46
47
 
48
+ ## Notes on Password Age/Expiration
49
+
50
+ By default, the `password_age` is set to `nil` (which turns this feature off).
51
+ If you want to use it, set it to how often you want passwords to expire, an
52
+ example might be `90.days`.
53
+
54
+ If a password has expired, the user will be redirected to a
55
+ `update_password_path` route, which defaults to `edit_admin_user_path(current_user)`.
56
+ You can override this in `ApplicationController` as needed.
57
+
58
+ class ApplicationController
59
+ # ...
60
+
61
+ protected
62
+ def update_password_path
63
+ your_custom_route_goes_here_path
64
+ end
65
+ end
66
+
67
+ Additionally, the filter that runs to check expired passwords is
68
+ `check_password_expiration`. To prevent this filter from running on the
69
+ controller that does the password updates, you should
70
+ `skip_before_filter :check_password_expiration`.
71
+
47
72
  ## Contributing
48
73
 
49
74
  1. Fork it
@@ -10,7 +10,7 @@ Gem::Specification.new do |gem|
10
10
  gem.email = ["ryan@rpheath.com"]
11
11
  gem.description = %q{Maintains password history and ensures old passwords aren't reused}
12
12
  gem.summary = %q{Password history support for devise}
13
- gem.homepage = ""
13
+ gem.homepage = "http://github.com/rpheath/devise_password_history"
14
14
 
15
15
  gem.add_dependency("devise", ["~> 2.2.0"])
16
16
 
@@ -0,0 +1,41 @@
1
+ module DevisePasswordHistory
2
+ module Controllers
3
+ module Helpers
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ append_before_filter :check_password_expiration
8
+ end
9
+
10
+ protected
11
+ def check_password_expiration
12
+ # skip if we don't have a user
13
+ return if current_user.blank?
14
+ # skip if we're on the controller that needs
15
+ # to update the passwords (infinite loop otherwise)
16
+ return if self.class.to_s == update_password_controller.to_s
17
+
18
+ if current_user.has_password_expired?
19
+ flash[:alert] = expired_password_message
20
+ redirect_to update_password_path
21
+ end
22
+ end
23
+
24
+ # path to update passwords (can be overridden)
25
+ def update_password_path
26
+ edit_admin_user_path(current_user)
27
+ end
28
+
29
+ # the controller that handles password
30
+ # updating (can be overridden)
31
+ def update_password_controller
32
+ "Admin::UsersController"
33
+ end
34
+
35
+ # flash message
36
+ def expired_password_message
37
+ "Your password has expired, please choose a new one"
38
+ end
39
+ end
40
+ end
41
+ end
@@ -20,6 +20,8 @@ module DevisePasswordHistory
20
20
  " config.password_history_count = 8\n\n" +
21
21
  " # Toggles behavior for Deny/Allow old passwords\n" +
22
22
  " config.deny_old_passwords = true\n\n" +
23
+ " # Repeatedly forces a new password based on this age\n" +
24
+ " # config.password_age = 90.days\n\n" +
23
25
  "", :before => /end[\s|\n|]+\Z/
24
26
  end
25
27
 
@@ -6,7 +6,7 @@ module Devise
6
6
  extend ActiveSupport::Concern
7
7
 
8
8
  module ClassMethods
9
- Devise::Models.config(self, :password_history_count, :deny_old_passwords)
9
+ Devise::Models.config(self, :password_history_count, :deny_old_passwords, :password_age)
10
10
  end
11
11
 
12
12
  included do
@@ -45,6 +45,32 @@ module Devise
45
45
  false
46
46
  end
47
47
 
48
+ def has_password_expired?
49
+ # make sure this feature is turned on
50
+ return false if self.class.password_age.nil?
51
+
52
+ # initializing to ensure expired_stamp
53
+ # exists in case conditions fail below
54
+ expired_stamp = Time.now
55
+
56
+ if self.old_passwords.present?
57
+ # since we are tracking old passwords, we can get the
58
+ # last time the password was changed
59
+ password_changed_at = self.old_passwords.order(:created_at).last.created_at
60
+ # our expired stamp is the password age past the last password change
61
+ expired_stamp = password_changed_at + self.class.password_age
62
+ else
63
+ # if no old passwords exist yet, we can check against
64
+ # when the user was created and use that timestamp
65
+ if self.respond_to?(:created_at)
66
+ expired_stamp = self.created_at + self.class.password_age
67
+ end
68
+ end
69
+
70
+ # are we expired?
71
+ !!(Time.now > expired_stamp)
72
+ end
73
+
48
74
  protected
49
75
  # make sure this is turned on in the Devise config
50
76
  def should_deny_old_passwords?
@@ -0,0 +1,7 @@
1
+ module DevisePasswordHistory
2
+ class Engine < Rails::Engine
3
+ ActiveSupport.on_load(:action_controller) do
4
+ include DevisePasswordHistory::Controllers::Helpers
5
+ end
6
+ end
7
+ end
@@ -1,3 +1,3 @@
1
1
  module DevisePasswordHistory
2
- VERSION = "0.1.2"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -14,9 +14,19 @@ module Devise
14
14
  # Toggles the behavior of denying/allowing old passwords
15
15
  mattr_accessor :deny_old_passwords
16
16
  @@deny_old_passwords = true
17
+
18
+ # Repeatedly forces a new password based on this age
19
+ mattr_accessor :password_age
20
+ @@password_age = nil
17
21
  end
18
22
 
19
- module DevisePasswordHistory; end
23
+ module DevisePasswordHistory
24
+ module Controllers
25
+ autoload :Helpers, "devise_password_history/controllers/helpers"
26
+ end
27
+ end
20
28
 
21
29
  # makes this module available to the `devise` command
22
- Devise.add_module :password_history, :model => "devise_password_history/models/password_history"
30
+ Devise.add_module :password_history, :model => "devise_password_history/models/password_history"
31
+
32
+ require "devise_password_history/rails"
@@ -0,0 +1,9 @@
1
+ require "test/unit"
2
+ require "mocha/setup"
3
+ require "turn"
4
+
5
+ Test::Unit::TestCase.class_eval do
6
+ def self.test(name, &block)
7
+ define_method("test_#{name.to_s.gsub(/\W/,'_')}", &block) if block_given?
8
+ end
9
+ end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: devise_password_history
3
3
  version: !ruby/object:Gem::Version
4
- hash: 31
4
+ hash: 23
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
- - 1
9
8
  - 2
10
- version: 0.1.2
9
+ - 0
10
+ version: 0.2.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Ryan Heath
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2014-01-14 00:00:00 -05:00
18
+ date: 2014-01-25 00:00:00 -05:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -51,13 +51,16 @@ files:
51
51
  - Rakefile
52
52
  - devise_password_history.gemspec
53
53
  - lib/devise_password_history.rb
54
+ - lib/devise_password_history/controllers/helpers.rb
54
55
  - lib/devise_password_history/generators/install_generator.rb
55
56
  - lib/devise_password_history/generators/templates/migrations/create_old_passwords.rb
56
57
  - lib/devise_password_history/generators/templates/models/old_password.rb
57
58
  - lib/devise_password_history/models/password_history.rb
59
+ - lib/devise_password_history/rails.rb
58
60
  - lib/devise_password_history/version.rb
61
+ - test/test_helper.rb
59
62
  has_rdoc: true
60
- homepage: ""
63
+ homepage: http://github.com/rpheath/devise_password_history
61
64
  licenses: []
62
65
 
63
66
  post_install_message:
@@ -90,5 +93,5 @@ rubygems_version: 1.6.2
90
93
  signing_key:
91
94
  specification_version: 3
92
95
  summary: Password history support for devise
93
- test_files: []
94
-
96
+ test_files:
97
+ - test/test_helper.rb