summaryrefslogtreecommitdiff
path: root/test/rubygems/test_webauthn_poller.rb
diff options
context:
space:
mode:
Diffstat (limited to 'test/rubygems/test_webauthn_poller.rb')
-rw-r--r--test/rubygems/test_webauthn_poller.rb134
1 files changed, 134 insertions, 0 deletions
diff --git a/test/rubygems/test_webauthn_poller.rb b/test/rubygems/test_webauthn_poller.rb
new file mode 100644
index 0000000000..fd24081758
--- /dev/null
+++ b/test/rubygems/test_webauthn_poller.rb
@@ -0,0 +1,134 @@
+# frozen_string_literal: true
+
+require_relative "helper"
+require "rubygems/gemcutter_utilities/webauthn_poller"
+require "rubygems/gemcutter_utilities"
+
+class WebauthnPollerTest < Gem::TestCase
+ def setup
+ super
+
+ @host = Gem.host
+ @webauthn_url = "#{@host}/api/v1/webauthn_verification/odow34b93t6aPCdY"
+ @fetcher = Gem::FakeFetcher.new
+ Gem::RemoteFetcher.fetcher = @fetcher
+ @credentials = {
+ identifier: "email@example.com",
+ password: "password",
+ }
+ end
+
+ def test_poll_thread_success
+ @fetcher.data["#{@webauthn_url}/status.json"] = Gem::HTTPResponseFactory.create(
+ body: "{\"status\":\"success\",\"code\":\"Uvh6T57tkWuUnWYo\"}",
+ code: 200,
+ msg: "OK"
+ )
+
+ thread = Gem::GemcutterUtilities::WebauthnPoller.poll_thread({}, @host, @webauthn_url, @credentials)
+ thread.join
+
+ assert_equal thread[:otp], "Uvh6T57tkWuUnWYo"
+ end
+
+ def test_poll_thread_webauthn_verification_error
+ @fetcher.data["#{@webauthn_url}/status.json"] = Gem::HTTPResponseFactory.create(
+ body: "HTTP Basic: Access denied.",
+ code: 401,
+ msg: "Unauthorized"
+ )
+
+ thread = Gem::GemcutterUtilities::WebauthnPoller.poll_thread({}, @host, @webauthn_url, @credentials)
+ thread.join
+
+ assert_equal thread[:error].message, "Security device verification failed: Unauthorized"
+ end
+
+ def test_poll_thread_timeout_error
+ raise_error = ->(*_args) { raise Gem::Timeout::Error, "execution expired" }
+ Gem::Timeout.stub(:timeout, raise_error) do
+ thread = Gem::GemcutterUtilities::WebauthnPoller.poll_thread({}, @host, @webauthn_url, @credentials)
+ thread.join
+ assert_equal thread[:error].message, "execution expired"
+ end
+ end
+
+ def test_poll_for_otp_success
+ @fetcher.data["#{@webauthn_url}/status.json"] = Gem::HTTPResponseFactory.create(
+ body: "{\"status\":\"success\",\"code\":\"Uvh6T57tkWuUnWYo\"}",
+ code: 200,
+ msg: "OK"
+ )
+
+ otp = Gem::GemcutterUtilities::WebauthnPoller.new({}, @host).poll_for_otp(@webauthn_url, @credentials)
+
+ assert_equal otp, "Uvh6T57tkWuUnWYo"
+ end
+
+ def test_poll_for_otp_pending_sleeps
+ @fetcher.data["#{@webauthn_url}/status.json"] = Gem::HTTPResponseFactory.create(
+ body: "{\"status\":\"pending\",\"message\":\"Security device authentication is still pending.\"}",
+ code: 200,
+ msg: "OK"
+ )
+
+ assert_raise Gem::Timeout::Error do
+ Gem::Timeout.timeout(0.1) do
+ Gem::GemcutterUtilities::WebauthnPoller.new({}, @host).poll_for_otp(@webauthn_url, @credentials)
+ end
+ end
+ end
+
+ def test_poll_for_otp_not_http_success
+ @fetcher.data["#{@webauthn_url}/status.json"] = Gem::HTTPResponseFactory.create(
+ body: "HTTP Basic: Access denied.",
+ code: 401,
+ msg: "Unauthorized"
+ )
+
+ error = assert_raise Gem::WebauthnVerificationError do
+ Gem::GemcutterUtilities::WebauthnPoller.new({}, @host).poll_for_otp(@webauthn_url, @credentials)
+ end
+
+ assert_equal error.message, "Security device verification failed: Unauthorized"
+ end
+
+ def test_poll_for_otp_invalid_format
+ @fetcher.data["#{@webauthn_url}/status.json"] = Gem::HTTPResponseFactory.create(
+ body: "{}",
+ code: 200,
+ msg: "OK"
+ )
+
+ error = assert_raise Gem::WebauthnVerificationError do
+ Gem::GemcutterUtilities::WebauthnPoller.new({}, @host).poll_for_otp(@webauthn_url, @credentials)
+ end
+
+ assert_equal error.message, "Security device verification failed: Invalid response from server"
+ end
+
+ def test_poll_for_otp_invalid_status
+ @fetcher.data["#{@webauthn_url}/status.json"] = Gem::HTTPResponseFactory.create(
+ body: "{\"status\":\"expired\",\"message\":\"The token in the link you used has either expired or been used already.\"}",
+ code: 200,
+ msg: "OK"
+ )
+
+ error = assert_raise Gem::WebauthnVerificationError do
+ Gem::GemcutterUtilities::WebauthnPoller.new({}, @host).poll_for_otp(@webauthn_url, @credentials)
+ end
+
+ assert_equal error.message,
+ "Security device verification failed: The token in the link you used has either expired or been used already."
+ end
+
+ def test_poll_for_otp_missing_credentials
+ @credentials = { password: "password" }
+
+ error = assert_raise Gem::WebauthnVerificationError do
+ Gem::GemcutterUtilities::WebauthnPoller.new({}, @host).poll_for_otp(@webauthn_url, @credentials)
+ end
+
+ assert_equal error.message, "Security device verification failed: Provided missing credentials"
+ end
+end