devise_password_expirable 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ data.tar.gz: 580d34c38ff0183b3a09f42988a1c77441df2945
4
+ metadata.gz: 55c8b247f7f7a72167a97d4d5320bbc86d05271d
5
+ SHA512:
6
+ data.tar.gz: 37da798f6da4020241ad192e3d1c0f7bb644dfcc6b63e8167b345c31dccb32627221dadbaf515e0240a6fafa79a7de50a7c4ce93d3462f369838b6ad4c59f0e7
7
+ metadata.gz: aade38df02cfb36229bb7c4993786e1e6fdfe9cc4b73f88bb517bd103551515e0d222e102003eeb485a0ffff31a412750380f0d7001a93a51bd89b4474c18e24
@@ -0,0 +1,20 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+
6
+ # Temporary files of every sort
7
+ .DS_Store
8
+ .idea
9
+ .rvmrc
10
+ .stgit*
11
+ *.swap
12
+ *.swo
13
+ *.swp
14
+ *~
15
+ bin/*
16
+ nbproject
17
+ patches-*
18
+ capybara-*.html
19
+ dump.rdb
20
+ *.ids
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in devise_ip_filter.gemspec
4
+ gemspec
5
+ gem "rails"
6
+ gem "devise"
@@ -0,0 +1,3 @@
1
+ ## Expire passwords plugin for Devise
2
+
3
+ This plugin expires user passwords after a set time period.
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,38 @@
1
+ class Devise::PasswordExpiredController < DeviseController
2
+ skip_before_filter :handle_password_change
3
+ prepend_before_filter :authenticate_scope!, :only => [:show, :update]
4
+
5
+ def show
6
+ if not resource.nil? and resource.need_change_password?
7
+ respond_with(resource)
8
+ else
9
+ redirect_to :root
10
+ end
11
+ end
12
+
13
+ def update
14
+ if resource.update_with_password(resource_params)
15
+ warden.session(scope)[:password_expired] = false
16
+ set_flash_message :notice, :updated
17
+ sign_in scope, resource, :bypass => true
18
+ redirect_to stored_location_for(scope) || :root
19
+ else
20
+ clean_up_passwords(resource)
21
+ respond_with(resource, action: :show)
22
+ end
23
+ end
24
+
25
+ private
26
+ def resource_params
27
+ params.require(resource_name).permit!
28
+ end
29
+
30
+ def scope
31
+ resource_name.to_sym
32
+ end
33
+
34
+ def authenticate_scope!
35
+ send(:"authenticate_#{resource_name}!")
36
+ self.resource = send("current_#{resource_name}")
37
+ end
38
+ end
@@ -0,0 +1,16 @@
1
+ <h2>Renew your password</h2>
2
+
3
+ <%= form_for(resource, :as => resource_name, :url => [resource_name, :password_expired], :html => { :method => :put }) do |f| %>
4
+ <%= devise_error_messages! %>
5
+
6
+ <p><%= f.label :current_password, "Current password" %><br />
7
+ <%= f.password_field :current_password %></p>
8
+
9
+ <p><%= f.label :password, "New password" %><br />
10
+ <%= f.password_field :password %></p>
11
+
12
+ <p><%= f.label :password_confirmation, "Confirm new password" %><br />
13
+ <%= f.password_field :password_confirmation %></p>
14
+
15
+ <p><%= f.submit "Change my password" %></p>
16
+ <% end %>
@@ -0,0 +1,9 @@
1
+ en:
2
+ errors:
3
+ messages:
4
+ equal_to_current_password: "must be different to the current password!"
5
+ password_format: "must contain at least 1 uppercase letter, 1 lowercase letter, and a number."
6
+ devise:
7
+ password_expired:
8
+ updated: "Your new password is saved."
9
+ change_required: "Your password is expired. Please renew your password!"
@@ -0,0 +1,26 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "devise_password_expirable/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "devise_password_expirable"
7
+ s.version = DevisePasswordExpirable::VERSION.dup
8
+ s.authors = ["Jenni Kissinger"]
9
+ s.email = ["jkissinger@carekinesis.com"]
10
+ s.homepage = "https://github.com/jenjaina/devise_password_expirable"
11
+ s.licenses = ["MIT"]
12
+ s.summary = %q{Expire passwords plugin for devise}
13
+ s.description = "An extension to devise that will expire user passwords after a set amount of time and prompt them to update their password."
14
+
15
+ # s.rubyforge_project = "devise_password_expirable"
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.require_paths = ["lib"]
21
+
22
+ s.add_runtime_dependency 'rails', '3.0.20'
23
+ s.add_runtime_dependency 'devise', '1.1.3'
24
+
25
+ s.add_development_dependency 'bundler'
26
+ end
@@ -0,0 +1,32 @@
1
+ require 'devise_password_expirable/version'
2
+ require 'active_record'
3
+ require 'active_support/core_ext/integer'
4
+ require 'active_support/ordered_hash'
5
+ require 'active_support/concern'
6
+ require 'devise'
7
+
8
+ module Devise
9
+ # Should the password expire (e.g 3.months)
10
+ mattr_accessor :expire_password_after
11
+ @@expire_password_after = 3.months
12
+
13
+ # Validate password for strongness
14
+ mattr_accessor :password_regex
15
+ @@password_regex = /^\w*(?=\w*\d)(?=\w*[a-z])(?=\w*[A-Z])\w*$/
16
+ end
17
+
18
+ # an security extension for devise
19
+ module DevisePasswordExpirable
20
+ autoload :Schema, 'devise_password_expirable/schema'
21
+
22
+ module Controllers
23
+ autoload :Helpers, 'devise_password_expirable/controllers/helpers'
24
+ end
25
+ end
26
+
27
+ # modules
28
+ Devise.add_module :password_expirable, :controller => :password_expirable, :model => 'devise_password_expirable/models/password_expirable', :route => :password_expired
29
+
30
+ # requires
31
+ require 'devise_password_expirable/routes'
32
+ require 'devise_password_expirable/rails'
@@ -0,0 +1,50 @@
1
+ module DevisePasswordExpirable
2
+ module Controllers
3
+ module Helpers
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ before_filter :handle_password_change
8
+ end
9
+
10
+ # controller instance methods
11
+
12
+ private
13
+
14
+ # lookup if an password change needed
15
+ def handle_password_change
16
+ if not devise_controller? and not ignore_password_expire? and not request.format.nil? and request.format.html?
17
+ Devise.mappings.keys.flatten.any? do |scope|
18
+ if signed_in?(scope) and warden.session(scope)['password_expired']
19
+ session["#{scope}_return_to"] = request.path if request.get?
20
+ redirect_for_password_change scope
21
+ return
22
+ end
23
+ end
24
+ end
25
+ end
26
+
27
+ # redirect for password update with alert message
28
+ def redirect_for_password_change(scope)
29
+ redirect_to change_password_required_path_for(scope), :alert => I18n.t('change_required', {:scope => 'devise.password_expired'})
30
+ end
31
+
32
+ # path for change password
33
+ def change_password_required_path_for(resource_or_scope = nil)
34
+ scope = Devise::Mapping.find_scope!(resource_or_scope)
35
+ change_path = "#{scope}_password_expired_path"
36
+ send(change_path)
37
+ end
38
+
39
+ protected
40
+
41
+ # allow to overwrite for some special handlings
42
+ def ignore_password_expire?
43
+ false
44
+ end
45
+
46
+
47
+ end
48
+ end
49
+
50
+ end
@@ -0,0 +1,5 @@
1
+ Warden::Manager.after_authentication do |record, warden, options|
2
+ if record.respond_to?(:need_change_password?)
3
+ warden.session(options[:scope])['password_expired'] = record.need_change_password?
4
+ end
5
+ end
@@ -0,0 +1,57 @@
1
+ require 'devise_password_expirable/hooks/password_expirable'
2
+
3
+ module Devise
4
+ module Models
5
+
6
+ # PasswordExpirable takes care of change password after
7
+ module PasswordExpirable
8
+ extend ActiveSupport::Concern
9
+
10
+ included do
11
+ before_save :update_password_changed
12
+ end
13
+
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.last_password_reset.nil? or self.last_password_reset < self.class.expire_password_after.ago
18
+ else
19
+ false
20
+ end
21
+ end
22
+
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)
28
+ end
29
+ end
30
+
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.last_password_reset = self.class.expire_password_after.ago
35
+ end
36
+
37
+ # is date not set it will set default to need set new password next login
38
+ need_change_password if self.last_password_reset.nil?
39
+
40
+ self.last_password_reset
41
+ end
42
+
43
+ private
44
+
45
+ # is password changed then update password_cahanged_at
46
+ def update_password_changed
47
+ self.last_password_reset = Time.now if (self.new_record? or self.encrypted_password_changed?) and not self.last_password_reset_changed?
48
+ end
49
+
50
+ module ClassMethods
51
+ ::Devise::Models.config(self, :expire_password_after)
52
+ end
53
+ end
54
+
55
+ end
56
+
57
+ end
@@ -0,0 +1,7 @@
1
+ module DevisePasswordExpirable
2
+ class Engine < ::Rails::Engine
3
+ ActiveSupport.on_load(:action_controller) do
4
+ include DevisePasswordExpirable::Controllers::Helpers
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,13 @@
1
+ module ActionDispatch::Routing
2
+ class Mapper
3
+
4
+ protected
5
+
6
+ # route for handle expired passwords
7
+ def devise_password_expired(mapping, controllers)
8
+ resource :password_expired, :only => [:show, :update], :path => mapping.path_names[:password_expired], :controller => controllers[:password_expired]
9
+ end
10
+
11
+ end
12
+ end
13
+
@@ -0,0 +1,24 @@
1
+ module DevisePasswordExpirable
2
+ # add schema helper for migrations
3
+ module Schema
4
+ # Add last_password_reset columns in the resource's database table.
5
+ #
6
+ # Examples
7
+ #
8
+ # # For a new resource migration:
9
+ # create_table :the_resources do |t|
10
+ # t.password_expirable
11
+ # ...
12
+ # end
13
+ #
14
+ # # or if the resource's table already exists, define a migration and put this in:
15
+ # change_table :the_resources do |t|
16
+ # t.datetime :last_password_reset
17
+ # end
18
+ #
19
+ def password_expirable
20
+ apply_devise_schema :last_password_reset, DateTime
21
+ end
22
+
23
+ end
24
+ end
@@ -0,0 +1,3 @@
1
+ module DevisePasswordExpirable
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,23 @@
1
+ module DevisePasswordExpirable
2
+ module Generators
3
+ # Install Generator
4
+ class InstallGenerator < Rails::Generators::Base
5
+ source_root File.expand_path("../../templates", __FILE__)
6
+
7
+ desc "Install the devise password expirable extension"
8
+
9
+ def add_configs
10
+ inject_into_file "config/initializers/devise.rb", "\n # ==> Password Expirable Extension\n # Configure expire passwords extension for devise\n\n" +
11
+ " # Should the password expire (e.g 3.months)\n" +
12
+ " # config.expire_password_after = false\n\n" +
13
+ " # Need 1 char of A-Z, a-z and 0-9\n" +
14
+ " # config.password_regex = /(?=.*\\d)(?=.*[a-z])(?=.*[A-Z])/\n\n" +
15
+ "", :before => /end[ |\n|]+\Z/
16
+ end
17
+
18
+ def copy_locale
19
+ copy_file "../../../config/locales/en.yml", "config/locales/devise.password_expirable.en.yml"
20
+ end
21
+ end
22
+ end
23
+ end
metadata ADDED
@@ -0,0 +1,96 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: devise_password_expirable
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Jenni Kissinger
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2014-10-21 00:00:00 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rails
16
+ prerelease: false
17
+ requirement: &id001 !ruby/object:Gem::Requirement
18
+ requirements:
19
+ - - "="
20
+ - !ruby/object:Gem::Version
21
+ version: 3.0.20
22
+ type: :runtime
23
+ version_requirements: *id001
24
+ - !ruby/object:Gem::Dependency
25
+ name: devise
26
+ prerelease: false
27
+ requirement: &id002 !ruby/object:Gem::Requirement
28
+ requirements:
29
+ - - "="
30
+ - !ruby/object:Gem::Version
31
+ version: 1.1.3
32
+ type: :runtime
33
+ version_requirements: *id002
34
+ - !ruby/object:Gem::Dependency
35
+ name: bundler
36
+ prerelease: false
37
+ requirement: &id003 !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - &id004
40
+ - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: "0"
43
+ type: :development
44
+ version_requirements: *id003
45
+ description: An extension to devise that will expire user passwords after a set amount of time and prompt them to update their password.
46
+ email:
47
+ - jkissinger@carekinesis.com
48
+ executables: []
49
+
50
+ extensions: []
51
+
52
+ extra_rdoc_files: []
53
+
54
+ files:
55
+ - .gitignore
56
+ - Gemfile
57
+ - README.md
58
+ - Rakefile
59
+ - app/controllers/devise/password_expired_controller.rb
60
+ - app/views/devise/password_expired/show.html.erb
61
+ - config/locales/en.yml
62
+ - devise_password_expirable.gemspec
63
+ - lib/devise_password_expirable.rb
64
+ - lib/devise_password_expirable/controllers/helpers.rb
65
+ - lib/devise_password_expirable/hooks/password_expirable.rb
66
+ - lib/devise_password_expirable/models/password_expirable.rb
67
+ - lib/devise_password_expirable/rails.rb
68
+ - lib/devise_password_expirable/routes.rb
69
+ - lib/devise_password_expirable/schema.rb
70
+ - lib/devise_password_expirable/version.rb
71
+ - lib/generators/devise_expire_passwords/install_generator.rb
72
+ homepage: https://github.com/jenjaina/devise_password_expirable
73
+ licenses:
74
+ - MIT
75
+ metadata: {}
76
+
77
+ post_install_message:
78
+ rdoc_options: []
79
+
80
+ require_paths:
81
+ - lib
82
+ required_ruby_version: !ruby/object:Gem::Requirement
83
+ requirements:
84
+ - *id004
85
+ required_rubygems_version: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - *id004
88
+ requirements: []
89
+
90
+ rubyforge_project:
91
+ rubygems_version: 2.4.1
92
+ signing_key:
93
+ specification_version: 4
94
+ summary: Expire passwords plugin for devise
95
+ test_files: []
96
+