protected 1.0.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,4 +1,4 @@
1
- Copyright 2012 YOURNAME
1
+ Copyright 2012 Mark Daggett
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
@@ -69,9 +69,7 @@ module Protected
69
69
  require File.dirname(__FILE__) + '/../../../lib/protected/password_utils'
70
70
 
71
71
  class User < ActiveRecord::Base
72
- # devise :database_authenticatable, :recoverable, :trackable, :validatable, :lockable, :timeoutable, :password_archivable,
73
- # :maximum_attempts => 4, :unlock_strategy => :none
74
- devise :database_authenticatable, :recoverable, :trackable, :validatable, :lockable, :timeoutable,
72
+ devise :database_authenticatable, :recoverable, :trackable, :validatable, :lockable, :timeoutable, :password_archivable,
75
73
  :maximum_attempts => 4, :unlock_strategy => :none
76
74
 
77
75
  has_many :old_passwords, :as => :password_archivable, :dependent => :destroy
@@ -156,8 +156,8 @@ Devise.setup do |config|
156
156
  # and :restful_authentication_sha1 (then you should set stretches to 10, and copy
157
157
  # REST_AUTH_SITE_KEY to pepper)
158
158
  config.encryptor = :bcrypt
159
- # config.password_archiving_count = 5
160
- # config.deny_old_passwords = true
159
+ config.password_archiving_count = 5
160
+ config.deny_old_passwords = true
161
161
 
162
162
  # ==> Configuration for :token_authenticatable
163
163
  # Defines name of the authentication token params key
@@ -3,6 +3,7 @@
3
3
  en:
4
4
  errors:
5
5
  messages:
6
+ taken_in_past: "was already taken in the past!"
6
7
  expired: "has expired, please request a new one"
7
8
  not_found: "not found"
8
9
  already_confirmed: "was already confirmed, please try signing in"
@@ -174,8 +174,8 @@ Devise.setup do |config|
174
174
  # REST_AUTH_SITE_KEY to pepper)
175
175
  # config.encryptor = :sha512
176
176
  config.encryptor = :bcrypt
177
- # config.password_archiving_count = 5
178
- # config.deny_old_passwords = true
177
+ config.password_archiving_count = 5
178
+ config.deny_old_passwords = true
179
179
 
180
180
  # ==> Configuration for :token_authenticatable
181
181
  # Defines name of the authentication token params key
@@ -1,4 +1,14 @@
1
1
  require "protected/engine"
2
+ require 'devise'
3
+ module Devise
4
+ # How often save old passwords in archive
5
+ mattr_accessor :password_archiving_count
6
+ @@password_archiving_count = 5
2
7
 
8
+ # Deny old password (true, false, count)
9
+ mattr_accessor :deny_old_passwords
10
+ @@deny_old_passwords = true
11
+ end
3
12
  module Protected
4
13
  end
14
+ Devise.add_module :password_archivable, :model => "#{File.dirname(__FILE__)}/protected/password_archiveable"
@@ -0,0 +1,64 @@
1
+ module Devise
2
+ module Models
3
+
4
+ # PasswordArchivable
5
+ module PasswordArchivable
6
+ extend ActiveSupport::Concern
7
+
8
+ included do
9
+ has_many :old_passwords, :as => :password_archivable, :dependent => :destroy, :order => 'id DESC'
10
+ before_update :archive_password
11
+ validate :validate_password_archive
12
+ end
13
+
14
+ def validate_password_archive
15
+ self.errors.add(:password, :taken_in_past) if encrypted_password_changed? and password_archive_included?
16
+ end
17
+
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
25
+ end
26
+ end
27
+
28
+ if self.class.deny_old_passwords > 0 and not self.password.nil?
29
+ self.old_passwords.order('created_at DESC').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)
34
+ end
35
+ end
36
+
37
+ false
38
+ end
39
+
40
+ private
41
+
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
48
+ else
49
+ self.old_passwords.create! :encrypted_password => self.encrypted_password_change.first
50
+ end
51
+ self.old_passwords.order('created_at DESC').offset(self.class.password_archiving_count).destroy_all
52
+ else
53
+ self.old_passwords.destroy_all
54
+ end
55
+ end
56
+ end
57
+
58
+ module ClassMethods
59
+ ::Devise::Models.config(self, :password_archiving_count, :deny_old_passwords)
60
+ end
61
+ end
62
+ end
63
+
64
+ end
@@ -1,3 +1,3 @@
1
1
  module Protected
2
- VERSION = "1.0.0"
2
+ VERSION = "1.0.1"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: protected
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2012-05-22 00:00:00.000000000 Z
13
+ date: 2012-05-23 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rack
@@ -373,6 +373,7 @@ files:
373
373
  - lib/generators/protected/views/views_generator.rb
374
374
  - lib/protected/devise_recoverable_extensions.rb
375
375
  - lib/protected/engine.rb
376
+ - lib/protected/password_archiveable.rb
376
377
  - lib/protected/password_utils.rb
377
378
  - lib/protected/version.rb
378
379
  - lib/protected.rb
@@ -394,7 +395,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
394
395
  version: '0'
395
396
  segments:
396
397
  - 0
397
- hash: -2923849300726707462
398
+ hash: -1272936797958317662
398
399
  required_rubygems_version: !ruby/object:Gem::Requirement
399
400
  none: false
400
401
  requirements:
@@ -403,7 +404,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
403
404
  version: '0'
404
405
  segments:
405
406
  - 0
406
- hash: -2923849300726707462
407
+ hash: -1272936797958317662
407
408
  requirements: []
408
409
  rubyforge_project:
409
410
  rubygems_version: 1.8.21