devise_password_expirable 0.0.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.
@@ -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
+