diff --git a/fasp_base/Gemfile.lock b/fasp_base/Gemfile.lock index 36f8f47..3d0eb0f 100644 --- a/fasp_base/Gemfile.lock +++ b/fasp_base/Gemfile.lock @@ -2,8 +2,10 @@ PATH remote: . specs: fasp_base (0.1.0) + addressable bcrypt httpx + idnx linzer (>= 0.7.7) openssl rails (>= 8.0.0) @@ -106,6 +108,16 @@ GEM drb (2.2.3) erb (6.0.1) erubi (1.13.1) + ffi (1.17.4-aarch64-linux-gnu) + ffi (1.17.4-aarch64-linux-musl) + ffi (1.17.4-arm-linux-gnu) + ffi (1.17.4-arm-linux-musl) + ffi (1.17.4-arm64-darwin) + ffi (1.17.4-x86-linux-gnu) + ffi (1.17.4-x86-linux-musl) + ffi (1.17.4-x86_64-darwin) + ffi (1.17.4-x86_64-linux-gnu) + ffi (1.17.4-x86_64-linux-musl) forwardable (1.4.0) globalid (1.3.0) activesupport (>= 6.1) @@ -115,6 +127,8 @@ GEM http-2 (>= 1.2.0) i18n (1.14.7) concurrent-ruby (~> 1.0) + idnx (0.1.1) + ffi (~> 1.12) io-console (0.8.2) irb (1.16.0) pp (>= 0.6.0) @@ -144,7 +158,7 @@ GEM marcel (1.1.0) mini_mime (1.1.5) mini_portile2 (2.8.9) - minitest (5.26.0) + minitest (5.27.0) net-http (0.9.1) uri (>= 0.11.1) net-imap (0.5.12) @@ -160,22 +174,6 @@ GEM nokogiri (1.18.10) mini_portile2 (~> 2.8.2) racc (~> 1.4) - nokogiri (1.18.10-aarch64-linux-gnu) - racc (~> 1.4) - nokogiri (1.18.10-aarch64-linux-musl) - racc (~> 1.4) - nokogiri (1.18.10-arm-linux-gnu) - racc (~> 1.4) - nokogiri (1.18.10-arm-linux-musl) - racc (~> 1.4) - nokogiri (1.18.10-arm64-darwin) - racc (~> 1.4) - nokogiri (1.18.10-x86_64-darwin) - racc (~> 1.4) - nokogiri (1.18.10-x86_64-linux-gnu) - racc (~> 1.4) - nokogiri (1.18.10-x86_64-linux-musl) - racc (~> 1.4) openssl (4.0.2) parallel (1.27.0) parser (3.3.8.0) @@ -244,7 +242,7 @@ GEM reline (0.6.3) io-console (~> 0.5) rexml (3.4.4) - rubocop (1.78.0) + rubocop (1.80.2) json (~> 2.3) language_server-protocol (~> 3.17.0.2) lint_roller (~> 1.1.0) @@ -252,7 +250,7 @@ GEM parser (>= 3.3.0.2) rainbow (>= 2.2.2, < 4.0) regexp_parser (>= 2.9.3, < 3.0) - rubocop-ast (>= 1.45.1, < 2.0) + rubocop-ast (>= 1.46.0, < 2.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 2.4.0, < 4.0) rubocop-ast (1.46.0) @@ -292,9 +290,9 @@ GEM tsort (0.2.0) tzinfo (2.0.6) concurrent-ruby (~> 1.0) - unicode-display_width (3.1.4) - unicode-emoji (~> 4.0, >= 4.0.4) - unicode-emoji (4.0.4) + unicode-display_width (3.2.0) + unicode-emoji (~> 4.1) + unicode-emoji (4.2.0) uri (1.1.1) useragent (0.16.11) webmock (3.26.1) diff --git a/fasp_base/fasp_base.gemspec b/fasp_base/fasp_base.gemspec index cfe39e6..b33b495 100644 --- a/fasp_base/fasp_base.gemspec +++ b/fasp_base/fasp_base.gemspec @@ -22,6 +22,8 @@ Gem::Specification.new do |spec| spec.add_dependency "httpx" spec.add_dependency "linzer", ">= 0.7.7" spec.add_dependency "openssl" + spec.add_dependency "addressable" + spec.add_dependency "idnx" spec.add_development_dependency "webmock" end diff --git a/fasp_data_sharing/Gemfile.lock b/fasp_data_sharing/Gemfile.lock index 9169835..3dc128e 100644 --- a/fasp_data_sharing/Gemfile.lock +++ b/fasp_data_sharing/Gemfile.lock @@ -2,8 +2,10 @@ PATH remote: ../fasp_base specs: fasp_base (0.1.0) + addressable bcrypt httpx + idnx linzer (>= 0.7.7) openssl rails (>= 8.0.0) @@ -113,6 +115,16 @@ GEM drb (2.2.3) erb (5.1.3) erubi (1.13.1) + ffi (1.17.4-aarch64-linux-gnu) + ffi (1.17.4-aarch64-linux-musl) + ffi (1.17.4-arm-linux-gnu) + ffi (1.17.4-arm-linux-musl) + ffi (1.17.4-arm64-darwin) + ffi (1.17.4-x86-linux-gnu) + ffi (1.17.4-x86-linux-musl) + ffi (1.17.4-x86_64-darwin) + ffi (1.17.4-x86_64-linux-gnu) + ffi (1.17.4-x86_64-linux-musl) forwardable (1.3.3) globalid (1.3.0) activesupport (>= 6.1) @@ -122,6 +134,8 @@ GEM http-2 (>= 1.0.0) i18n (1.14.7) concurrent-ruby (~> 1.0) + idnx (0.1.1) + ffi (~> 1.12) io-console (0.8.1) irb (1.15.3) pp (>= 0.6.0) @@ -153,7 +167,7 @@ GEM marcel (1.1.0) mini_mime (1.1.5) mini_portile2 (2.8.9) - minitest (5.26.0) + minitest (5.27.0) net-http (0.6.0) uri net-imap (0.5.12) @@ -169,22 +183,6 @@ GEM nokogiri (1.18.10) mini_portile2 (~> 2.8.2) racc (~> 1.4) - nokogiri (1.18.10-aarch64-linux-gnu) - racc (~> 1.4) - nokogiri (1.18.10-aarch64-linux-musl) - racc (~> 1.4) - nokogiri (1.18.10-arm-linux-gnu) - racc (~> 1.4) - nokogiri (1.18.10-arm-linux-musl) - racc (~> 1.4) - nokogiri (1.18.10-arm64-darwin) - racc (~> 1.4) - nokogiri (1.18.10-x86_64-darwin) - racc (~> 1.4) - nokogiri (1.18.10-x86_64-linux-gnu) - racc (~> 1.4) - nokogiri (1.18.10-x86_64-linux-musl) - racc (~> 1.4) openssl (3.3.2) parallel (1.27.0) parser (3.3.10.0) @@ -283,16 +281,8 @@ GEM rubocop-rails (>= 2.30) ruby-progressbar (1.13.0) securerandom (0.4.1) - sqlite3 (2.7.4-aarch64-linux-gnu) - sqlite3 (2.7.4-aarch64-linux-musl) - sqlite3 (2.7.4-arm-linux-gnu) - sqlite3 (2.7.4-arm-linux-musl) - sqlite3 (2.7.4-arm64-darwin) - sqlite3 (2.7.4-x86-linux-gnu) - sqlite3 (2.7.4-x86-linux-musl) - sqlite3 (2.7.4-x86_64-darwin) - sqlite3 (2.7.4-x86_64-linux-gnu) - sqlite3 (2.7.4-x86_64-linux-musl) + sqlite3 (2.7.4) + mini_portile2 (~> 2.8.0) starry (0.2.0) base64 stringio (3.1.7) @@ -303,7 +293,7 @@ GEM concurrent-ruby (~> 1.0) unicode-display_width (3.2.0) unicode-emoji (~> 4.1) - unicode-emoji (4.1.0) + unicode-emoji (4.2.0) uri (1.1.1) useragent (0.16.11) webmock (3.26.1) diff --git a/fasp_data_sharing/app/models/fasp_data_sharing/activity_pub_object.rb b/fasp_data_sharing/app/models/fasp_data_sharing/activity_pub_object.rb index bda772d..6a1078e 100644 --- a/fasp_data_sharing/app/models/fasp_data_sharing/activity_pub_object.rb +++ b/fasp_data_sharing/app/models/fasp_data_sharing/activity_pub_object.rb @@ -40,7 +40,7 @@ def signature_headers "accept" => "application/activity+json", "digest" => "SHA-256=#{EMPTY_DIGEST}", "date" => Time.now.utc.httpdate, - "host" => URI(uri).host + "host" => parsed_uri.host } signature_header = [ "keyId=\"#{keyid}\"", @@ -52,11 +52,8 @@ def signature_headers end def sign(headers) - parsed_uri = URI(uri) - target = parsed_uri.path - target << "?#{parsed_uri.query}" unless parsed_uri.query.nil? string = [ - "(request-target): get #{target}", + "(request-target): get #{parsed_uri.request_uri}", "date: #{headers["date"]}", "digest: #{headers["digest"]}", "host: #{headers["host"]}" @@ -72,4 +69,8 @@ def keyid def private_key_pem @private_key_pem ||= FaspDataSharing::Actor.instance.private_key_pem end + + def parsed_uri + @parsed_uri ||= Addressable::URI.parse(uri) + end end diff --git a/fasp_data_sharing/test/models/fasp_data_sharing/activity_pub_object_test.rb b/fasp_data_sharing/test/models/fasp_data_sharing/activity_pub_object_test.rb index 47f6fef..999a80c 100644 --- a/fasp_data_sharing/test/models/fasp_data_sharing/activity_pub_object_test.rb +++ b/fasp_data_sharing/test/models/fasp_data_sharing/activity_pub_object_test.rb @@ -42,5 +42,24 @@ class ActivityPubObjectTest < ActiveSupport::TestCase assert_requested(message_signatures_stub) assert_requested(signatures_stub) end + + test "when URI contains non-ASCII characters it gets parsed and processed successfully" do + uri = "http://www.詹姆斯.com/users/\u4F11\u65E5\u8AB2\u9577" + json_object = { + "@context" => "https://www.w3.org/ns/activitystreams", + "id" => uri + } + activity_pub_object = ActivityPubObject.new(uri: uri) + message_signatures_stub = stub_request(:get, "http://www.xn--8ws00zhy3a.com/users/%E4%BC%91%E6%97%A5%E8%AA%B2%E9%95%B7") + .with { |r| r.headers["Signature-Input"].present? } + .to_return_json( + body: json_object, + headers: { "content-type" => "application/activity+json" + }) + + returned_json = activity_pub_object.fetch + assert_equal json_object, returned_json + assert_requested(message_signatures_stub) + end end end diff --git a/fasp_data_sharing/test/test_helper.rb b/fasp_data_sharing/test/test_helper.rb index 098c60e..85817fe 100644 --- a/fasp_data_sharing/test/test_helper.rb +++ b/fasp_data_sharing/test/test_helper.rb @@ -1,6 +1,13 @@ # Configure Rails Environment ENV["RAILS_ENV"] = "test" +require "webmock" +require "httpx/adapters/webmock" +require "webmock/minitest" +WebMock.disable_net_connect!( + allow_localhost: true +) + require_relative "../test/dummy/config/environment" ActiveRecord::Migrator.migrations_paths = [ File.expand_path("../test/dummy/db/migrate", __dir__) ] ActiveRecord::Migrator.migrations_paths << File.expand_path("../db/migrate", __dir__) @@ -14,11 +21,5 @@ ActiveSupport::TestCase.fixtures :all end -require "webmock" -require "httpx/adapters/webmock" -require "webmock/minitest" -WebMock.disable_net_connect!( - allow_localhost: true -) Dir[File.expand_path("support/**/*.rb", __dir__)].each { |f| require f }