Always use OpenSSL constants for Digest operations
As also previously discussed in https://github.com/rails/rails/pull/40770#issuecomment-748347066, this moves the usage of Digest constants to always use the OpenSSL version of those Digest implementations.
This commit is contained in:
parent
bead3221c7
commit
0523532a3c
|
@ -1,3 +1,7 @@
|
||||||
|
* OpenSSL constants are now used for Digest computations.
|
||||||
|
|
||||||
|
*Dirkjan Bussink*
|
||||||
|
|
||||||
* The Action Cable client now includes safeguards to prevent a "thundering
|
* The Action Cable client now includes safeguards to prevent a "thundering
|
||||||
herd" of client reconnects after server connectivity loss:
|
herd" of client reconnects after server connectivity loss:
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
gem "pg", "~> 1.1"
|
gem "pg", "~> 1.1"
|
||||||
require "pg"
|
require "pg"
|
||||||
require "thread"
|
require "thread"
|
||||||
require "digest/sha1"
|
require "openssl"
|
||||||
|
|
||||||
module ActionCable
|
module ActionCable
|
||||||
module SubscriptionAdapter
|
module SubscriptionAdapter
|
||||||
|
@ -58,7 +58,7 @@ module ActionCable
|
||||||
|
|
||||||
private
|
private
|
||||||
def channel_identifier(channel)
|
def channel_identifier(channel)
|
||||||
channel.size > 63 ? Digest::SHA1.hexdigest(channel) : channel
|
channel.size > 63 ? OpenSSL::Digest::SHA1.hexdigest(channel) : channel
|
||||||
end
|
end
|
||||||
|
|
||||||
def listener
|
def listener
|
||||||
|
|
|
@ -2,5 +2,8 @@
|
||||||
|
|
||||||
*Santiago Bartesaghi*
|
*Santiago Bartesaghi*
|
||||||
|
|
||||||
|
* OpenSSL constants are now used for Digest computations.
|
||||||
|
|
||||||
|
*Dirkjan Bussink*
|
||||||
|
|
||||||
Please check [6-1-stable](https://github.com/rails/rails/blob/6-1-stable/actionmailbox/CHANGELOG.md) for previous changes.
|
Please check [6-1-stable](https://github.com/rails/rails/blob/6-1-stable/actionmailbox/CHANGELOG.md) for previous changes.
|
||||||
|
|
|
@ -14,7 +14,7 @@ module ActionMailbox::InboundEmail::MessageId
|
||||||
# attachment called +raw_email+. Before the upload, extract the Message-ID from the +source+ and set
|
# attachment called +raw_email+. Before the upload, extract the Message-ID from the +source+ and set
|
||||||
# it as an attribute on the new +InboundEmail+.
|
# it as an attribute on the new +InboundEmail+.
|
||||||
def create_and_extract_message_id!(source, **options)
|
def create_and_extract_message_id!(source, **options)
|
||||||
message_checksum = Digest::SHA1.hexdigest(source)
|
message_checksum = OpenSSL::Digest::SHA1.hexdigest(source)
|
||||||
message_id = extract_message_id(source) || generate_missing_message_id(message_checksum)
|
message_id = extract_message_id(source) || generate_missing_message_id(message_checksum)
|
||||||
|
|
||||||
create! raw_email: create_and_upload_raw_email!(source),
|
create! raw_email: create_and_upload_raw_email!(source),
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
* OpenSSL constants are now used for Digest computations.
|
||||||
|
|
||||||
|
*Dirkjan Bussink*
|
||||||
|
|
||||||
* Remove IE6-7-8 file download related hack/fix from ActionController::DataStreaming module
|
* Remove IE6-7-8 file download related hack/fix from ActionController::DataStreaming module
|
||||||
|
|
||||||
Due to the age of those versions of IE this fix is no longer relevant, more importantly it creates an edge-case for unexpected Cache-Control headers.
|
Due to the age of those versions of IE this fix is no longer relevant, more importantly it creates an edge-case for unexpected Cache-Control headers.
|
||||||
|
|
|
@ -138,11 +138,11 @@ module ActionController
|
||||||
#
|
#
|
||||||
# === Simple \Digest example
|
# === Simple \Digest example
|
||||||
#
|
#
|
||||||
# require "digest/md5"
|
# require "openssl"
|
||||||
# class PostsController < ApplicationController
|
# class PostsController < ApplicationController
|
||||||
# REALM = "SuperSecret"
|
# REALM = "SuperSecret"
|
||||||
# USERS = {"dhh" => "secret", #plain text password
|
# USERS = {"dhh" => "secret", #plain text password
|
||||||
# "dap" => Digest::MD5.hexdigest(["dap",REALM,"secret"].join(":"))} #ha1 digest password
|
# "dap" => OpenSSL::Digest::MD5.hexdigest(["dap",REALM,"secret"].join(":"))} #ha1 digest password
|
||||||
#
|
#
|
||||||
# before_action :authenticate, except: [:index]
|
# before_action :authenticate, except: [:index]
|
||||||
#
|
#
|
||||||
|
@ -230,12 +230,12 @@ module ActionController
|
||||||
# of a plain-text password.
|
# of a plain-text password.
|
||||||
def expected_response(http_method, uri, credentials, password, password_is_ha1 = true)
|
def expected_response(http_method, uri, credentials, password, password_is_ha1 = true)
|
||||||
ha1 = password_is_ha1 ? password : ha1(credentials, password)
|
ha1 = password_is_ha1 ? password : ha1(credentials, password)
|
||||||
ha2 = ::Digest::MD5.hexdigest([http_method.to_s.upcase, uri].join(":"))
|
ha2 = OpenSSL::Digest::MD5.hexdigest([http_method.to_s.upcase, uri].join(":"))
|
||||||
::Digest::MD5.hexdigest([ha1, credentials[:nonce], credentials[:nc], credentials[:cnonce], credentials[:qop], ha2].join(":"))
|
OpenSSL::Digest::MD5.hexdigest([ha1, credentials[:nonce], credentials[:nc], credentials[:cnonce], credentials[:qop], ha2].join(":"))
|
||||||
end
|
end
|
||||||
|
|
||||||
def ha1(credentials, password)
|
def ha1(credentials, password)
|
||||||
::Digest::MD5.hexdigest([credentials[:username], credentials[:realm], password].join(":"))
|
OpenSSL::Digest::MD5.hexdigest([credentials[:username], credentials[:realm], password].join(":"))
|
||||||
end
|
end
|
||||||
|
|
||||||
def encode_credentials(http_method, credentials, password, password_is_ha1)
|
def encode_credentials(http_method, credentials, password, password_is_ha1)
|
||||||
|
@ -309,7 +309,7 @@ module ActionController
|
||||||
def nonce(secret_key, time = Time.now)
|
def nonce(secret_key, time = Time.now)
|
||||||
t = time.to_i
|
t = time.to_i
|
||||||
hashed = [t, secret_key]
|
hashed = [t, secret_key]
|
||||||
digest = ::Digest::MD5.hexdigest(hashed.join(":"))
|
digest = OpenSSL::Digest::MD5.hexdigest(hashed.join(":"))
|
||||||
::Base64.strict_encode64("#{t}:#{digest}")
|
::Base64.strict_encode64("#{t}:#{digest}")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -326,7 +326,7 @@ module ActionController
|
||||||
|
|
||||||
# Opaque based on digest of secret key
|
# Opaque based on digest of secret key
|
||||||
def opaque(secret_key)
|
def opaque(secret_key)
|
||||||
::Digest::MD5.hexdigest(secret_key)
|
OpenSSL::Digest::MD5.hexdigest(secret_key)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ class HttpDigestAuthenticationTest < ActionController::TestCase
|
||||||
before_action :authenticate_with_request, only: :display
|
before_action :authenticate_with_request, only: :display
|
||||||
|
|
||||||
USERS = { "lifo" => "world", "pretty" => "please",
|
USERS = { "lifo" => "world", "pretty" => "please",
|
||||||
"dhh" => ::Digest::MD5.hexdigest(["dhh", "SuperSecret", "secret"].join(":")) }
|
"dhh" => OpenSSL::Digest::MD5.hexdigest(["dhh", "SuperSecret", "secret"].join(":")) }
|
||||||
|
|
||||||
def index
|
def index
|
||||||
render plain: "Hello Secret"
|
render plain: "Hello Secret"
|
||||||
|
@ -185,7 +185,7 @@ class HttpDigestAuthenticationTest < ActionController::TestCase
|
||||||
test "authentication request with password stored as ha1 digest hash" do
|
test "authentication request with password stored as ha1 digest hash" do
|
||||||
@request.env["HTTP_AUTHORIZATION"] = encode_credentials(
|
@request.env["HTTP_AUTHORIZATION"] = encode_credentials(
|
||||||
username: "dhh",
|
username: "dhh",
|
||||||
password: ::Digest::MD5.hexdigest(["dhh", "SuperSecret", "secret"].join(":")),
|
password: OpenSSL::Digest::MD5.hexdigest(["dhh", "SuperSecret", "secret"].join(":")),
|
||||||
password_is_ha1: true)
|
password_is_ha1: true)
|
||||||
get :display
|
get :display
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
* OpenSSL constants are now used for Digest computations.
|
||||||
|
|
||||||
|
*Dirkjan Bussink*
|
||||||
|
|
||||||
* Add support for passing `form:` option to `rich_text_area_tag` and
|
* Add support for passing `form:` option to `rich_text_area_tag` and
|
||||||
`rich_text_area` helpers to specify the `<input type="hidden" form="...">`
|
`rich_text_area` helpers to specify the `<input type="hidden" form="...">`
|
||||||
value.
|
value.
|
||||||
|
|
|
@ -9,7 +9,7 @@ module ActionText
|
||||||
|
|
||||||
private
|
private
|
||||||
def cache_digest
|
def cache_digest
|
||||||
Digest::SHA256.hexdigest(node.to_s)
|
OpenSSL::Digest::SHA256.hexdigest(node.to_s)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
* OpenSSL constants are now used for Digest computations.
|
||||||
|
|
||||||
|
*Dirkjan Bussink*
|
||||||
|
|
||||||
* The `translate` helper now passes `default` values that aren't
|
* The `translate` helper now passes `default` values that aren't
|
||||||
translation keys through `I18n.translate` for interpolation.
|
translation keys through `I18n.translate` for interpolation.
|
||||||
|
|
||||||
|
|
|
@ -65,7 +65,7 @@ module ActionView
|
||||||
# +asset_host+ to a proc like this:
|
# +asset_host+ to a proc like this:
|
||||||
#
|
#
|
||||||
# ActionController::Base.asset_host = Proc.new { |source|
|
# ActionController::Base.asset_host = Proc.new { |source|
|
||||||
# "http://assets#{Digest::MD5.hexdigest(source).to_i(16) % 2 + 1}.example.com"
|
# "http://assets#{OpenSSL::Digest::SHA256.hexdigest(source).to_i(16) % 2 + 1}.example.com"
|
||||||
# }
|
# }
|
||||||
# image_tag("rails.png")
|
# image_tag("rails.png")
|
||||||
# # => <img src="http://assets1.example.com/assets/rails.png" />
|
# # => <img src="http://assets1.example.com/assets/rails.png" />
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
* OpenSSL constants are now used for Digest computations.
|
||||||
|
|
||||||
|
*Dirkjan Bussink*
|
||||||
|
|
||||||
* Add a Serializer for the Range class
|
* Add a Serializer for the Range class
|
||||||
|
|
||||||
This should allow things like `MyJob.perform_later(range: 1..100)`
|
This should allow things like `MyJob.perform_later(range: 1..100)`
|
||||||
|
|
|
@ -31,7 +31,7 @@ module SneakersJobsManager
|
||||||
@pid = fork do
|
@pid = fork do
|
||||||
queues = %w(integration_tests)
|
queues = %w(integration_tests)
|
||||||
workers = queues.map do |q|
|
workers = queues.map do |q|
|
||||||
worker_klass = "ActiveJobWorker" + Digest::MD5.hexdigest(q)
|
worker_klass = "ActiveJobWorker" + OpenSSL::Digest::MD5.hexdigest(q)
|
||||||
Sneakers.const_set(worker_klass, Class.new(ActiveJob::QueueAdapters::SneakersAdapter::JobWrapper) do
|
Sneakers.const_set(worker_klass, Class.new(ActiveJob::QueueAdapters::SneakersAdapter::JobWrapper) do
|
||||||
from_queue q
|
from_queue q
|
||||||
end)
|
end)
|
||||||
|
|
|
@ -1,5 +1,11 @@
|
||||||
|
* OpenSSL constants are now used for Digest computations.
|
||||||
|
|
||||||
|
*Dirkjan Bussink*
|
||||||
|
|
||||||
* Relation#destroy_all perform its work in batches
|
* Relation#destroy_all perform its work in batches
|
||||||
|
|
||||||
|
* Prevent double saves in autosave of cyclic associations
|
||||||
|
|
||||||
Since destroy_all actually loads the entire relation and then iteratively destroys the records one by one,
|
Since destroy_all actually loads the entire relation and then iteratively destroys the records one by one,
|
||||||
you can blow your memory gasket very easily. So let's do the right thing by default
|
you can blow your memory gasket very easily. So let's do the right thing by default
|
||||||
and do this work in batches of 100 by default and allow you to specify
|
and do this work in batches of 100 by default and allow you to specify
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require "active_support/core_ext/string/access"
|
require "active_support/core_ext/string/access"
|
||||||
require "digest/sha2"
|
require "openssl"
|
||||||
|
|
||||||
module ActiveRecord
|
module ActiveRecord
|
||||||
module ConnectionAdapters # :nodoc:
|
module ConnectionAdapters # :nodoc:
|
||||||
|
@ -1532,7 +1532,7 @@ module ActiveRecord
|
||||||
def foreign_key_name(table_name, options)
|
def foreign_key_name(table_name, options)
|
||||||
options.fetch(:name) do
|
options.fetch(:name) do
|
||||||
identifier = "#{table_name}_#{options.fetch(:column)}_fk"
|
identifier = "#{table_name}_#{options.fetch(:column)}_fk"
|
||||||
hashed_identifier = Digest::SHA256.hexdigest(identifier).first(10)
|
hashed_identifier = OpenSSL::Digest::SHA256.hexdigest(identifier).first(10)
|
||||||
|
|
||||||
"fk_rails_#{hashed_identifier}"
|
"fk_rails_#{hashed_identifier}"
|
||||||
end
|
end
|
||||||
|
@ -1560,7 +1560,7 @@ module ActiveRecord
|
||||||
options.fetch(:name) do
|
options.fetch(:name) do
|
||||||
expression = options.fetch(:expression)
|
expression = options.fetch(:expression)
|
||||||
identifier = "#{table_name}_#{expression}_chk"
|
identifier = "#{table_name}_#{expression}_chk"
|
||||||
hashed_identifier = Digest::SHA256.hexdigest(identifier).first(10)
|
hashed_identifier = OpenSSL::Digest::SHA256.hexdigest(identifier).first(10)
|
||||||
|
|
||||||
"chk_rails_#{hashed_identifier}"
|
"chk_rails_#{hashed_identifier}"
|
||||||
end
|
end
|
||||||
|
|
|
@ -592,7 +592,7 @@ module ActiveRecord
|
||||||
end
|
end
|
||||||
|
|
||||||
def schema_sha1(file)
|
def schema_sha1(file)
|
||||||
Digest::SHA1.hexdigest(File.read(file))
|
OpenSSL::Digest::SHA1.hexdigest(File.read(file))
|
||||||
end
|
end
|
||||||
|
|
||||||
def structure_dump_flags_for(adapter)
|
def structure_dump_flags_for(adapter)
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
* OpenSSL constants are now used for Digest computations.
|
||||||
|
|
||||||
|
*Dirkjan Bussink*
|
||||||
|
|
||||||
* Deprecate `config.active_storage.replace_on_assign_to_many`. Future versions of Rails
|
* Deprecate `config.active_storage.replace_on_assign_to_many`. Future versions of Rails
|
||||||
will behave the same way as when the config is set to `true`.
|
will behave the same way as when the config is set to `true`.
|
||||||
|
|
||||||
|
|
|
@ -305,7 +305,7 @@ class ActiveStorage::Blob < ActiveStorage::Record
|
||||||
|
|
||||||
private
|
private
|
||||||
def compute_checksum_in_chunks(io)
|
def compute_checksum_in_chunks(io)
|
||||||
Digest::MD5.new.tap do |checksum|
|
OpenSSL::Digest::MD5.new.tap do |checksum|
|
||||||
while chunk = io.read(5.megabytes)
|
while chunk = io.read(5.megabytes)
|
||||||
checksum << chunk
|
checksum << chunk
|
||||||
end
|
end
|
||||||
|
|
|
@ -67,7 +67,7 @@ class ActiveStorage::Variant
|
||||||
|
|
||||||
# Returns a combination key of the blob and the variation that together identifies a specific variant.
|
# Returns a combination key of the blob and the variation that together identifies a specific variant.
|
||||||
def key
|
def key
|
||||||
"variants/#{blob.key}/#{Digest::SHA256.hexdigest(variation.key)}"
|
"variants/#{blob.key}/#{OpenSSL::Digest::SHA256.hexdigest(variation.key)}"
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns the URL of the blob variant on the service. See {ActiveStorage::Blob#url} for details.
|
# Returns the URL of the blob variant on the service. See {ActiveStorage::Blob#url} for details.
|
||||||
|
|
|
@ -75,7 +75,7 @@ class ActiveStorage::Variation
|
||||||
end
|
end
|
||||||
|
|
||||||
def digest
|
def digest
|
||||||
Digest::SHA1.base64digest Marshal.dump(transformations)
|
OpenSSL::Digest::SHA1.base64digest Marshal.dump(transformations)
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
|
@ -35,7 +35,7 @@ module ActiveStorage
|
||||||
end
|
end
|
||||||
|
|
||||||
def verify_integrity_of(file, checksum:)
|
def verify_integrity_of(file, checksum:)
|
||||||
unless Digest::MD5.file(file).base64digest == checksum
|
unless OpenSSL::Digest::MD5.file(file).base64digest == checksum
|
||||||
raise ActiveStorage::IntegrityError
|
raise ActiveStorage::IntegrityError
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
require "fileutils"
|
require "fileutils"
|
||||||
require "pathname"
|
require "pathname"
|
||||||
require "digest/md5"
|
require "openssl"
|
||||||
require "active_support/core_ext/numeric/bytes"
|
require "active_support/core_ext/numeric/bytes"
|
||||||
|
|
||||||
module ActiveStorage
|
module ActiveStorage
|
||||||
|
@ -158,7 +158,7 @@ module ActiveStorage
|
||||||
end
|
end
|
||||||
|
|
||||||
def ensure_integrity_of(key, checksum)
|
def ensure_integrity_of(key, checksum)
|
||||||
unless Digest::MD5.file(path_for(key)).base64digest == checksum
|
unless OpenSSL::Digest::MD5.file(path_for(key)).base64digest == checksum
|
||||||
delete key
|
delete key
|
||||||
raise ActiveStorage::IntegrityError
|
raise ActiveStorage::IntegrityError
|
||||||
end
|
end
|
||||||
|
|
|
@ -15,7 +15,7 @@ if SERVICE_CONFIGURATIONS[:s3] && SERVICE_CONFIGURATIONS[:s3][:access_key_id].pr
|
||||||
end
|
end
|
||||||
|
|
||||||
test "creating new direct upload" do
|
test "creating new direct upload" do
|
||||||
checksum = Digest::MD5.base64digest("Hello")
|
checksum = OpenSSL::Digest::MD5.base64digest("Hello")
|
||||||
metadata = {
|
metadata = {
|
||||||
"foo": "bar",
|
"foo": "bar",
|
||||||
"my_key_1": "my_value_1",
|
"my_key_1": "my_value_1",
|
||||||
|
@ -58,7 +58,7 @@ if SERVICE_CONFIGURATIONS[:gcs]
|
||||||
end
|
end
|
||||||
|
|
||||||
test "creating new direct upload" do
|
test "creating new direct upload" do
|
||||||
checksum = Digest::MD5.base64digest("Hello")
|
checksum = OpenSSL::Digest::MD5.base64digest("Hello")
|
||||||
metadata = {
|
metadata = {
|
||||||
"foo": "bar",
|
"foo": "bar",
|
||||||
"my_key_1": "my_value_1",
|
"my_key_1": "my_value_1",
|
||||||
|
@ -100,7 +100,7 @@ if SERVICE_CONFIGURATIONS[:azure]
|
||||||
end
|
end
|
||||||
|
|
||||||
test "creating new direct upload" do
|
test "creating new direct upload" do
|
||||||
checksum = Digest::MD5.base64digest("Hello")
|
checksum = OpenSSL::Digest::MD5.base64digest("Hello")
|
||||||
metadata = {
|
metadata = {
|
||||||
"foo": "bar",
|
"foo": "bar",
|
||||||
"my_key_1": "my_value_1",
|
"my_key_1": "my_value_1",
|
||||||
|
@ -130,7 +130,7 @@ end
|
||||||
|
|
||||||
class ActiveStorage::DiskDirectUploadsControllerTest < ActionDispatch::IntegrationTest
|
class ActiveStorage::DiskDirectUploadsControllerTest < ActionDispatch::IntegrationTest
|
||||||
test "creating new direct upload" do
|
test "creating new direct upload" do
|
||||||
checksum = Digest::MD5.base64digest("Hello")
|
checksum = OpenSSL::Digest::MD5.base64digest("Hello")
|
||||||
metadata = {
|
metadata = {
|
||||||
"foo": "bar",
|
"foo": "bar",
|
||||||
"my_key_1": "my_value_1",
|
"my_key_1": "my_value_1",
|
||||||
|
@ -155,7 +155,7 @@ class ActiveStorage::DiskDirectUploadsControllerTest < ActionDispatch::Integrati
|
||||||
end
|
end
|
||||||
|
|
||||||
test "creating new direct upload does not include root in json" do
|
test "creating new direct upload does not include root in json" do
|
||||||
checksum = Digest::MD5.base64digest("Hello")
|
checksum = OpenSSL::Digest::MD5.base64digest("Hello")
|
||||||
metadata = {
|
metadata = {
|
||||||
"foo": "bar",
|
"foo": "bar",
|
||||||
"my_key_1": "my_value_1",
|
"my_key_1": "my_value_1",
|
||||||
|
|
|
@ -67,7 +67,7 @@ class ActiveStorage::DiskControllerTest < ActionDispatch::IntegrationTest
|
||||||
|
|
||||||
test "directly uploading blob with integrity" do
|
test "directly uploading blob with integrity" do
|
||||||
data = "Something else entirely!"
|
data = "Something else entirely!"
|
||||||
blob = create_blob_before_direct_upload byte_size: data.size, checksum: Digest::MD5.base64digest(data)
|
blob = create_blob_before_direct_upload byte_size: data.size, checksum: OpenSSL::Digest::MD5.base64digest(data)
|
||||||
|
|
||||||
put blob.service_url_for_direct_upload, params: data, headers: { "Content-Type" => "text/plain" }
|
put blob.service_url_for_direct_upload, params: data, headers: { "Content-Type" => "text/plain" }
|
||||||
assert_response :no_content
|
assert_response :no_content
|
||||||
|
@ -76,7 +76,7 @@ class ActiveStorage::DiskControllerTest < ActionDispatch::IntegrationTest
|
||||||
|
|
||||||
test "directly uploading blob without integrity" do
|
test "directly uploading blob without integrity" do
|
||||||
data = "Something else entirely!"
|
data = "Something else entirely!"
|
||||||
blob = create_blob_before_direct_upload byte_size: data.size, checksum: Digest::MD5.base64digest("bad data")
|
blob = create_blob_before_direct_upload byte_size: data.size, checksum: OpenSSL::Digest::MD5.base64digest("bad data")
|
||||||
|
|
||||||
put blob.service_url_for_direct_upload, params: data
|
put blob.service_url_for_direct_upload, params: data
|
||||||
assert_response :unprocessable_entity
|
assert_response :unprocessable_entity
|
||||||
|
@ -85,7 +85,7 @@ class ActiveStorage::DiskControllerTest < ActionDispatch::IntegrationTest
|
||||||
|
|
||||||
test "directly uploading blob with mismatched content type" do
|
test "directly uploading blob with mismatched content type" do
|
||||||
data = "Something else entirely!"
|
data = "Something else entirely!"
|
||||||
blob = create_blob_before_direct_upload byte_size: data.size, checksum: Digest::MD5.base64digest(data)
|
blob = create_blob_before_direct_upload byte_size: data.size, checksum: OpenSSL::Digest::MD5.base64digest(data)
|
||||||
|
|
||||||
put blob.service_url_for_direct_upload, params: data, headers: { "Content-Type" => "application/octet-stream" }
|
put blob.service_url_for_direct_upload, params: data, headers: { "Content-Type" => "application/octet-stream" }
|
||||||
assert_response :unprocessable_entity
|
assert_response :unprocessable_entity
|
||||||
|
@ -95,7 +95,7 @@ class ActiveStorage::DiskControllerTest < ActionDispatch::IntegrationTest
|
||||||
test "directly uploading blob with different but equivalent content type" do
|
test "directly uploading blob with different but equivalent content type" do
|
||||||
data = "Something else entirely!"
|
data = "Something else entirely!"
|
||||||
blob = create_blob_before_direct_upload(
|
blob = create_blob_before_direct_upload(
|
||||||
byte_size: data.size, checksum: Digest::MD5.base64digest(data), content_type: "application/x-gzip")
|
byte_size: data.size, checksum: OpenSSL::Digest::MD5.base64digest(data), content_type: "application/x-gzip")
|
||||||
|
|
||||||
put blob.service_url_for_direct_upload, params: data, headers: { "Content-Type" => "application/x-gzip" }
|
put blob.service_url_for_direct_upload, params: data, headers: { "Content-Type" => "application/x-gzip" }
|
||||||
assert_response :no_content
|
assert_response :no_content
|
||||||
|
@ -104,7 +104,7 @@ class ActiveStorage::DiskControllerTest < ActionDispatch::IntegrationTest
|
||||||
|
|
||||||
test "directly uploading blob with mismatched content length" do
|
test "directly uploading blob with mismatched content length" do
|
||||||
data = "Something else entirely!"
|
data = "Something else entirely!"
|
||||||
blob = create_blob_before_direct_upload byte_size: data.size - 1, checksum: Digest::MD5.base64digest(data)
|
blob = create_blob_before_direct_upload byte_size: data.size - 1, checksum: OpenSSL::Digest::MD5.base64digest(data)
|
||||||
|
|
||||||
put blob.service_url_for_direct_upload, params: data, headers: { "Content-Type" => "text/plain" }
|
put blob.service_url_for_direct_upload, params: data, headers: { "Content-Type" => "text/plain" }
|
||||||
assert_response :unprocessable_entity
|
assert_response :unprocessable_entity
|
||||||
|
|
|
@ -38,7 +38,7 @@ class ActiveStorage::BlobTest < ActiveSupport::TestCase
|
||||||
|
|
||||||
assert_equal data, blob.download
|
assert_equal data, blob.download
|
||||||
assert_equal data.length, blob.byte_size
|
assert_equal data.length, blob.byte_size
|
||||||
assert_equal Digest::MD5.base64digest(data), blob.checksum
|
assert_equal OpenSSL::Digest::MD5.base64digest(data), blob.checksum
|
||||||
end
|
end
|
||||||
|
|
||||||
test "create_and_upload extracts content type from data" do
|
test "create_and_upload extracts content type from data" do
|
||||||
|
@ -129,7 +129,7 @@ class ActiveStorage::BlobTest < ActiveSupport::TestCase
|
||||||
|
|
||||||
test "open without integrity" do
|
test "open without integrity" do
|
||||||
create_blob(data: "Hello, world!").tap do |blob|
|
create_blob(data: "Hello, world!").tap do |blob|
|
||||||
blob.update! checksum: Digest::MD5.base64digest("Goodbye, world!")
|
blob.update! checksum: OpenSSL::Digest::MD5.base64digest("Goodbye, world!")
|
||||||
|
|
||||||
assert_raises ActiveStorage::IntegrityError do
|
assert_raises ActiveStorage::IntegrityError do
|
||||||
blob.open { |file| flunk "Expected integrity check to fail" }
|
blob.open { |file| flunk "Expected integrity check to fail" }
|
||||||
|
|
|
@ -21,7 +21,7 @@ if SERVICE_CONFIGURATIONS[:azure_public]
|
||||||
test "direct upload" do
|
test "direct upload" do
|
||||||
key = SecureRandom.base58(24)
|
key = SecureRandom.base58(24)
|
||||||
data = "Something else entirely!"
|
data = "Something else entirely!"
|
||||||
checksum = Digest::MD5.base64digest(data)
|
checksum = OpenSSL::Digest::MD5.base64digest(data)
|
||||||
content_type = "text/xml"
|
content_type = "text/xml"
|
||||||
url = @service.url_for_direct_upload(key, expires_in: 5.minutes, content_type: content_type, content_length: data.size, checksum: checksum)
|
url = @service.url_for_direct_upload(key, expires_in: 5.minutes, content_type: content_type, content_length: data.size, checksum: checksum)
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ if SERVICE_CONFIGURATIONS[:azure]
|
||||||
test "direct upload with content type" do
|
test "direct upload with content type" do
|
||||||
key = SecureRandom.base58(24)
|
key = SecureRandom.base58(24)
|
||||||
data = "Something else entirely!"
|
data = "Something else entirely!"
|
||||||
checksum = Digest::MD5.base64digest(data)
|
checksum = OpenSSL::Digest::MD5.base64digest(data)
|
||||||
content_type = "text/xml"
|
content_type = "text/xml"
|
||||||
url = @service.url_for_direct_upload(key, expires_in: 5.minutes, content_type: content_type, content_length: data.size, checksum: checksum)
|
url = @service.url_for_direct_upload(key, expires_in: 5.minutes, content_type: content_type, content_length: data.size, checksum: checksum)
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ if SERVICE_CONFIGURATIONS[:azure]
|
||||||
test "direct upload with content disposition" do
|
test "direct upload with content disposition" do
|
||||||
key = SecureRandom.base58(24)
|
key = SecureRandom.base58(24)
|
||||||
data = "Something else entirely!"
|
data = "Something else entirely!"
|
||||||
checksum = Digest::MD5.base64digest(data)
|
checksum = OpenSSL::Digest::MD5.base64digest(data)
|
||||||
url = @service.url_for_direct_upload(key, expires_in: 5.minutes, content_type: "text/plain", content_length: data.size, checksum: checksum)
|
url = @service.url_for_direct_upload(key, expires_in: 5.minutes, content_type: "text/plain", content_length: data.size, checksum: checksum)
|
||||||
|
|
||||||
uri = URI.parse url
|
uri = URI.parse url
|
||||||
|
@ -56,7 +56,7 @@ if SERVICE_CONFIGURATIONS[:azure]
|
||||||
key = SecureRandom.base58(24)
|
key = SecureRandom.base58(24)
|
||||||
data = "Foobar"
|
data = "Foobar"
|
||||||
|
|
||||||
@service.upload(key, StringIO.new(data), checksum: Digest::MD5.base64digest(data), filename: ActiveStorage::Filename.new("test.txt"), content_type: "text/plain")
|
@service.upload(key, StringIO.new(data), checksum: OpenSSL::Digest::MD5.base64digest(data), filename: ActiveStorage::Filename.new("test.txt"), content_type: "text/plain")
|
||||||
|
|
||||||
url = @service.url(key, expires_in: 2.minutes, disposition: :attachment, content_type: nil, filename: ActiveStorage::Filename.new("test.html"))
|
url = @service.url(key, expires_in: 2.minutes, disposition: :attachment, content_type: nil, filename: ActiveStorage::Filename.new("test.html"))
|
||||||
response = Net::HTTP.get_response(URI(url))
|
response = Net::HTTP.get_response(URI(url))
|
||||||
|
@ -70,7 +70,7 @@ if SERVICE_CONFIGURATIONS[:azure]
|
||||||
key = SecureRandom.base58(24)
|
key = SecureRandom.base58(24)
|
||||||
data = "Foobar"
|
data = "Foobar"
|
||||||
|
|
||||||
@service.upload(key, StringIO.new(data), checksum: Digest::MD5.base64digest(data), filename: ActiveStorage::Filename.new("test.txt"), disposition: :inline)
|
@service.upload(key, StringIO.new(data), checksum: OpenSSL::Digest::MD5.base64digest(data), filename: ActiveStorage::Filename.new("test.txt"), disposition: :inline)
|
||||||
|
|
||||||
assert_equal("inline; filename=\"test.txt\"; filename*=UTF-8''test.txt", @service.client.get_blob_properties(@service.container, key).properties[:content_disposition])
|
assert_equal("inline; filename=\"test.txt\"; filename*=UTF-8''test.txt", @service.client.get_blob_properties(@service.container, key).properties[:content_disposition])
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ if SERVICE_CONFIGURATIONS[:gcs_public]
|
||||||
test "direct upload" do
|
test "direct upload" do
|
||||||
key = SecureRandom.base58(24)
|
key = SecureRandom.base58(24)
|
||||||
data = "Something else entirely!"
|
data = "Something else entirely!"
|
||||||
checksum = Digest::MD5.base64digest(data)
|
checksum = OpenSSL::Digest::MD5.base64digest(data)
|
||||||
url = @service.url_for_direct_upload(key, expires_in: 5.minutes, content_type: "text/plain", content_length: data.size, checksum: checksum)
|
url = @service.url_for_direct_upload(key, expires_in: 5.minutes, content_type: "text/plain", content_length: data.size, checksum: checksum)
|
||||||
|
|
||||||
uri = URI.parse url
|
uri = URI.parse url
|
||||||
|
|
|
@ -16,7 +16,7 @@ if SERVICE_CONFIGURATIONS[:gcs]
|
||||||
test "direct upload" do
|
test "direct upload" do
|
||||||
key = SecureRandom.base58(24)
|
key = SecureRandom.base58(24)
|
||||||
data = "Something else entirely!"
|
data = "Something else entirely!"
|
||||||
checksum = Digest::MD5.base64digest(data)
|
checksum = OpenSSL::Digest::MD5.base64digest(data)
|
||||||
url = @service.url_for_direct_upload(key, expires_in: 5.minutes, content_type: "text/plain", content_length: data.size, checksum: checksum)
|
url = @service.url_for_direct_upload(key, expires_in: 5.minutes, content_type: "text/plain", content_length: data.size, checksum: checksum)
|
||||||
|
|
||||||
uri = URI.parse url
|
uri = URI.parse url
|
||||||
|
@ -36,7 +36,7 @@ if SERVICE_CONFIGURATIONS[:gcs]
|
||||||
test "direct upload with content disposition" do
|
test "direct upload with content disposition" do
|
||||||
key = SecureRandom.base58(24)
|
key = SecureRandom.base58(24)
|
||||||
data = "Something else entirely!"
|
data = "Something else entirely!"
|
||||||
checksum = Digest::MD5.base64digest(data)
|
checksum = OpenSSL::Digest::MD5.base64digest(data)
|
||||||
url = @service.url_for_direct_upload(key, expires_in: 5.minutes, content_type: "text/plain", content_length: data.size, checksum: checksum)
|
url = @service.url_for_direct_upload(key, expires_in: 5.minutes, content_type: "text/plain", content_length: data.size, checksum: checksum)
|
||||||
|
|
||||||
uri = URI.parse url
|
uri = URI.parse url
|
||||||
|
@ -91,7 +91,7 @@ if SERVICE_CONFIGURATIONS[:gcs]
|
||||||
key = SecureRandom.base58(24)
|
key = SecureRandom.base58(24)
|
||||||
data = "Something else entirely!"
|
data = "Something else entirely!"
|
||||||
|
|
||||||
@service.upload(key, StringIO.new(data), checksum: Digest::MD5.base64digest(data), disposition: :attachment, filename: ActiveStorage::Filename.new("test.txt"), content_type: "text/plain")
|
@service.upload(key, StringIO.new(data), checksum: OpenSSL::Digest::MD5.base64digest(data), disposition: :attachment, filename: ActiveStorage::Filename.new("test.txt"), content_type: "text/plain")
|
||||||
|
|
||||||
url = @service.url(key, expires_in: 2.minutes, disposition: :inline, content_type: "text/html", filename: ActiveStorage::Filename.new("test.html"))
|
url = @service.url(key, expires_in: 2.minutes, disposition: :inline, content_type: "text/html", filename: ActiveStorage::Filename.new("test.html"))
|
||||||
response = Net::HTTP.get_response(URI(url))
|
response = Net::HTTP.get_response(URI(url))
|
||||||
|
@ -105,7 +105,7 @@ if SERVICE_CONFIGURATIONS[:gcs]
|
||||||
key = SecureRandom.base58(24)
|
key = SecureRandom.base58(24)
|
||||||
data = "Something else entirely!"
|
data = "Something else entirely!"
|
||||||
|
|
||||||
@service.upload(key, StringIO.new(data), checksum: Digest::MD5.base64digest(data), content_type: "text/plain")
|
@service.upload(key, StringIO.new(data), checksum: OpenSSL::Digest::MD5.base64digest(data), content_type: "text/plain")
|
||||||
|
|
||||||
url = @service.url(key, expires_in: 2.minutes, disposition: :inline, content_type: "text/html", filename: ActiveStorage::Filename.new("test.html"))
|
url = @service.url(key, expires_in: 2.minutes, disposition: :inline, content_type: "text/html", filename: ActiveStorage::Filename.new("test.html"))
|
||||||
response = Net::HTTP.get_response(URI(url))
|
response = Net::HTTP.get_response(URI(url))
|
||||||
|
@ -135,7 +135,7 @@ if SERVICE_CONFIGURATIONS[:gcs]
|
||||||
test "update metadata" do
|
test "update metadata" do
|
||||||
key = SecureRandom.base58(24)
|
key = SecureRandom.base58(24)
|
||||||
data = "Something else entirely!"
|
data = "Something else entirely!"
|
||||||
@service.upload(key, StringIO.new(data), checksum: Digest::MD5.base64digest(data), disposition: :attachment, filename: ActiveStorage::Filename.new("test.html"), content_type: "text/html")
|
@service.upload(key, StringIO.new(data), checksum: OpenSSL::Digest::MD5.base64digest(data), disposition: :attachment, filename: ActiveStorage::Filename.new("test.html"), content_type: "text/html")
|
||||||
|
|
||||||
@service.update_metadata(key, disposition: :inline, filename: ActiveStorage::Filename.new("test.txt"), content_type: "text/plain")
|
@service.update_metadata(key, disposition: :inline, filename: ActiveStorage::Filename.new("test.txt"), content_type: "text/plain")
|
||||||
url = @service.url(key, expires_in: 2.minutes, disposition: :attachment, content_type: "text/html", filename: ActiveStorage::Filename.new("test.html"))
|
url = @service.url(key, expires_in: 2.minutes, disposition: :attachment, content_type: "text/html", filename: ActiveStorage::Filename.new("test.html"))
|
||||||
|
|
|
@ -25,7 +25,7 @@ class ActiveStorage::Service::MirrorServiceTest < ActiveSupport::TestCase
|
||||||
key = SecureRandom.base58(24)
|
key = SecureRandom.base58(24)
|
||||||
data = "Something else entirely!"
|
data = "Something else entirely!"
|
||||||
io = StringIO.new(data)
|
io = StringIO.new(data)
|
||||||
checksum = Digest::MD5.base64digest(data)
|
checksum = OpenSSL::Digest::MD5.base64digest(data)
|
||||||
|
|
||||||
@service.upload key, io.tap(&:read), checksum: checksum
|
@service.upload key, io.tap(&:read), checksum: checksum
|
||||||
assert_predicate io, :eof?
|
assert_predicate io, :eof?
|
||||||
|
@ -41,7 +41,7 @@ class ActiveStorage::Service::MirrorServiceTest < ActiveSupport::TestCase
|
||||||
test "downloading from primary service" do
|
test "downloading from primary service" do
|
||||||
key = SecureRandom.base58(24)
|
key = SecureRandom.base58(24)
|
||||||
data = "Something else entirely!"
|
data = "Something else entirely!"
|
||||||
checksum = Digest::MD5.base64digest(data)
|
checksum = OpenSSL::Digest::MD5.base64digest(data)
|
||||||
|
|
||||||
@service.primary.upload key, StringIO.new(data), checksum: checksum
|
@service.primary.upload key, StringIO.new(data), checksum: checksum
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@ class ActiveStorage::Service::MirrorServiceTest < ActiveSupport::TestCase
|
||||||
test "mirroring a file from the primary service to secondary services where it doesn't exist" do
|
test "mirroring a file from the primary service to secondary services where it doesn't exist" do
|
||||||
key = SecureRandom.base58(24)
|
key = SecureRandom.base58(24)
|
||||||
data = "Something else entirely!"
|
data = "Something else entirely!"
|
||||||
checksum = Digest::MD5.base64digest(data)
|
checksum = OpenSSL::Digest::MD5.base64digest(data)
|
||||||
|
|
||||||
@service.primary.upload key, StringIO.new(data), checksum: checksum
|
@service.primary.upload key, StringIO.new(data), checksum: checksum
|
||||||
@service.mirrors.third.upload key, StringIO.new("Surprise!")
|
@service.mirrors.third.upload key, StringIO.new("Surprise!")
|
||||||
|
|
|
@ -35,7 +35,7 @@ if SERVICE_CONFIGURATIONS[:s3_public]
|
||||||
test "direct upload" do
|
test "direct upload" do
|
||||||
key = SecureRandom.base58(24)
|
key = SecureRandom.base58(24)
|
||||||
data = "Something else entirely!"
|
data = "Something else entirely!"
|
||||||
checksum = Digest::MD5.base64digest(data)
|
checksum = OpenSSL::Digest::MD5.base64digest(data)
|
||||||
url = @service.url_for_direct_upload(key, expires_in: 5.minutes, content_type: "text/plain", content_length: data.size, checksum: checksum)
|
url = @service.url_for_direct_upload(key, expires_in: 5.minutes, content_type: "text/plain", content_length: data.size, checksum: checksum)
|
||||||
|
|
||||||
uri = URI.parse url
|
uri = URI.parse url
|
||||||
|
|
|
@ -17,7 +17,7 @@ if SERVICE_CONFIGURATIONS[:s3]
|
||||||
test "direct upload" do
|
test "direct upload" do
|
||||||
key = SecureRandom.base58(24)
|
key = SecureRandom.base58(24)
|
||||||
data = "Something else entirely!"
|
data = "Something else entirely!"
|
||||||
checksum = Digest::MD5.base64digest(data)
|
checksum = OpenSSL::Digest::MD5.base64digest(data)
|
||||||
url = @service.url_for_direct_upload(key, expires_in: 5.minutes, content_type: "text/plain", content_length: data.size, checksum: checksum)
|
url = @service.url_for_direct_upload(key, expires_in: 5.minutes, content_type: "text/plain", content_length: data.size, checksum: checksum)
|
||||||
|
|
||||||
uri = URI.parse url
|
uri = URI.parse url
|
||||||
|
@ -37,7 +37,7 @@ if SERVICE_CONFIGURATIONS[:s3]
|
||||||
test "direct upload with content disposition" do
|
test "direct upload with content disposition" do
|
||||||
key = SecureRandom.base58(24)
|
key = SecureRandom.base58(24)
|
||||||
data = "Something else entirely!"
|
data = "Something else entirely!"
|
||||||
checksum = Digest::MD5.base64digest(data)
|
checksum = OpenSSL::Digest::MD5.base64digest(data)
|
||||||
url = @service.url_for_direct_upload(key, expires_in: 5.minutes, content_type: "text/plain", content_length: data.size, checksum: checksum)
|
url = @service.url_for_direct_upload(key, expires_in: 5.minutes, content_type: "text/plain", content_length: data.size, checksum: checksum)
|
||||||
|
|
||||||
uri = URI.parse url
|
uri = URI.parse url
|
||||||
|
@ -58,7 +58,7 @@ if SERVICE_CONFIGURATIONS[:s3]
|
||||||
test "directly uploading file larger than the provided content-length does not work" do
|
test "directly uploading file larger than the provided content-length does not work" do
|
||||||
key = SecureRandom.base58(24)
|
key = SecureRandom.base58(24)
|
||||||
data = "Some text that is longer than the specified content length"
|
data = "Some text that is longer than the specified content length"
|
||||||
checksum = Digest::MD5.base64digest(data)
|
checksum = OpenSSL::Digest::MD5.base64digest(data)
|
||||||
url = @service.url_for_direct_upload(key, expires_in: 5.minutes, content_type: "text/plain", content_length: data.size - 1, checksum: checksum)
|
url = @service.url_for_direct_upload(key, expires_in: 5.minutes, content_type: "text/plain", content_length: data.size - 1, checksum: checksum)
|
||||||
|
|
||||||
uri = URI.parse url
|
uri = URI.parse url
|
||||||
|
@ -99,7 +99,7 @@ if SERVICE_CONFIGURATIONS[:s3]
|
||||||
begin
|
begin
|
||||||
key = SecureRandom.base58(24)
|
key = SecureRandom.base58(24)
|
||||||
data = "Something else entirely!"
|
data = "Something else entirely!"
|
||||||
service.upload key, StringIO.new(data), checksum: Digest::MD5.base64digest(data)
|
service.upload key, StringIO.new(data), checksum: OpenSSL::Digest::MD5.base64digest(data)
|
||||||
|
|
||||||
assert_equal "AES256", service.bucket.object(key).server_side_encryption
|
assert_equal "AES256", service.bucket.object(key).server_side_encryption
|
||||||
ensure
|
ensure
|
||||||
|
@ -115,7 +115,7 @@ if SERVICE_CONFIGURATIONS[:s3]
|
||||||
@service.upload(
|
@service.upload(
|
||||||
key,
|
key,
|
||||||
StringIO.new(data),
|
StringIO.new(data),
|
||||||
checksum: Digest::MD5.base64digest(data),
|
checksum: OpenSSL::Digest::MD5.base64digest(data),
|
||||||
filename: "cool_data.txt",
|
filename: "cool_data.txt",
|
||||||
content_type: content_type
|
content_type: content_type
|
||||||
)
|
)
|
||||||
|
@ -132,7 +132,7 @@ if SERVICE_CONFIGURATIONS[:s3]
|
||||||
@service.upload(
|
@service.upload(
|
||||||
key,
|
key,
|
||||||
StringIO.new(data),
|
StringIO.new(data),
|
||||||
checksum: Digest::MD5.base64digest(data),
|
checksum: OpenSSL::Digest::MD5.base64digest(data),
|
||||||
filename: ActiveStorage::Filename.new("cool_data.txt"),
|
filename: ActiveStorage::Filename.new("cool_data.txt"),
|
||||||
disposition: :attachment
|
disposition: :attachment
|
||||||
)
|
)
|
||||||
|
@ -149,7 +149,7 @@ if SERVICE_CONFIGURATIONS[:s3]
|
||||||
key = SecureRandom.base58(24)
|
key = SecureRandom.base58(24)
|
||||||
data = SecureRandom.bytes(8.megabytes)
|
data = SecureRandom.bytes(8.megabytes)
|
||||||
|
|
||||||
service.upload key, StringIO.new(data), checksum: Digest::MD5.base64digest(data)
|
service.upload key, StringIO.new(data), checksum: OpenSSL::Digest::MD5.base64digest(data)
|
||||||
assert data == service.download(key)
|
assert data == service.download(key)
|
||||||
ensure
|
ensure
|
||||||
service.delete key
|
service.delete key
|
||||||
|
@ -163,7 +163,7 @@ if SERVICE_CONFIGURATIONS[:s3]
|
||||||
key = SecureRandom.base58(24)
|
key = SecureRandom.base58(24)
|
||||||
data = SecureRandom.bytes(3.megabytes)
|
data = SecureRandom.bytes(3.megabytes)
|
||||||
|
|
||||||
service.upload key, StringIO.new(data), checksum: Digest::MD5.base64digest(data)
|
service.upload key, StringIO.new(data), checksum: OpenSSL::Digest::MD5.base64digest(data)
|
||||||
assert data == service.download(key)
|
assert data == service.download(key)
|
||||||
ensure
|
ensure
|
||||||
service.delete key
|
service.delete key
|
||||||
|
|
|
@ -22,7 +22,7 @@ module ActiveStorage::Service::SharedServiceTests
|
||||||
test "uploading with integrity" do
|
test "uploading with integrity" do
|
||||||
key = SecureRandom.base58(24)
|
key = SecureRandom.base58(24)
|
||||||
data = "Something else entirely!"
|
data = "Something else entirely!"
|
||||||
@service.upload(key, StringIO.new(data), checksum: Digest::MD5.base64digest(data))
|
@service.upload(key, StringIO.new(data), checksum: OpenSSL::Digest::MD5.base64digest(data))
|
||||||
|
|
||||||
assert_equal data, @service.download(key)
|
assert_equal data, @service.download(key)
|
||||||
ensure
|
ensure
|
||||||
|
@ -34,7 +34,7 @@ module ActiveStorage::Service::SharedServiceTests
|
||||||
data = "Something else entirely!"
|
data = "Something else entirely!"
|
||||||
|
|
||||||
assert_raises(ActiveStorage::IntegrityError) do
|
assert_raises(ActiveStorage::IntegrityError) do
|
||||||
@service.upload(key, StringIO.new(data), checksum: Digest::MD5.base64digest("bad data"))
|
@service.upload(key, StringIO.new(data), checksum: OpenSSL::Digest::MD5.base64digest("bad data"))
|
||||||
end
|
end
|
||||||
|
|
||||||
assert_not @service.exist?(key)
|
assert_not @service.exist?(key)
|
||||||
|
@ -48,7 +48,7 @@ module ActiveStorage::Service::SharedServiceTests
|
||||||
@service.upload(
|
@service.upload(
|
||||||
key,
|
key,
|
||||||
StringIO.new(data),
|
StringIO.new(data),
|
||||||
checksum: Digest::MD5.base64digest(data),
|
checksum: OpenSSL::Digest::MD5.base64digest(data),
|
||||||
filename: "racecar.jpg",
|
filename: "racecar.jpg",
|
||||||
content_type: "image/jpeg"
|
content_type: "image/jpeg"
|
||||||
)
|
)
|
||||||
|
|
|
@ -97,7 +97,7 @@ class ActiveSupport::TestCase
|
||||||
def directly_upload_file_blob(filename: "racecar.jpg", content_type: "image/jpeg", record: nil)
|
def directly_upload_file_blob(filename: "racecar.jpg", content_type: "image/jpeg", record: nil)
|
||||||
file = file_fixture(filename)
|
file = file_fixture(filename)
|
||||||
byte_size = file.size
|
byte_size = file.size
|
||||||
checksum = Digest::MD5.file(file).base64digest
|
checksum = OpenSSL::Digest::MD5.file(file).base64digest
|
||||||
|
|
||||||
create_blob_before_direct_upload(filename: filename, byte_size: byte_size, checksum: checksum, content_type: content_type, record: record).tap do |blob|
|
create_blob_before_direct_upload(filename: filename, byte_size: byte_size, checksum: checksum, content_type: content_type, record: record).tap do |blob|
|
||||||
service = ActiveStorage::Blob.service.try(:primary) || ActiveStorage::Blob.service
|
service = ActiveStorage::Blob.service.try(:primary) || ActiveStorage::Blob.service
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
* OpenSSL constants are now used for Digest computations.
|
||||||
|
|
||||||
|
*Dirkjan Bussink*
|
||||||
|
|
||||||
* `TimeZone.iso8601` now accepts valid ordinal values similar to Ruby's `Date._iso8601` method.
|
* `TimeZone.iso8601` now accepts valid ordinal values similar to Ruby's `Date._iso8601` method.
|
||||||
A valid ordinal value will be converted to an instance of `TimeWithZone` using the `:year`
|
A valid ordinal value will be converted to an instance of `TimeWithZone` using the `:year`
|
||||||
and `:yday` fragments returned from `Date._iso8601`.
|
and `:yday` fragments returned from `Date._iso8601`.
|
||||||
|
|
|
@ -11,17 +11,17 @@ module Digest
|
||||||
|
|
||||||
# Generates a v5 non-random UUID (Universally Unique IDentifier).
|
# Generates a v5 non-random UUID (Universally Unique IDentifier).
|
||||||
#
|
#
|
||||||
# Using Digest::MD5 generates version 3 UUIDs; Digest::SHA1 generates version 5 UUIDs.
|
# Using OpenSSL::Digest::MD5 generates version 3 UUIDs; OpenSSL::Digest::SHA1 generates version 5 UUIDs.
|
||||||
# uuid_from_hash always generates the same UUID for a given name and namespace combination.
|
# uuid_from_hash always generates the same UUID for a given name and namespace combination.
|
||||||
#
|
#
|
||||||
# See RFC 4122 for details of UUID at: https://www.ietf.org/rfc/rfc4122.txt
|
# See RFC 4122 for details of UUID at: https://www.ietf.org/rfc/rfc4122.txt
|
||||||
def self.uuid_from_hash(hash_class, uuid_namespace, name)
|
def self.uuid_from_hash(hash_class, uuid_namespace, name)
|
||||||
if hash_class == Digest::MD5
|
if hash_class == Digest::MD5 || hash_class == OpenSSL::Digest::MD5
|
||||||
version = 3
|
version = 3
|
||||||
elsif hash_class == Digest::SHA1
|
elsif hash_class == Digest::SHA1 || hash_class == OpenSSL::Digest::SHA1
|
||||||
version = 5
|
version = 5
|
||||||
else
|
else
|
||||||
raise ArgumentError, "Expected Digest::SHA1 or Digest::MD5, got #{hash_class.name}."
|
raise ArgumentError, "Expected OpenSSL::Digest::SHA1 or OpenSSL::Digest::MD5, got #{hash_class.name}."
|
||||||
end
|
end
|
||||||
|
|
||||||
hash = hash_class.new
|
hash = hash_class.new
|
||||||
|
@ -35,14 +35,14 @@ module Digest
|
||||||
"%08x-%04x-%04x-%04x-%04x%08x" % ary
|
"%08x-%04x-%04x-%04x-%04x%08x" % ary
|
||||||
end
|
end
|
||||||
|
|
||||||
# Convenience method for uuid_from_hash using Digest::MD5.
|
# Convenience method for uuid_from_hash using OpenSSL::Digest::MD5.
|
||||||
def self.uuid_v3(uuid_namespace, name)
|
def self.uuid_v3(uuid_namespace, name)
|
||||||
uuid_from_hash(Digest::MD5, uuid_namespace, name)
|
uuid_from_hash(OpenSSL::Digest::MD5, uuid_namespace, name)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Convenience method for uuid_from_hash using Digest::SHA1.
|
# Convenience method for uuid_from_hash using OpenSSL::Digest::SHA1.
|
||||||
def self.uuid_v5(uuid_namespace, name)
|
def self.uuid_v5(uuid_namespace, name)
|
||||||
uuid_from_hash(Digest::SHA1, uuid_namespace, name)
|
uuid_from_hash(OpenSSL::Digest::SHA1, uuid_namespace, name)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Convenience method for SecureRandom.uuid.
|
# Convenience method for SecureRandom.uuid.
|
||||||
|
|
|
@ -20,7 +20,7 @@ class DigestUUIDExt < ActiveSupport::TestCase
|
||||||
|
|
||||||
def test_invalid_hash_class
|
def test_invalid_hash_class
|
||||||
assert_raise ArgumentError do
|
assert_raise ArgumentError do
|
||||||
Digest::UUID.uuid_from_hash(Digest::SHA2, Digest::UUID::OID_NAMESPACE, "1.2.3")
|
Digest::UUID.uuid_from_hash(OpenSSL::Digest::SHA256, Digest::UUID::OID_NAMESPACE, "1.2.3")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue