authlogic 3.8.0 → 4.5.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 (143) hide show
  1. checksums.yaml +7 -0
  2. data/.github/ISSUE_TEMPLATE/bug_report.md +28 -0
  3. data/.github/ISSUE_TEMPLATE/feature_proposal.md +32 -0
  4. data/.github/triage.md +86 -0
  5. data/.gitignore +4 -3
  6. data/.rubocop.yml +109 -9
  7. data/.rubocop_todo.yml +38 -355
  8. data/.travis.yml +11 -35
  9. data/CHANGELOG.md +345 -2
  10. data/CONTRIBUTING.md +45 -14
  11. data/Gemfile +3 -2
  12. data/README.md +244 -90
  13. data/Rakefile +10 -10
  14. data/UPGRADING.md +22 -0
  15. data/authlogic.gemspec +34 -21
  16. data/doc/use_normal_rails_validation.md +82 -0
  17. data/gemfiles/Gemfile.rails-4.2.x +6 -0
  18. data/{test/gemfiles → gemfiles}/Gemfile.rails-5.1.x +2 -2
  19. data/{test/gemfiles → gemfiles}/Gemfile.rails-5.2.x +2 -2
  20. data/lib/authlogic/acts_as_authentic/base.rb +36 -24
  21. data/lib/authlogic/acts_as_authentic/email.rb +65 -31
  22. data/lib/authlogic/acts_as_authentic/logged_in_status.rb +14 -9
  23. data/lib/authlogic/acts_as_authentic/login.rb +61 -45
  24. data/lib/authlogic/acts_as_authentic/magic_columns.rb +6 -6
  25. data/lib/authlogic/acts_as_authentic/password.rb +267 -146
  26. data/lib/authlogic/acts_as_authentic/perishable_token.rb +24 -19
  27. data/lib/authlogic/acts_as_authentic/persistence_token.rb +10 -15
  28. data/lib/authlogic/acts_as_authentic/queries/find_with_case.rb +67 -0
  29. data/lib/authlogic/acts_as_authentic/restful_authentication.rb +50 -14
  30. data/lib/authlogic/acts_as_authentic/session_maintenance.rb +88 -60
  31. data/lib/authlogic/acts_as_authentic/single_access_token.rb +23 -11
  32. data/lib/authlogic/acts_as_authentic/validations_scope.rb +9 -6
  33. data/lib/authlogic/authenticates_many/association.rb +7 -7
  34. data/lib/authlogic/authenticates_many/base.rb +37 -21
  35. data/lib/authlogic/config.rb +21 -10
  36. data/lib/authlogic/controller_adapters/abstract_adapter.rb +38 -11
  37. data/lib/authlogic/controller_adapters/rack_adapter.rb +9 -5
  38. data/lib/authlogic/controller_adapters/rails_adapter.rb +12 -7
  39. data/lib/authlogic/controller_adapters/sinatra_adapter.rb +2 -2
  40. data/lib/authlogic/crypto_providers/aes256.rb +37 -32
  41. data/lib/authlogic/crypto_providers/bcrypt.rb +21 -15
  42. data/lib/authlogic/crypto_providers/md5.rb +4 -2
  43. data/lib/authlogic/crypto_providers/scrypt.rb +22 -17
  44. data/lib/authlogic/crypto_providers/sha1.rb +11 -5
  45. data/lib/authlogic/crypto_providers/sha256.rb +13 -9
  46. data/lib/authlogic/crypto_providers/sha512.rb +0 -21
  47. data/lib/authlogic/crypto_providers/wordpress.rb +32 -3
  48. data/lib/authlogic/crypto_providers.rb +91 -0
  49. data/lib/authlogic/i18n.rb +26 -19
  50. data/lib/authlogic/random.rb +10 -28
  51. data/lib/authlogic/regex.rb +59 -28
  52. data/lib/authlogic/session/activation.rb +10 -7
  53. data/lib/authlogic/session/active_record_trickery.rb +13 -9
  54. data/lib/authlogic/session/base.rb +15 -4
  55. data/lib/authlogic/session/brute_force_protection.rb +40 -33
  56. data/lib/authlogic/session/callbacks.rb +94 -46
  57. data/lib/authlogic/session/cookies.rb +130 -45
  58. data/lib/authlogic/session/existence.rb +21 -11
  59. data/lib/authlogic/session/foundation.rb +64 -14
  60. data/lib/authlogic/session/http_auth.rb +35 -28
  61. data/lib/authlogic/session/id.rb +9 -4
  62. data/lib/authlogic/session/klass.rb +15 -12
  63. data/lib/authlogic/session/magic_columns.rb +58 -55
  64. data/lib/authlogic/session/magic_states.rb +25 -19
  65. data/lib/authlogic/session/params.rb +42 -28
  66. data/lib/authlogic/session/password.rb +130 -120
  67. data/lib/authlogic/session/perishable_token.rb +5 -4
  68. data/lib/authlogic/session/persistence.rb +18 -12
  69. data/lib/authlogic/session/priority_record.rb +15 -12
  70. data/lib/authlogic/session/scopes.rb +51 -32
  71. data/lib/authlogic/session/session.rb +38 -28
  72. data/lib/authlogic/session/timeout.rb +13 -13
  73. data/lib/authlogic/session/unauthorized_record.rb +18 -13
  74. data/lib/authlogic/session/validation.rb +9 -9
  75. data/lib/authlogic/test_case/mock_controller.rb +5 -4
  76. data/lib/authlogic/test_case/mock_cookie_jar.rb +47 -3
  77. data/lib/authlogic/test_case/mock_request.rb +6 -3
  78. data/lib/authlogic/test_case/rails_request_adapter.rb +3 -2
  79. data/lib/authlogic/test_case.rb +70 -2
  80. data/lib/authlogic/version.rb +21 -0
  81. data/lib/authlogic.rb +51 -49
  82. data/test/acts_as_authentic_test/base_test.rb +3 -1
  83. data/test/acts_as_authentic_test/email_test.rb +43 -42
  84. data/test/acts_as_authentic_test/logged_in_status_test.rb +6 -4
  85. data/test/acts_as_authentic_test/login_test.rb +77 -80
  86. data/test/acts_as_authentic_test/magic_columns_test.rb +3 -1
  87. data/test/acts_as_authentic_test/password_test.rb +51 -37
  88. data/test/acts_as_authentic_test/perishable_token_test.rb +13 -5
  89. data/test/acts_as_authentic_test/persistence_token_test.rb +7 -1
  90. data/test/acts_as_authentic_test/restful_authentication_test.rb +14 -3
  91. data/test/acts_as_authentic_test/session_maintenance_test.rb +69 -15
  92. data/test/acts_as_authentic_test/single_access_test.rb +3 -1
  93. data/test/adapter_test.rb +23 -0
  94. data/test/authenticates_many_test.rb +3 -1
  95. data/test/config_test.rb +11 -9
  96. data/test/crypto_provider_test/aes256_test.rb +3 -1
  97. data/test/crypto_provider_test/bcrypt_test.rb +3 -1
  98. data/test/crypto_provider_test/scrypt_test.rb +3 -1
  99. data/test/crypto_provider_test/sha1_test.rb +3 -1
  100. data/test/crypto_provider_test/sha256_test.rb +3 -1
  101. data/test/crypto_provider_test/sha512_test.rb +3 -1
  102. data/test/crypto_provider_test/wordpress_test.rb +26 -0
  103. data/test/fixtures/companies.yml +2 -2
  104. data/test/fixtures/employees.yml +1 -1
  105. data/test/i18n_test.rb +6 -4
  106. data/test/libs/affiliate.rb +2 -0
  107. data/test/libs/company.rb +4 -2
  108. data/test/libs/employee.rb +2 -0
  109. data/test/libs/employee_session.rb +2 -0
  110. data/test/libs/ldaper.rb +2 -0
  111. data/test/libs/project.rb +2 -0
  112. data/test/libs/user.rb +2 -0
  113. data/test/libs/user_session.rb +4 -2
  114. data/test/random_test.rb +10 -38
  115. data/test/session_test/activation_test.rb +3 -1
  116. data/test/session_test/active_record_trickery_test.rb +7 -4
  117. data/test/session_test/brute_force_protection_test.rb +11 -9
  118. data/test/session_test/callbacks_test.rb +12 -4
  119. data/test/session_test/cookies_test.rb +48 -5
  120. data/test/session_test/existence_test.rb +18 -5
  121. data/test/session_test/foundation_test.rb +19 -1
  122. data/test/session_test/http_auth_test.rb +11 -7
  123. data/test/session_test/id_test.rb +3 -1
  124. data/test/session_test/klass_test.rb +3 -1
  125. data/test/session_test/magic_columns_test.rb +13 -13
  126. data/test/session_test/magic_states_test.rb +3 -1
  127. data/test/session_test/params_test.rb +13 -5
  128. data/test/session_test/password_test.rb +10 -8
  129. data/test/session_test/perishability_test.rb +3 -1
  130. data/test/session_test/persistence_test.rb +4 -1
  131. data/test/session_test/scopes_test.rb +16 -8
  132. data/test/session_test/session_test.rb +6 -4
  133. data/test/session_test/timeout_test.rb +4 -2
  134. data/test/session_test/unauthorized_record_test.rb +4 -2
  135. data/test/session_test/validation_test.rb +3 -1
  136. data/test/test_helper.rb +84 -45
  137. metadata +87 -73
  138. data/.github/ISSUE_TEMPLATE.md +0 -13
  139. data/test/gemfiles/Gemfile.rails-3.2.x +0 -7
  140. data/test/gemfiles/Gemfile.rails-4.0.x +0 -7
  141. data/test/gemfiles/Gemfile.rails-4.1.x +0 -7
  142. data/test/gemfiles/Gemfile.rails-4.2.x +0 -7
  143. data/test/gemfiles/Gemfile.rails-5.0.x +0 -6
@@ -3,7 +3,7 @@ module Authlogic
3
3
  # to an account, you want to make sure only users that belong to that account can
4
4
  # actually login into that account. Simple, just do:
5
5
  #
6
- # class Account < ActiveRecord::Base
6
+ # class Account < ApplicationRecord
7
7
  # authenticates_many :user_sessions
8
8
  # end
9
9
  #
@@ -17,8 +17,16 @@ module Authlogic
17
17
  # Checkout the authenticates_many method for a list of options.
18
18
  # You may also want to checkout Authlogic::ActsAsAuthentic::Scope to scope your model.
19
19
  module AuthenticatesMany
20
+ # These methods become class methods of ::ActiveRecord::Base.
20
21
  module Base
21
- # Allows you set essentially set up a relationship with your sessions. See module
22
+ DPR_AUTH_MANY = <<~EOS.freeze
23
+ authenticates_many is deprecated without replacement. Let us know
24
+ if you would like to take over maintenance of this feature as a separate
25
+ gem. If no one volunteers to extract and maintain a new gem, then this
26
+ feature will simply be deleted.
27
+ EOS
28
+
29
+ # Allows you to set up a relationship with your sessions. See module
22
30
  # definition above for more details.
23
31
  #
24
32
  # === Options
@@ -26,37 +34,45 @@ module Authlogic
26
34
  # * <tt>session_class:</tt> default: "#{name}Session",
27
35
  # This is the related session class.
28
36
  #
29
- # * <tt>relationship_name:</tt> default: options[:session_class].klass_name.underscore.pluralize,
30
- # This is the name of the relationship you want to use to scope everything. For
31
- # example an Account has many Users. There should be a relationship called :users
32
- # that you defined with a has_many. The reason we use the relationship is so you
33
- # don't have to repeat yourself. The relationship could have all kinds of custom
34
- # options. So instead of repeating yourself we essentially use the scope that the
37
+ # * <tt>relationship_name:</tt>
38
+ # default: options[:session_class].klass_name.underscore.pluralize,
39
+ # This is the name of the relationship you want to use to scope
40
+ # everything. For example an Account has many Users. There should be a
41
+ # relationship called :users that you defined with a has_many. The
42
+ # reason we use the relationship is so you don't have to repeat
43
+ # yourself. The relationship could have all kinds of custom options. So
44
+ # instead of repeating yourself we essentially use the scope that the
35
45
  # relationship creates.
36
46
  #
37
47
  # * <tt>find_options:</tt> default: nil,
38
- # By default the find options are created from the relationship you specify with
39
- # :relationship_name. But if you want to override this and manually specify
40
- # find_options you can do it here. Specify options just as you would in
41
- # ActiveRecord::Base.find.
48
+ # By default the find options are created from the relationship you
49
+ # specify with :relationship_name. But if you want to override this and
50
+ # manually specify find_options you can do it here. Specify options just
51
+ # as you would in ActiveRecord::Base.find.
42
52
  #
43
53
  # * <tt>scope_cookies:</tt> default: false
44
- # By the nature of cookies they scope themselves if you are using subdomains to
45
- # access accounts. If you aren't using subdomains you need to have separate
46
- # cookies for each account, assuming a user is logging into more than one account.
47
- # Authlogic can take care of this for you by prefixing the name of the cookie and
48
- # session with the model id. Because it affects both cookies names and session keys,
49
- # the name `scope_cookies` is misleading. Perhaps simply `scope` or `scoped`
54
+ # By the nature of cookies they scope themselves if you are using
55
+ # subdomains to access accounts. If you aren't using subdomains you need
56
+ # to have separate cookies for each account, assuming a user is logging
57
+ # into more than one account. Authlogic can take care of this for you by
58
+ # prefixing the name of the cookie and session with the model id.
59
+ # Because it affects both cookies names and session keys, the name
60
+ # `scope_cookies` is misleading. Perhaps simply `scope` or `scoped`
50
61
  # would have been better.
51
62
  def authenticates_many(name, options = {})
63
+ ::ActiveSupport::Deprecation.warn(DPR_AUTH_MANY)
52
64
  options[:session_class] ||= name.to_s.classify.constantize
53
65
  options[:relationship_name] ||= options[:session_class].klass_name.underscore.pluralize
54
- class_eval <<-"end_eval", __FILE__, __LINE__
66
+ class_eval <<-EOS, __FILE__, __LINE__ + 1
55
67
  def #{name}
56
68
  find_options = #{options[:find_options].inspect} || #{options[:relationship_name]}.where(nil)
57
- @#{name} ||= Authlogic::AuthenticatesMany::Association.new(#{options[:session_class]}, find_options, #{options[:scope_cookies] ? "self.class.model_name.name.underscore + '_' + self.send(self.class.primary_key).to_s" : "nil"})
69
+ @#{name} ||= Authlogic::AuthenticatesMany::Association.new(
70
+ #{options[:session_class]},
71
+ find_options,
72
+ #{options[:scope_cookies] ? "self.class.model_name.name.underscore + '_' + self.send(self.class.primary_key).to_s" : 'nil'}
73
+ )
58
74
  end
59
- end_eval
75
+ EOS
60
76
  end
61
77
  end
62
78
 
@@ -1,6 +1,11 @@
1
- # encoding: utf-8
2
1
  module Authlogic
3
2
  module Config
3
+ E_USE_NORMAL_RAILS_VALIDATION = <<~EOS.freeze
4
+ This Authlogic configuration option (%s) is deprecated. Use normal
5
+ ActiveRecord validation instead. Detailed instructions:
6
+ https://github.com/binarylogic/authlogic/blob/master/doc/use_normal_rails_validation.md
7
+ EOS
8
+
4
9
  def self.extended(klass)
5
10
  klass.class_eval do
6
11
  class_attribute :acts_as_authentic_config
@@ -10,15 +15,21 @@ module Authlogic
10
15
 
11
16
  private
12
17
 
13
- # This is a one-liner method to write a config setting, read the config
14
- # setting, and also set a default value for the setting.
15
- def rw_config(key, value, default_value = nil)
16
- if value.nil?
17
- acts_as_authentic_config.include?(key) ? acts_as_authentic_config[key] : default_value
18
- else
19
- self.acts_as_authentic_config = acts_as_authentic_config.merge(key => value)
20
- value
21
- end
18
+ def deprecate_authlogic_config(method_name)
19
+ ::ActiveSupport::Deprecation.warn(
20
+ format(E_USE_NORMAL_RAILS_VALIDATION, method_name)
21
+ )
22
+ end
23
+
24
+ # This is a one-liner method to write a config setting, read the config
25
+ # setting, and also set a default value for the setting.
26
+ def rw_config(key, value, default_value = nil)
27
+ if value.nil?
28
+ acts_as_authentic_config.include?(key) ? acts_as_authentic_config[key] : default_value
29
+ else
30
+ self.acts_as_authentic_config = acts_as_authentic_config.merge(key => value)
31
+ value
22
32
  end
33
+ end
23
34
  end
24
35
  end
@@ -3,16 +3,19 @@ module Authlogic
3
3
  # Allows you to use Authlogic in any framework you want, not just rails. See the RailsAdapter
4
4
  # for an example of how to adapt Authlogic to work with your framework.
5
5
  class AbstractAdapter
6
+ E_COOKIE_DOMAIN_ADAPTER = "The cookie_domain method has not been " \
7
+ "implemented by the controller adapter".freeze
8
+
6
9
  attr_accessor :controller
7
10
 
8
11
  def initialize(controller)
9
12
  self.controller = controller
10
13
  end
11
14
 
12
- def authenticate_with_http_basic(&block)
15
+ def authenticate_with_http_basic
13
16
  @auth = Rack::Auth::Basic::Request.new(controller.request.env)
14
- if @auth.provided? and @auth.basic?
15
- block.call(*@auth.credentials)
17
+ if @auth.provided? && @auth.basic?
18
+ yield(*@auth.credentials)
16
19
  else
17
20
  false
18
21
  end
@@ -23,7 +26,7 @@ module Authlogic
23
26
  end
24
27
 
25
28
  def cookie_domain
26
- raise NotImplementedError.new("The cookie_domain method has not been implemented by the controller adapter")
29
+ raise NotImplementedError.new(E_COOKIE_DOMAIN_ADAPTER)
27
30
  end
28
31
 
29
32
  def params
@@ -50,19 +53,43 @@ module Authlogic
50
53
  controller.send(:single_access_allowed?)
51
54
  end
52
55
 
53
- def responds_to_last_request_update_allowed?
54
- controller.respond_to?(:last_request_update_allowed?, true)
56
+ # You can disable the updating of `last_request_at`
57
+ # on a per-controller basis.
58
+ #
59
+ # # in your controller
60
+ # def last_request_update_allowed?
61
+ # false
62
+ # end
63
+ #
64
+ # For example, what if you had a javascript function that polled the
65
+ # server updating how much time is left in their session before it
66
+ # times out. Obviously you would want to ignore this request, because
67
+ # then the user would never time out. So you can do something like
68
+ # this in your controller:
69
+ #
70
+ # def last_request_update_allowed?
71
+ # action_name != "update_session_time_left"
72
+ # end
73
+ #
74
+ # See `authlogic/session/magic_columns.rb` to learn more about the
75
+ # `last_request_at` column itself.
76
+ def last_request_update_allowed?
77
+ if controller.respond_to?(:last_request_update_allowed?, true)
78
+ controller.send(:last_request_update_allowed?)
79
+ else
80
+ true
81
+ end
55
82
  end
56
83
 
57
- def last_request_update_allowed?
58
- controller.send(:last_request_update_allowed?)
84
+ def respond_to_missing?(*args)
85
+ super(*args) || controller.respond_to?(*args)
59
86
  end
60
87
 
61
88
  private
62
89
 
63
- def method_missing(id, *args, &block)
64
- controller.send(id, *args, &block)
65
- end
90
+ def method_missing(id, *args, &block)
91
+ controller.send(id, *args, &block)
92
+ end
66
93
  end
67
94
  end
68
95
  end
@@ -32,7 +32,7 @@ module Authlogic
32
32
  # # Authlogic options go here
33
33
  # end
34
34
  #
35
- # class User < ActiveRecord::Base
35
+ # class User < ApplicationRecord
36
36
  # acts_as_authentic
37
37
  # end
38
38
  #
@@ -48,7 +48,7 @@ module Authlogic
48
48
  end
49
49
 
50
50
  def remote_ip
51
- self.ip
51
+ ip
52
52
  end
53
53
  end
54
54
 
@@ -56,10 +56,14 @@ module Authlogic
56
56
  Authlogic::Session::Base.controller = self
57
57
  end
58
58
 
59
- # Rack Requests stores cookies with not just the value, but also with flags and expire information in the hash.
60
- # Authlogic does not like this, so we drop everything except the cookie value
59
+ # Rack Requests stores cookies with not just the value, but also with
60
+ # flags and expire information in the hash. Authlogic does not like this,
61
+ # so we drop everything except the cookie value.
61
62
  def cookies
62
- controller.cookies.map { |key, value_hash| { key => value_hash[:value] } }.inject(:merge) || {}
63
+ controller
64
+ .cookies
65
+ .map { |key, value_hash| { key => value_hash[:value] } }
66
+ .inject(:merge) || {}
63
67
  end
64
68
  end
65
69
  end
@@ -1,4 +1,4 @@
1
- require 'action_controller'
1
+ require "action_controller"
2
2
 
3
3
  module Authlogic
4
4
  module ControllerAdapters
@@ -13,12 +13,14 @@ module Authlogic
13
13
  controller.authenticate_with_http_basic(&block)
14
14
  end
15
15
 
16
+ # Returns a `ActionDispatch::Cookies::CookieJar`. See the AC guide
17
+ # http://guides.rubyonrails.org/action_controller_overview.html#cookies
16
18
  def cookies
17
19
  controller.send(:cookies)
18
20
  end
19
21
 
20
22
  def cookie_domain
21
- @cookie_domain_key ||= Rails::VERSION::STRING >= '2.3' ? :domain : :session_domain
23
+ @cookie_domain_key ||= Rails::VERSION::STRING >= "2.3" ? :domain : :session_domain
22
24
  controller.request.session_options[@cookie_domain_key]
23
25
  end
24
26
 
@@ -32,7 +34,7 @@ module Authlogic
32
34
  def self.included(klass) # :nodoc:
33
35
  if defined?(::ApplicationController)
34
36
  raise AuthlogicLoadedTooLateError.new(
35
- <<-EOS.strip_heredoc
37
+ <<~EOS.squish
36
38
  Authlogic is trying to add a callback to ActionController::Base
37
39
  but ApplicationController has already been loaded, so the
38
40
  callback won't be copied into your application. Generally this
@@ -54,12 +56,15 @@ module Authlogic
54
56
 
55
57
  private
56
58
 
57
- def activate_authlogic
58
- Authlogic::Session::Base.controller = RailsAdapter.new(self)
59
- end
59
+ def activate_authlogic
60
+ Authlogic::Session::Base.controller = RailsAdapter.new(self)
61
+ end
60
62
  end
61
63
  end
62
64
  end
63
65
  end
64
66
 
65
- ActionController::Base.send(:include, Authlogic::ControllerAdapters::RailsAdapter::RailsImplementation)
67
+ ActionController::Base.send(
68
+ :include,
69
+ Authlogic::ControllerAdapters::RailsAdapter::RailsImplementation
70
+ )
@@ -32,7 +32,7 @@ module Authlogic
32
32
  end
33
33
 
34
34
  def session
35
- env['rack.session']
35
+ env["rack.session"]
36
36
  end
37
37
 
38
38
  def method_missing(meth, *args, &block)
@@ -42,7 +42,7 @@ module Authlogic
42
42
 
43
43
  class Adapter < AbstractAdapter
44
44
  def cookie_domain
45
- env['SERVER_NAME']
45
+ env["SERVER_NAME"]
46
46
  end
47
47
 
48
48
  module Implementation
@@ -2,21 +2,23 @@ require "openssl"
2
2
 
3
3
  module Authlogic
4
4
  module CryptoProviders
5
- # This encryption method is reversible if you have the supplied key. So in order to
6
- # use this encryption method you must supply it with a key first. In an initializer,
7
- # or before your application initializes, you should do the following:
5
+ # This encryption method is reversible if you have the supplied key. So in
6
+ # order to use this encryption method you must supply it with a key first.
7
+ # In an initializer, or before your application initializes, you should do
8
+ # the following:
8
9
  #
9
- # Authlogic::CryptoProviders::AES256.key = "my really long and unique key, preferably a bunch of random characters"
10
+ # Authlogic::CryptoProviders::AES256.key = "long, unique, and random key"
10
11
  #
11
- # My final comment is that this is a strong encryption method, but its main weakness
12
- # is that it's reversible. If you do not need to reverse the hash then you should
13
- # consider Sha512 or BCrypt instead.
12
+ # My final comment is that this is a strong encryption method, but its main
13
+ # weakness is that it's reversible. If you do not need to reverse the hash
14
+ # then you should consider Sha512 or BCrypt instead.
14
15
  #
15
- # Keep your key in a safe place, some even say the key should be stored on a separate
16
- # server. This won't hurt performance because the only time it will try and access the
17
- # key on the separate server is during initialization, which only happens once. The
18
- # reasoning behind this is if someone does compromise your server they won't have the
19
- # key also. Basically, you don't want to store the key with the lock.
16
+ # Keep your key in a safe place, some even say the key should be stored on a
17
+ # separate server. This won't hurt performance because the only time it will
18
+ # try and access the key on the separate server is during initialization,
19
+ # which only happens once. The reasoning behind this is if someone does
20
+ # compromise your server they won't have the key also. Basically, you don't
21
+ # want to store the key with the lock.
20
22
  class AES256
21
23
  class << self
22
24
  attr_writer :key
@@ -37,29 +39,32 @@ module Authlogic
37
39
 
38
40
  private
39
41
 
40
- def aes
41
- if @key.blank?
42
- raise ArgumentError.new(
43
- "You must provide a key like #{name}.key = my_key before using the #{name}"
44
- )
45
- end
46
-
47
- @aes ||= openssl_cipher_class.new("AES-256-ECB")
42
+ def aes
43
+ if @key.blank?
44
+ raise ArgumentError.new(
45
+ "You must provide a key like #{name}.key = my_key before using the #{name}"
46
+ )
48
47
  end
49
48
 
50
- # `::OpenSSL::Cipher::Cipher` has been deprecated since at least 2014,
51
- # in favor of `::OpenSSL::Cipher`, but a deprecation warning was not
52
- # printed until 2016
53
- # (https://github.com/ruby/openssl/commit/5c20a4c014) when openssl
54
- # became a gem. Its first release as a gem was 2.0.0, in ruby 2.4.
55
- # (See https://github.com/ruby/ruby/blob/v2_4_0/NEWS)
56
- def openssl_cipher_class
57
- if ::Gem::Version.new(::OpenSSL::VERSION) < ::Gem::Version.new("2.0.0")
58
- ::OpenSSL::Cipher::Cipher
59
- else
60
- ::OpenSSL::Cipher
61
- end
49
+ @aes ||= openssl_cipher_class.new("AES-256-ECB")
50
+ end
51
+
52
+ # `::OpenSSL::Cipher::Cipher` has been deprecated since at least 2014,
53
+ # in favor of `::OpenSSL::Cipher`, but a deprecation warning was not
54
+ # printed until 2016
55
+ # (https://github.com/ruby/openssl/commit/5c20a4c014) when openssl
56
+ # became a gem. Its first release as a gem was 2.0.0, in ruby 2.4.
57
+ # (See https://github.com/ruby/ruby/blob/v2_4_0/NEWS)
58
+ #
59
+ # When we eventually drop support for ruby < 2.4, we can probably also
60
+ # drop support for openssl gem < 2.
61
+ def openssl_cipher_class
62
+ if ::Gem::Version.new(::OpenSSL::VERSION) < ::Gem::Version.new("2.0.0")
63
+ ::OpenSSL::Cipher::Cipher
64
+ else
65
+ ::OpenSSL::Cipher
62
66
  end
67
+ end
63
68
  end
64
69
  end
65
70
  end
@@ -16,10 +16,18 @@ module Authlogic
16
16
  # require "benchmark"
17
17
  #
18
18
  # Benchmark.bm(18) do |x|
19
- # x.report("BCrypt (cost = 10:") { 100.times { BCrypt::Password.create("mypass", :cost => 10) } }
20
- # x.report("BCrypt (cost = 4:") { 100.times { BCrypt::Password.create("mypass", :cost => 4) } }
21
- # x.report("Sha512:") { 100.times { Digest::SHA512.hexdigest("mypass") } }
22
- # x.report("Sha1:") { 100.times { Digest::SHA1.hexdigest("mypass") } }
19
+ # x.report("BCrypt (cost = 10:") {
20
+ # 100.times { BCrypt::Password.create("mypass", :cost => 10) }
21
+ # }
22
+ # x.report("BCrypt (cost = 4:") {
23
+ # 100.times { BCrypt::Password.create("mypass", :cost => 4) }
24
+ # }
25
+ # x.report("Sha512:") {
26
+ # 100.times { Digest::SHA512.hexdigest("mypass") }
27
+ # }
28
+ # x.report("Sha1:") {
29
+ # 100.times { Digest::SHA1.hexdigest("mypass") }
30
+ # }
23
31
  # end
24
32
  #
25
33
  # user system total real
@@ -66,7 +74,7 @@ module Authlogic
66
74
 
67
75
  # Creates a BCrypt hash for the password passed.
68
76
  def encrypt(*tokens)
69
- ::BCrypt::Password.create(join_tokens(tokens), :cost => cost)
77
+ ::BCrypt::Password.create(join_tokens(tokens), cost: cost)
70
78
  end
71
79
 
72
80
  # Does the hash match the tokens? Uses the same tokens that were used to
@@ -90,17 +98,15 @@ module Authlogic
90
98
 
91
99
  private
92
100
 
93
- def join_tokens(tokens)
94
- tokens.flatten.join
95
- end
101
+ def join_tokens(tokens)
102
+ tokens.flatten.join
103
+ end
96
104
 
97
- def new_from_hash(hash)
98
- begin
99
- ::BCrypt::Password.new(hash)
100
- rescue ::BCrypt::Errors::InvalidHash
101
- return nil
102
- end
103
- end
105
+ def new_from_hash(hash)
106
+ ::BCrypt::Password.new(hash)
107
+ rescue ::BCrypt::Errors::InvalidHash
108
+ nil
109
+ end
104
110
  end
105
111
  end
106
112
  end
@@ -6,7 +6,8 @@ module Authlogic
6
6
  # I highly discourage using this crypto provider as it superbly inferior
7
7
  # to your other options.
8
8
  #
9
- # Please use any other provider offered by Authlogic.
9
+ # Please use any other provider offered by Authlogic (except AES256, that
10
+ # would be even worse).
10
11
  class MD5
11
12
  class << self
12
13
  attr_accessor :join_token
@@ -24,7 +25,8 @@ module Authlogic
24
25
  digest
25
26
  end
26
27
 
27
- # Does the crypted password match the tokens? Uses the same tokens that were used to encrypt.
28
+ # Does the crypted password match the tokens? Uses the same tokens that
29
+ # were used to encrypt.
28
30
  def matches?(crypted, *tokens)
29
31
  encrypt(*tokens) == crypted
30
32
  end
@@ -19,7 +19,13 @@ module Authlogic
19
19
  # end
20
20
  class SCrypt
21
21
  class << self
22
- DEFAULTS = { :key_len => 32, :salt_size => 8, :max_time => 0.2, :max_mem => 1024 * 1024, :max_memfrac => 0.5 }
22
+ DEFAULTS = {
23
+ key_len: 32,
24
+ salt_size: 8,
25
+ max_time: 0.2,
26
+ max_mem: 1024 * 1024,
27
+ max_memfrac: 0.5
28
+ }.freeze
23
29
 
24
30
  attr_writer :key_len, :salt_size, :max_time, :max_mem, :max_memfrac
25
31
  # Key length - length in bytes of generated key, from 16 to 512.
@@ -42,7 +48,8 @@ module Authlogic
42
48
  @max_mem ||= DEFAULTS[:max_mem]
43
49
  end
44
50
 
45
- # Max memory fraction - maximum memory out of all available. Always greater than zero and <= 0.5.
51
+ # Max memory fraction - maximum memory out of all available. Always
52
+ # greater than zero and <= 0.5.
46
53
  def max_memfrac
47
54
  @max_memfrac ||= DEFAULTS[:max_memfrac]
48
55
  end
@@ -51,11 +58,11 @@ module Authlogic
51
58
  def encrypt(*tokens)
52
59
  ::SCrypt::Password.create(
53
60
  join_tokens(tokens),
54
- :key_len => key_len,
55
- :salt_size => salt_size,
56
- :max_mem => max_mem,
57
- :max_memfrac => max_memfrac,
58
- :max_time => max_time
61
+ key_len: key_len,
62
+ salt_size: salt_size,
63
+ max_mem: max_mem,
64
+ max_memfrac: max_memfrac,
65
+ max_time: max_time
59
66
  )
60
67
  end
61
68
 
@@ -68,17 +75,15 @@ module Authlogic
68
75
 
69
76
  private
70
77
 
71
- def join_tokens(tokens)
72
- tokens.flatten.join
73
- end
78
+ def join_tokens(tokens)
79
+ tokens.flatten.join
80
+ end
74
81
 
75
- def new_from_hash(hash)
76
- begin
77
- ::SCrypt::Password.new(hash)
78
- rescue ::SCrypt::Errors::InvalidHash
79
- return nil
80
- end
81
- end
82
+ def new_from_hash(hash)
83
+ ::SCrypt::Password.new(hash)
84
+ rescue ::SCrypt::Errors::InvalidHash
85
+ nil
86
+ end
82
87
  end
83
88
  end
84
89
  end
@@ -2,8 +2,10 @@ require "digest/sha1"
2
2
 
3
3
  module Authlogic
4
4
  module CryptoProviders
5
- # This class was made for the users transitioning from restful_authentication. I highly discourage using this
6
- # crypto provider as it is far inferior to your other options. Please use any other provider offered by Authlogic.
5
+ # This class was made for the users transitioning from
6
+ # restful_authentication. Use of this crypto provider is highly discouraged.
7
+ # It is far inferior to your other options. Please use any other provider
8
+ # offered by Authlogic.
7
9
  class Sha1
8
10
  class << self
9
11
  def join_token
@@ -11,7 +13,8 @@ module Authlogic
11
13
  end
12
14
  attr_writer :join_token
13
15
 
14
- # The number of times to loop through the encryption. This is ten because that is what restful_authentication defaults to.
16
+ # The number of times to loop through the encryption. This is ten
17
+ # because that is what restful_authentication defaults to.
15
18
  def stretches
16
19
  @stretches ||= 10
17
20
  end
@@ -21,11 +24,14 @@ module Authlogic
21
24
  def encrypt(*tokens)
22
25
  tokens = tokens.flatten
23
26
  digest = tokens.shift
24
- stretches.times { digest = Digest::SHA1.hexdigest([digest, *tokens].join(join_token)) }
27
+ stretches.times do
28
+ digest = Digest::SHA1.hexdigest([digest, *tokens].join(join_token))
29
+ end
25
30
  digest
26
31
  end
27
32
 
28
- # Does the crypted password match the tokens? Uses the same tokens that were used to encrypt.
33
+ # Does the crypted password match the tokens? Uses the same tokens that
34
+ # were used to encrypt.
29
35
  def matches?(crypted, *tokens)
30
36
  encrypt(*tokens) == crypted
31
37
  end
@@ -1,22 +1,25 @@
1
1
  require "digest/sha2"
2
2
 
3
3
  module Authlogic
4
- # The acts_as_authentic method has a crypto_provider option. This allows you to use any type of encryption you like.
5
- # Just create a class with a class level encrypt and matches? method. See example below.
4
+ # The acts_as_authentic method has a crypto_provider option. This allows you
5
+ # to use any type of encryption you like. Just create a class with a class
6
+ # level encrypt and matches? method. See example below.
6
7
  #
7
8
  # === Example
8
9
  #
9
10
  # class MyAwesomeEncryptionMethod
10
11
  # def self.encrypt(*tokens)
11
- # # the tokens passed will be an array of objects, what type of object is irrelevant,
12
- # # just do what you need to do with them and return a single encrypted string.
13
- # # for example, you will most likely join all of the objects into a single string and then encrypt that string
12
+ # # the tokens passed will be an array of objects, what type of object
13
+ # # is irrelevant, just do what you need to do with them and return a
14
+ # # single encrypted string. for example, you will most likely join all
15
+ # # of the objects into a single string and then encrypt that string
14
16
  # end
15
17
  #
16
18
  # def self.matches?(crypted, *tokens)
17
- # # return true if the crypted string matches the tokens.
18
- # # depending on your algorithm you might decrypt the string then compare it to the token, or you might
19
- # # encrypt the tokens and make sure it matches the crypted string, its up to you
19
+ # # return true if the crypted string matches the tokens. Depending on
20
+ # # your algorithm you might decrypt the string then compare it to the
21
+ # # token, or you might encrypt the tokens and make sure it matches the
22
+ # # crypted string, its up to you.
20
23
  # end
21
24
  # end
22
25
  module CryptoProviders
@@ -40,7 +43,8 @@ module Authlogic
40
43
  digest
41
44
  end
42
45
 
43
- # Does the crypted password match the tokens? Uses the same tokens that were used to encrypt.
46
+ # Does the crypted password match the tokens? Uses the same tokens that
47
+ # were used to encrypt.
44
48
  def matches?(crypted, *tokens)
45
49
  encrypt(*tokens) == crypted
46
50
  end