passwd 0.2.0 → 0.3.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.
Files changed (100) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +10 -17
  3. data/.travis.yml +3 -11
  4. data/Gemfile +3 -1
  5. data/LICENSE +21 -0
  6. data/README.md +39 -53
  7. data/Rakefile +6 -6
  8. data/bin/console +7 -0
  9. data/bin/setup +8 -0
  10. data/lib/generators/passwd/install/USAGE +5 -0
  11. data/lib/generators/passwd/install/install_generator.rb +10 -0
  12. data/lib/generators/passwd/install/templates/passwd.rb +27 -0
  13. data/lib/passwd.rb +33 -15
  14. data/lib/passwd/config.rb +29 -0
  15. data/lib/passwd/errors.rb +2 -7
  16. data/lib/passwd/rails/action_controller_ext.rb +77 -0
  17. data/lib/passwd/rails/active_record_ext.rb +37 -0
  18. data/lib/passwd/railtie.rb +5 -6
  19. data/lib/passwd/version.rb +2 -2
  20. data/passwd.gemspec +13 -14
  21. metadata +22 -156
  22. data/.coveralls.yml +0 -1
  23. data/CHANGELOG.md +0 -35
  24. data/LICENSE.txt +0 -23
  25. data/example/.gitignore +0 -16
  26. data/example/Gemfile +0 -25
  27. data/example/README.rdoc +0 -28
  28. data/example/Rakefile +0 -6
  29. data/example/app/assets/images/.keep +0 -0
  30. data/example/app/assets/javascripts/application.js +0 -16
  31. data/example/app/assets/stylesheets/application.css +0 -16
  32. data/example/app/controllers/application_controller.rb +0 -10
  33. data/example/app/controllers/concerns/.keep +0 -0
  34. data/example/app/controllers/profiles_controller.rb +0 -28
  35. data/example/app/controllers/root_controller.rb +0 -5
  36. data/example/app/controllers/sessions_controller.rb +0 -29
  37. data/example/app/helpers/application_helper.rb +0 -2
  38. data/example/app/mailers/.keep +0 -0
  39. data/example/app/models/.keep +0 -0
  40. data/example/app/models/concerns/.keep +0 -0
  41. data/example/app/models/user.rb +0 -4
  42. data/example/app/views/layouts/application.html.erb +0 -15
  43. data/example/app/views/profiles/edit.html.erb +0 -14
  44. data/example/app/views/profiles/show.html.erb +0 -12
  45. data/example/app/views/root/index.html.erb +0 -5
  46. data/example/app/views/sessions/new.html.erb +0 -6
  47. data/example/bin/bundle +0 -3
  48. data/example/bin/rails +0 -4
  49. data/example/bin/rake +0 -4
  50. data/example/config.ru +0 -4
  51. data/example/config/application.rb +0 -40
  52. data/example/config/boot.rb +0 -4
  53. data/example/config/database.yml +0 -26
  54. data/example/config/environment.rb +0 -5
  55. data/example/config/environments/development.rb +0 -37
  56. data/example/config/environments/production.rb +0 -78
  57. data/example/config/environments/test.rb +0 -39
  58. data/example/config/initializers/assets.rb +0 -8
  59. data/example/config/initializers/backtrace_silencers.rb +0 -7
  60. data/example/config/initializers/cookies_serializer.rb +0 -3
  61. data/example/config/initializers/filter_parameter_logging.rb +0 -4
  62. data/example/config/initializers/inflections.rb +0 -16
  63. data/example/config/initializers/mime_types.rb +0 -4
  64. data/example/config/initializers/passwd.rb +0 -41
  65. data/example/config/initializers/session_store.rb +0 -3
  66. data/example/config/initializers/wrap_parameters.rb +0 -14
  67. data/example/config/locales/en.yml +0 -23
  68. data/example/config/routes.rb +0 -16
  69. data/example/config/secrets.yml +0 -22
  70. data/example/db/migrate/20141122165914_create_users.rb +0 -13
  71. data/example/db/schema.rb +0 -25
  72. data/example/db/seeds.rb +0 -7
  73. data/example/lib/assets/.keep +0 -0
  74. data/example/lib/tasks/.keep +0 -0
  75. data/example/lib/tasks/user.rake +0 -12
  76. data/example/log/.keep +0 -0
  77. data/example/public/404.html +0 -67
  78. data/example/public/422.html +0 -67
  79. data/example/public/500.html +0 -66
  80. data/example/public/favicon.ico +0 -0
  81. data/example/public/robots.txt +0 -5
  82. data/example/vendor/assets/javascripts/.keep +0 -0
  83. data/example/vendor/assets/stylesheets/.keep +0 -0
  84. data/lib/generators/passwd/config_generator.rb +0 -13
  85. data/lib/generators/passwd/templates/passwd_config.rb +0 -41
  86. data/lib/passwd/action_controller_ext.rb +0 -48
  87. data/lib/passwd/active_record_ext.rb +0 -65
  88. data/lib/passwd/base.rb +0 -31
  89. data/lib/passwd/configuration.rb +0 -82
  90. data/lib/passwd/password.rb +0 -89
  91. data/lib/passwd/policy.rb +0 -28
  92. data/lib/passwd/salt.rb +0 -50
  93. data/spec/passwd/.keep +0 -0
  94. data/spec/passwd/active_record_ext_spec.rb +0 -80
  95. data/spec/passwd/base_spec.rb +0 -60
  96. data/spec/passwd/configuration_spec.rb +0 -50
  97. data/spec/passwd/password_spec.rb +0 -156
  98. data/spec/spec_helper.rb +0 -34
  99. data/spec/support/data_util.rb +0 -11
  100. data/spec/support/paths.rb +0 -2
File without changes
@@ -1,5 +0,0 @@
1
- # See http://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file
2
- #
3
- # To ban all spiders from the entire site uncomment the next two lines:
4
- # User-agent: *
5
- # Disallow: /
File without changes
File without changes
@@ -1,13 +0,0 @@
1
- module Passwd
2
- module Generators
3
- class ConfigGenerator < ::Rails::Generators::Base
4
- source_root File.expand_path(File.join(File.dirname(__FILE__), "templates"))
5
-
6
- desc "Create Passwd configuration file"
7
- def create_configuration_file
8
- template "passwd_config.rb", "config/initializers/passwd.rb"
9
- end
10
- end
11
- end
12
- end
13
-
@@ -1,41 +0,0 @@
1
- Passwd.configure do |c|
2
- # Password settings
3
- # The following settings are all default values.
4
-
5
- # Hashing algorithm
6
- # Supported algorithm is :md5, :rmd160, :sha1, :sha256, :sha384 and :sha512
7
- # c.algorithm = :sha512
8
-
9
- # Random generate password length
10
- # c.length = 8
11
-
12
- # Number of hashed by stretching
13
- # Not stretching if specified nil.
14
- # c.stretching = nil
15
-
16
- # Character type that is used for password
17
- # c.lower = true
18
- # c.upper = true
19
- # c.number = true
20
- end
21
-
22
- Passwd.policy_configure do |c|
23
- # Minimum password length
24
- # c.min_length = 8
25
-
26
- # Character types to force the use
27
- # c.require_lower = true
28
- # c.require_upper = false
29
- # c.require_number = true
30
- end
31
-
32
- # Session key for authentication
33
- Rails.application.config.passwd.session_key = :user_id
34
-
35
- # Authentication Model Class
36
- Rails.application.config.passwd.authenticate_class = :User
37
-
38
- # Redirect path when not signin
39
- # E.G. :signin_path # Do not specify ***_url
40
- Rails.application.config.passwd.redirect_to = nil
41
-
@@ -1,48 +0,0 @@
1
- module Passwd
2
- module ActionControllerExt
3
- extend ActiveSupport::Concern
4
-
5
- included do
6
- helper_method :current_user
7
- end
8
-
9
- def current_user
10
- @current_user ||= auth_class.find_by(id: session[auth_key])
11
- end
12
-
13
- def signin!(user)
14
- @current_user = user
15
- session[auth_key] = user.id
16
- end
17
-
18
- def signout!
19
- @current_user = session[auth_key] = nil
20
- end
21
-
22
- private
23
- def auth_key
24
- Rails.application.config.passwd.session_key || :user_id
25
- end
26
-
27
- def auth_class
28
- @_auth_class ||=
29
- (Rails.application.config.passwd.authenticate_class || :User).to_s.constantize
30
- end
31
-
32
- def _redirect_path
33
- _to = Rails.application.config.passwd.redirect_to
34
- _to ? Rails.application.routes.url_helpers.send(_to) : nil
35
- end
36
-
37
- def require_signin
38
- unless current_user
39
- if _redirect_path
40
- redirect_to _redirect_path
41
- else
42
- raise UnauthorizedAccess
43
- end
44
- end
45
- end
46
- end
47
- end
48
-
@@ -1,65 +0,0 @@
1
- module Passwd
2
- module ActiveRecordExt
3
- def with_authenticate(options = {})
4
- _id_key = options.fetch(:id, :email)
5
- _salt_key = options.fetch(:salt, :salt)
6
- _pass_key = options.fetch(:password, :password)
7
-
8
- _define_passwd(_salt_key, _pass_key)
9
- _define_singleton_auth(_id_key)
10
- _define_instance_auth
11
- _define_set_password(_salt_key, _pass_key)
12
- _define_update_password(_salt_key, _pass_key)
13
- end
14
-
15
- private
16
- def _define_passwd(_salt_key, _pass_key)
17
- define_method :passwd do |cache = true|
18
- return @_passwd if cache && @_passwd
19
- self.reload unless self.new_record?
20
- _salt, _pass = self.send(_salt_key), self.send(_pass_key)
21
- if _salt.present? && _pass.present?
22
- @_passwd = Passwd::Password.from_hash(_pass, _salt)
23
- else
24
- self.set_password
25
- end
26
- end
27
- end
28
-
29
- def _define_singleton_auth(_id_key)
30
- define_singleton_method :authenticate do |_id, _pass|
31
- _condition = Array(_id_key).map {|k| "#{k} = :id"}.join(" OR ")
32
- _user = self.find_by(_condition, id: _id)
33
- _user if _user && _user.passwd.match?(_pass)
34
- end
35
- end
36
-
37
- def _define_instance_auth
38
- define_method :authenticate do |_pass|
39
- self.passwd.match?(_pass)
40
- end
41
- end
42
-
43
- def _define_set_password(_salt_key, _pass_key)
44
- define_method :set_password do |_pass = nil|
45
- _options = _pass ? {plain: _pass} : {}
46
- _passwd = Passwd::Password.new(_options)
47
- self.send("#{_salt_key}=", _passwd.salt.hash)
48
- self.send("#{_pass_key}=", _passwd.hash)
49
- self.instance_variable_set(:@_passwd, _passwd)
50
- end
51
- end
52
-
53
- def _define_update_password(_salt_key, _pass_key)
54
- define_method :update_password do |_old, _new, _policy = false|
55
- raise PolicyNotMatch if _policy && !Passwd.policy_check(_new)
56
- if self.passwd.match?(_old)
57
- self.set_password(_new)
58
- else
59
- raise AuthenticationFails
60
- end
61
- end
62
- end
63
- end
64
- end
65
-
@@ -1,31 +0,0 @@
1
- module Passwd
2
- module Base
3
- def random(options = {})
4
- c = PwConfig.merge(options)
5
- Array.new(c.length){c.letters[rand(c.letters.size)]}.join
6
- end
7
-
8
- def digest(plain, _algorithm = nil)
9
- _algorithm ||= PwConfig.algorithm
10
-
11
- if PwConfig.stretching
12
- _pass = plain
13
- PwConfig.stretching.times do
14
- _pass = digest_without_stretching(_pass, _algorithm)
15
- end
16
- else
17
- digest_without_stretching(plain, _algorithm)
18
- end
19
- end
20
-
21
- def digest_without_stretching(plain, _algorithm = nil)
22
- algorithm(_algorithm || PwConfig.algorithm).hexdigest(plain)
23
- end
24
-
25
- private
26
- def algorithm(_algorithm)
27
- Digest.const_get(_algorithm.upcase, false)
28
- end
29
- end
30
- end
31
-
@@ -1,82 +0,0 @@
1
- module Passwd
2
- class Configuration
3
- KINDS = %i(lower upper number).freeze
4
- LETTERS = KINDS.map {|k| "letters_#{k}".to_sym}.freeze
5
-
6
- VALID_OPTIONS = [
7
- :algorithm,
8
- :length,
9
- :policy,
10
- :stretching,
11
- ].concat(KINDS).concat(LETTERS).freeze
12
-
13
- attr_accessor *VALID_OPTIONS
14
-
15
- def initialize
16
- reset
17
- end
18
-
19
- def configure
20
- yield self
21
- end
22
-
23
- def merge(params)
24
- self.dup.merge!(params)
25
- end
26
-
27
- def merge!(params)
28
- params.keys.each do |key|
29
- self.send("#{key}=", params[key])
30
- end
31
- self
32
- end
33
-
34
- KINDS.each do |kind|
35
- define_method "#{kind}_chars" do
36
- self.send("letters_#{kind}") || []
37
- end
38
- end
39
-
40
- def letters
41
- KINDS.detect {|k| self.send(k)} || (raise ConfigError, "letters is empry.")
42
- LETTERS.zip(KINDS).map {|l, k|
43
- self.send(l) if self.send(k)
44
- }.compact.flatten
45
- end
46
-
47
- def reset
48
- self.algorithm = :sha512
49
- self.length = 8
50
- self.policy = Policy.new
51
- self.stretching = nil
52
- self.lower = true
53
- self.upper = true
54
- self.number = true
55
- self.letters_lower = ("a".."z").to_a
56
- self.letters_upper = ("A".."Z").to_a
57
- self.letters_number = ("0".."9").to_a
58
- end
59
-
60
- module Writable
61
- def self.extended(base)
62
- base.send(:include, Accessible)
63
- end
64
-
65
- def configure(options = {}, &block)
66
- PwConfig.merge!(options) unless options.empty?
67
- PwConfig.configure(&block) if block_given?
68
- end
69
-
70
- def policy_configure(&block)
71
- PwConfig.policy.configure(&block) if block_given?
72
- end
73
- end
74
-
75
- module Accessible
76
- def self.included(base)
77
- base.const_set(:PwConfig, Configuration.new)
78
- end
79
- end
80
- end
81
- end
82
-
@@ -1,89 +0,0 @@
1
- module Passwd
2
- class Password
3
- include Base
4
-
5
- attr_reader :plain, :hash, :salt
6
-
7
- def initialize(options = {})
8
- options = default_options.merge(options)
9
-
10
- if options.has_key?(:hash)
11
- raise ArgumentError unless options.has_key?(:salt_hash)
12
- @salt = Salt.from_hash(options[:salt_hash], self)
13
- @hash = options[:hash]
14
- else
15
- @salt =
16
- case
17
- when options.has_key?(:salt_hash)
18
- Salt.from_hash(options[:salt_hash], self)
19
- when options.has_key?(:salt_plain)
20
- Salt.from_plain(options[:salt_plain], self)
21
- else
22
- Salt.new(password: self)
23
- end
24
- self.update_plain(options[:plain])
25
- end
26
- end
27
-
28
- def update_plain(value)
29
- @plain = value
30
- rehash
31
- end
32
-
33
- def update_hash(value, salt_hash)
34
- @plain = nil
35
- @hash = value
36
- self.salt.update_hash(salt_hash)
37
- end
38
-
39
- def rehash
40
- raise PasswdError unless self.plain
41
- @hash = digest([self.salt.hash, self.plain].join)
42
- end
43
-
44
- def match?(value)
45
- self.hash == digest([self.salt.hash, value].join)
46
- end
47
-
48
- def ==(other)
49
- match?(other)
50
- end
51
-
52
- def to_s
53
- self.plain.to_s
54
- end
55
-
56
- def valid?
57
- raise PasswdError unless self.plain
58
-
59
- return false if PwConfig.policy.min_length > self.plain.size
60
-
61
- Configuration::KINDS.each do |key|
62
- if PwConfig.policy.send("require_#{key}")
63
- return false unless include_char?(PwConfig.send("letters_#{key}"))
64
- end
65
- end
66
- true
67
- end
68
-
69
- def self.from_plain(value, options = {})
70
- new(options.merge(plain: value))
71
- end
72
-
73
- def self.from_hash(value, salt_hash)
74
- new(hash: value, salt_hash: salt_hash)
75
- end
76
-
77
- private
78
- def default_options
79
- {plain: random}
80
- end
81
-
82
- def include_char?(letters)
83
- raise PasswdError unless self.plain
84
- self.plain.chars.uniq.each {|c| return true if letters.include?(c)}
85
- false
86
- end
87
- end
88
- end
89
-
@@ -1,28 +0,0 @@
1
- module Passwd
2
- class Policy
3
- VALID_OPTIONS = [
4
- :min_length,
5
- :require_lower,
6
- :require_upper,
7
- :require_number
8
- ].freeze
9
-
10
- attr_accessor *VALID_OPTIONS
11
-
12
- def initialize
13
- reset
14
- end
15
-
16
- def configure
17
- yield self
18
- end
19
-
20
- def reset
21
- self.min_length = 8
22
- self.require_lower = true
23
- self.require_upper = false
24
- self.require_number = true
25
- end
26
- end
27
- end
28
-
@@ -1,50 +0,0 @@
1
- module Passwd
2
- class Salt
3
- include Base
4
-
5
- attr_reader :plain, :hash
6
-
7
- def initialize(options = {})
8
- options = default_options.merge(options)
9
-
10
- @password = options[:password]
11
- if options.has_key?(:hash)
12
- @plain = nil
13
- @hash = options[:hash]
14
- else
15
- @plain = options[:plain] || (raise ArgumentError)
16
- @hash = digest_without_stretching(@plain)
17
- end
18
- end
19
-
20
- def update_plain(value)
21
- @plain = value
22
- @hash = digest_without_stretching(@plain)
23
- update_password!
24
- end
25
-
26
- def update_hash(value)
27
- @plain = nil
28
- @hash = value
29
- update_password!
30
- end
31
-
32
- def self.from_plain(value, password = nil)
33
- new(plain: value, password: password)
34
- end
35
-
36
- def self.from_hash(value, password = nil)
37
- new(hash: value, password: password)
38
- end
39
-
40
- private
41
- def default_options
42
- {plain: Time.now.to_s}
43
- end
44
-
45
- def update_password!
46
- @password.rehash if @password && @password.plain
47
- end
48
- end
49
- end
50
-