From c7a8d63df84c4884cb30cc58292ec36efabfabbb Mon Sep 17 00:00:00 2001 From: Jenny Shen Date: Thu, 16 Feb 2023 16:14:36 -0500 Subject: Terminate interaction when rescuing WebauthnVerificationError during wait_for_otp Co-authored-by: Betty Li --- lib/rubygems/commands/owner_command.rb | 2 +- lib/rubygems/gemcutter_utilities.rb | 3 +++ test/rubygems/test_gem_commands_owner_command.rb | 16 +++++++--------- test/rubygems/test_gem_commands_push_command.rb | 5 +++-- test/rubygems/test_gem_commands_yank_command.rb | 5 +++-- test/rubygems/test_gem_gemcutter_utilities.rb | 6 +++--- 6 files changed, 20 insertions(+), 17 deletions(-) diff --git a/lib/rubygems/commands/owner_command.rb b/lib/rubygems/commands/owner_command.rb index eb66c510a9..fce32aca3e 100644 --- a/lib/rubygems/commands/owner_command.rb +++ b/lib/rubygems/commands/owner_command.rb @@ -101,7 +101,7 @@ permission to. rescue Gem::WebauthnVerificationError => e raise e rescue StandardError - # ignore + # ignore early exits to allow for completing the iteration of all owners end end diff --git a/lib/rubygems/gemcutter_utilities.rb b/lib/rubygems/gemcutter_utilities.rb index c4f31dc0d6..e66fd0e60f 100644 --- a/lib/rubygems/gemcutter_utilities.rb +++ b/lib/rubygems/gemcutter_utilities.rb @@ -266,6 +266,9 @@ module Gem::GemcutterUtilities thread = Thread.new do Thread.current[:otp] = Gem::WebauthnListener.wait_for_otp_code(host, server) + rescue Gem::WebauthnVerificationError => e + alert_error e.message + terminate_interaction(1) end thread.abort_on_exception = true thread.report_on_exception = false diff --git a/test/rubygems/test_gem_commands_owner_command.rb b/test/rubygems/test_gem_commands_owner_command.rb index fc8c8cb1bd..8b682c5202 100644 --- a/test/rubygems/test_gem_commands_owner_command.rb +++ b/test/rubygems/test_gem_commands_owner_command.rb @@ -406,21 +406,19 @@ EOF HTTPResponseFactory.create(body: response_success, code: 200, msg: "OK"), ] - error = assert_raise Gem::WebauthnVerificationError do - TCPServer.stub(:new, server) do - Gem::WebauthnListener.stub(:wait_for_otp_code, raise_error) do - use_ui @stub_ui do - @cmd.add_owners("freewill", ["user-new1@example.com"]) - end + TCPServer.stub(:new, server) do + Gem::WebauthnListener.stub(:wait_for_otp_code, raise_error) do + use_ui @stub_ui do + @cmd.add_owners("freewill", ["user-new1@example.com"]) end - ensure - server.close end + ensure + server.close end - assert_equal "Security device verification failed: Something went wrong", error.message url_with_port = "#{webauthn_verification_url}?port=#{port}" assert_match "You have enabled multi-factor authentication. Please visit #{url_with_port} to authenticate via security device.", @stub_ui.output + assert_match "ERROR: Security device verification failed: Something went wrong", @stub_ui.error refute_match "You are verified with a security device. You may close the browser window.", @stub_ui.output refute_match response_success, @stub_ui.output end diff --git a/test/rubygems/test_gem_commands_push_command.rb b/test/rubygems/test_gem_commands_push_command.rb index 9463e50a53..3f5ba70273 100644 --- a/test/rubygems/test_gem_commands_push_command.rb +++ b/test/rubygems/test_gem_commands_push_command.rb @@ -469,7 +469,7 @@ class TestGemCommandsPushCommand < Gem::TestCase ] @fetcher.data["#{Gem.host}/api/v1/webauthn_verification"] = HTTPResponseFactory.create(body: webauthn_verification_url, code: 200, msg: "OK") - error = assert_raise Gem::WebauthnVerificationError do + error = assert_raise Gem::MockGemUi::TermError do TCPServer.stub(:new, server) do Gem::WebauthnListener.stub(:wait_for_otp_code, raise_error) do use_ui @ui do @@ -480,10 +480,11 @@ class TestGemCommandsPushCommand < Gem::TestCase server.close end end - assert_equal "Security device verification failed: Something went wrong", error.message + assert_equal 1, error.exit_code url_with_port = "#{webauthn_verification_url}?port=#{port}" assert_match "You have enabled multi-factor authentication. Please visit #{url_with_port} to authenticate via security device.", @ui.output + assert_match "ERROR: Security device verification failed: Something went wrong", @ui.error refute_match "You are verified with a security device. You may close the browser window.", @ui.output refute_match response_success, @ui.output end diff --git a/test/rubygems/test_gem_commands_yank_command.rb b/test/rubygems/test_gem_commands_yank_command.rb index 860f445a95..306c9aa4f6 100644 --- a/test/rubygems/test_gem_commands_yank_command.rb +++ b/test/rubygems/test_gem_commands_yank_command.rb @@ -171,7 +171,7 @@ class TestGemCommandsYankCommand < Gem::TestCase @cmd.options[:added_platform] = true @cmd.options[:version] = req("= 1.0") - error = assert_raise Gem::WebauthnVerificationError do + error = assert_raise Gem::MockGemUi::TermError do TCPServer.stub(:new, server) do Gem::WebauthnListener.stub(:wait_for_otp_code, raise_error) do use_ui @ui do @@ -182,11 +182,12 @@ class TestGemCommandsYankCommand < Gem::TestCase server.close end end - assert_equal "Security device verification failed: Something went wrong", error.message + assert_equal 1, error.exit_code url_with_port = "#{webauthn_verification_url}?port=#{port}" assert_match %r{Yanking gem from http://example}, @ui.output assert_match "You have enabled multi-factor authentication. Please visit #{url_with_port} to authenticate via security device.", @ui.output + assert_match "ERROR: Security device verification failed: Something went wrong", @ui.error refute_match "You are verified with a security device. You may close the browser window.", @ui.output refute_match "Successfully yanked", @ui.output end diff --git a/test/rubygems/test_gem_gemcutter_utilities.rb b/test/rubygems/test_gem_gemcutter_utilities.rb index 93aec0c67c..d68e54fb63 100644 --- a/test/rubygems/test_gem_gemcutter_utilities.rb +++ b/test/rubygems/test_gem_gemcutter_utilities.rb @@ -267,7 +267,7 @@ class TestGemGemcutterUtilities < Gem::TestCase server = TCPServer.new(port) raise_error = ->(*_args) { raise Gem::WebauthnVerificationError, "Something went wrong" } - error = assert_raise Gem::WebauthnVerificationError do + error = assert_raise Gem::MockGemUi::TermError do TCPServer.stub(:new, server) do Gem::WebauthnListener.stub(:wait_for_otp_code, raise_error) do util_sign_in(proc do @@ -283,11 +283,11 @@ class TestGemGemcutterUtilities < Gem::TestCase server.close end end - - assert_equal "Security device verification failed: Something went wrong", error.message + assert_equal 1, error.exit_code url_with_port = "#{webauthn_verification_url}?port=#{port}" assert_match "You have enabled multi-factor authentication. Please visit #{url_with_port} to authenticate via security device.", @sign_in_ui.output + assert_match "ERROR: Security device verification failed: Something went wrong", @sign_in_ui.error refute_match "You are verified with a security device. You may close the browser window.", @sign_in_ui.output refute_match "Signed in with API key:", @sign_in_ui.output end -- cgit v1.2.3