Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deprecate passing a Class to ActiveSupport::Digest.hash_digest_class #39540

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
12 changes: 12 additions & 0 deletions activesupport/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
* Passing a Class to `ActiveSupport::Digest.hash_digest_class` is deprecated in favour of String.

Before:

ActiveSupport::Digest.hash_digest_class = OpenSSL::Digest::SHA256

After:

ActiveSupport::Digest.hash_digest_class = "SHA256"

*Vipul A M*

* `require_dependency` has been documented to be _obsolete_ in `:zeitwerk`
mode. The method is not deprecated as such (yet), but applications are
encouraged to not use it.
Expand Down
16 changes: 13 additions & 3 deletions activesupport/lib/active_support/digest.rb
Original file line number Diff line number Diff line change
@@ -1,19 +1,29 @@
# frozen_string_literal: true

require "openssl"

module ActiveSupport
class Digest #:nodoc:
class <<self
def hash_digest_class
@hash_digest_class ||= ::Digest::MD5
@hash_digest_class ||= "MD5"
end

def hash_digest_class=(klass)
raise ArgumentError, "#{klass} is expected to implement hexdigest class method" unless klass.respond_to?(:hexdigest)
unless klass.is_a?(String)
klass = klass.to_s.split("::").last.to_s
ActiveSupport::Deprecation.warn(<<~EOM)
Passing a Digest Class to `hash_digest_class=` is deprecated and will be removed in future
versions of Rails. Please pass a string instead (SHA1, SHA256, MD5, etc).
EOM
end

raise ArgumentError, "#{klass} is unsupported by OpenSSL::Digest" unless OpenSSL::Digest.const_defined?(klass)
@hash_digest_class = klass
end

def hexdigest(arg)
hash_digest_class.hexdigest(arg)[0...32]
OpenSSL::Digest.hexdigest(hash_digest_class, arg)[0...32]
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion activesupport/lib/active_support/railtie.rb
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ class Railtie < Rails::Railtie # :nodoc:
initializer "active_support.set_hash_digest_class" do |app|
config.after_initialize do
if app.config.active_support.use_sha1_digests
ActiveSupport::Digest.hash_digest_class = ::Digest::SHA1
ActiveSupport::Digest.hash_digest_class = "SHA1"
end
end
end
Expand Down
12 changes: 7 additions & 5 deletions activesupport/test/digest_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,24 @@
class DigestTest < ActiveSupport::TestCase
class InvalidDigest; end
def test_with_default_hash_digest_class
assert_equal ::Digest::MD5.hexdigest("hello friend"), ActiveSupport::Digest.hexdigest("hello friend")
assert_equal OpenSSL::Digest.hexdigest("MD5", "hello friend"), ActiveSupport::Digest.hexdigest("hello friend")
end

def test_with_custom_hash_digest_class
original_hash_digest_class = ActiveSupport::Digest.hash_digest_class

ActiveSupport::Digest.hash_digest_class = ::Digest::SHA1
ActiveSupport::Digest.hash_digest_class = "SHA1"
digest = ActiveSupport::Digest.hexdigest("hello friend")

assert_equal 32, digest.length
assert_equal ::Digest::SHA1.hexdigest("hello friend")[0...32], digest
assert_equal OpenSSL::Digest.hexdigest("SHA1", "hello friend")[0...32], digest
ensure
ActiveSupport::Digest.hash_digest_class = original_hash_digest_class
end

def test_should_raise_argument_error_if_custom_digest_is_missing_hexdigest_method
assert_raises(ArgumentError) { ActiveSupport::Digest.hash_digest_class = InvalidDigest }
assert_deprecated(/Passing a Digest Class to `hash_digest_class=` is deprecated and will be removed in future/) do
assert_raises(ArgumentError) { ActiveSupport::Digest.hash_digest_class = InvalidDigest }
assert_raises(ArgumentError) { ActiveSupport::Digest.hash_digest_class = "InvalidDigest" }
end
end
end
10 changes: 5 additions & 5 deletions railties/test/application/configuration_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2172,18 +2172,18 @@ class D < C
assert_equal true, ActiveSupport::MessageEncryptor.use_authenticated_message_encryption
end

test "ActiveSupport::Digest.hash_digest_class is Digest::SHA1 by default for new apps" do
test "ActiveSupport::Digest.hash_digest_class is SHA1 by default for new apps" do
app "development"

assert_equal Digest::SHA1, ActiveSupport::Digest.hash_digest_class
assert_equal "SHA1", ActiveSupport::Digest.hash_digest_class
end

test "ActiveSupport::Digest.hash_digest_class is Digest::MD5 by default for upgraded apps" do
test "ActiveSupport::Digest.hash_digest_class is MD5 by default for upgraded apps" do
remove_from_config '.*config\.load_defaults.*\n'

app "development"

assert_equal Digest::MD5, ActiveSupport::Digest.hash_digest_class
assert_equal "MD5", ActiveSupport::Digest.hash_digest_class
end

test "ActiveSupport::Digest.hash_digest_class can be configured via config.active_support.use_sha1_digests" do
Expand All @@ -2195,7 +2195,7 @@ class D < C

app "development"

assert_equal Digest::SHA1, ActiveSupport::Digest.hash_digest_class
assert_equal "SHA1", ActiveSupport::Digest.hash_digest_class
end

test "custom serializers should be able to set via config.active_job.custom_serializers in an initializer" do
Expand Down