passwd 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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
-