From 2b841d90c01026cbb1bc0938e0dfaa1bd7176529 Mon Sep 17 00:00:00 2001 From: Rory McNicholl Date: Thu, 6 Nov 2025 16:21:42 +0000 Subject: [PATCH 1/3] Don't add slash to URIs with obvious file.extensions --- config/initializers/hyrax.rb | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/config/initializers/hyrax.rb b/config/initializers/hyrax.rb index aafea048..35a831e3 100644 --- a/config/initializers/hyrax.rb +++ b/config/initializers/hyrax.rb @@ -230,3 +230,34 @@ def build_query_url(q) require 'hydra/derivatives' Hydra::Derivatives::Processors::Video::Processor.config.video_bitrate = '1500k' + +# Monkey patch Bulkrax so controlled URI validation allows http://thing.com/a/file/with/an/extension.html +# not just http://thing.com/thing(|/) +# Remove all the trailing slashes from authorities and remove from input if present rather than the inverse +module Bulkrax + # Import Behavior for Entry classes + module ImportBehavior # rubocop:disable Metrics/ModuleLength + #extend ActiveSupport::Concern + + # @param value [String] value to validate + # @param field [String] name of the controlled property + # @return [String, nil] validated URI value or nil + def validate_value(value, field) + if value.match?(::URI::DEFAULT_PARSER.make_regexp) + value = value.strip.chomp + # add trailing forward slash unless one is already present or there's an obvious file extension + value << '/' unless value.match?(%r{/$}) || value.match?(%r{/[^./]+\.[^./]+$}) + end + + valid = if active_id_for_authority?(value, field) + true + else + value.include?('https') ? value.sub!('https', 'http') : value.sub!('http', 'https') + active_id_for_authority?(value, field) + end + + valid ? value : nil + end + + end +end From 0fe2054ea486f32fd7f03f88415fd0bbf83ced4d Mon Sep 17 00:00:00 2001 From: Rory McNicholl Date: Thu, 6 Nov 2025 17:01:46 +0000 Subject: [PATCH 2/3] unlint --- app/controllers/application_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 8f052fda..bfec3e25 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -55,7 +55,7 @@ def authenticate_if_needed # Disable this extra authentication in test mode return true if Rails.env.test? return true # any hint of basic auth will stop BL staff from accessing site so instead we open all the "private" demo sites - if (is_hidden || is_staging) && !is_api_or_pdf + if (is_hidden || is_staging) && !is_api_or_pdf # rubocop:disable Lint/UnreachableCode authenticate_or_request_with_http_basic do |username, password| username == ENV.fetch("HYKU_DEMO_USER", "bl_demo_user") && password == ENV.fetch("HYKU_DEMO_PASSWORD", "resu_omed_lb") end From 9a90061c9523ed9a838056371de962e3fdaa943b Mon Sep 17 00:00:00 2001 From: Rory McNicholl Date: Thu, 6 Nov 2025 19:47:49 +0000 Subject: [PATCH 3/3] use module_eval to override... --- config/initializers/hyrax.rb | 41 ++++++++++++++++-------------------- 1 file changed, 18 insertions(+), 23 deletions(-) diff --git a/config/initializers/hyrax.rb b/config/initializers/hyrax.rb index 35a831e3..c0ccba51 100644 --- a/config/initializers/hyrax.rb +++ b/config/initializers/hyrax.rb @@ -234,30 +234,25 @@ def build_query_url(q) # Monkey patch Bulkrax so controlled URI validation allows http://thing.com/a/file/with/an/extension.html # not just http://thing.com/thing(|/) # Remove all the trailing slashes from authorities and remove from input if present rather than the inverse -module Bulkrax - # Import Behavior for Entry classes - module ImportBehavior # rubocop:disable Metrics/ModuleLength - #extend ActiveSupport::Concern - - # @param value [String] value to validate - # @param field [String] name of the controlled property - # @return [String, nil] validated URI value or nil - def validate_value(value, field) - if value.match?(::URI::DEFAULT_PARSER.make_regexp) - value = value.strip.chomp - # add trailing forward slash unless one is already present or there's an obvious file extension - value << '/' unless value.match?(%r{/$}) || value.match?(%r{/[^./]+\.[^./]+$}) - end - - valid = if active_id_for_authority?(value, field) - true - else - value.include?('https') ? value.sub!('https', 'http') : value.sub!('http', 'https') - active_id_for_authority?(value, field) - end - - valid ? value : nil +Bulkrax::ImportBehavior.module_eval do + + # @param value [String] value to validate + # @param field [String] name of the controlled property + # @return [String, nil] validated URI value or nil + def validate_value(value, field) + if value.match?(::URI::DEFAULT_PARSER.make_regexp) + value = value.strip.chomp + # add trailing forward slash unless one is already present or there's an obvious file extension + value << '/' unless value.match?(%r{/$}) || value.match?(%r{/[^./]+\.[^./]+$}) end + valid = if active_id_for_authority?(value, field) + true + else + value.include?('https') ? value.sub!('https', 'http') : value.sub!('http', 'https') + active_id_for_authority?(value, field) + end + + valid ? value : nil end end