1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
|
# frozen_string_literal: true
require_relative "helper"
require "rubygems/webauthn_listener"
class WebauthnListenerTest < Gem::TestCase
def setup
super
@server = TCPServer.new 0
@port = @server.addr[1].to_s
end
def teardown
@thread.kill.join if @thread
@server&.close
super
end
def test_wait_for_otp_code_get_follows_options
wait_for_otp_code
assert Gem::MockBrowser.options(URI("http://localhost:#{@port}?code=xyz")).is_a? Net::HTTPNoContent
assert Gem::MockBrowser.get(URI("http://localhost:#{@port}?code=xyz")).is_a? Net::HTTPOK
end
def test_wait_for_otp_code_options_request
wait_for_otp_code
response = Gem::MockBrowser.options URI("http://localhost:#{@port}?code=xyz")
assert response.is_a? Net::HTTPNoContent
assert_equal Gem.host, response["access-control-allow-origin"]
assert_equal "POST", response["access-control-allow-methods"]
assert_equal "Content-Type, Authorization, x-csrf-token", response["access-control-allow-headers"]
assert_equal "close", response["Connection"]
end
def test_wait_for_otp_code_get_request
wait_for_otp_code
response = Gem::MockBrowser.get URI("http://localhost:#{@port}?code=xyz")
assert response.is_a? Net::HTTPOK
assert_equal "text/plain", response["Content-Type"]
assert_equal "7", response["Content-Length"]
assert_equal Gem.host, response["access-control-allow-origin"]
assert_equal "POST", response["access-control-allow-methods"]
assert_equal "Content-Type, Authorization, x-csrf-token", response["access-control-allow-headers"]
assert_equal "close", response["Connection"]
assert_equal "success", response.body
@thread.join
assert_equal "xyz", @thread[:otp]
end
def test_wait_for_otp_code_invalid_post_req_method
wait_for_otp_code_expect_error_with_message("Security device verification failed: Invalid HTTP method POST received.")
response = Gem::MockBrowser.post URI("http://localhost:#{@port}?code=xyz")
assert response
assert response.is_a? Net::HTTPMethodNotAllowed
assert_equal "GET, OPTIONS", response["allow"]
assert_equal "close", response["Connection"]
@thread.join
assert_nil @thread[:otp]
end
def test_wait_for_otp_code_incorrect_path
wait_for_otp_code_expect_error_with_message("Security device verification failed: Page at /path not found.")
response = Gem::MockBrowser.post URI("http://localhost:#{@port}/path?code=xyz")
assert response.is_a? Net::HTTPNotFound
assert_equal "close", response["Connection"]
@thread.join
assert_nil @thread[:otp]
end
def test_wait_for_otp_code_no_params_response
wait_for_otp_code_expect_error_with_message("Security device verification failed: Did not receive OTP from https://rubygems.org.")
response = Gem::MockBrowser.get URI("http://localhost:#{@port}")
assert response.is_a? Net::HTTPBadRequest
assert_equal "text/plain", response["Content-Type"]
assert_equal "22", response["Content-Length"]
assert_equal "close", response["Connection"]
assert_equal "missing code parameter", response.body
@thread.join
assert_nil @thread[:otp]
end
def test_wait_for_otp_code_incorrect_params
wait_for_otp_code_expect_error_with_message("Security device verification failed: Did not receive OTP from https://rubygems.org.")
response = Gem::MockBrowser.get URI("http://localhost:#{@port}?param=xyz")
assert response.is_a? Net::HTTPBadRequest
assert_equal "text/plain", response["Content-Type"]
assert_equal "22", response["Content-Length"]
assert_equal "close", response["Connection"]
assert_equal "missing code parameter", response.body
@thread.join
assert_nil @thread[:otp]
end
private
def wait_for_otp_code
@thread = Thread.new do
Thread.current[:otp] = Gem::WebauthnListener.wait_for_otp_code(Gem.host, @server)
end
@thread.abort_on_exception = true
@thread.report_on_exception = false
end
def wait_for_otp_code_expect_error_with_message(message)
@thread = Thread.new do
error = assert_raise Gem::WebauthnVerificationError do
Thread.current[:otp] = Gem::WebauthnListener.wait_for_otp_code(Gem.host, @server)
end
assert_equal message, error.message
end
@thread.abort_on_exception = true
@thread.report_on_exception = false
end
end
|