diff options
Diffstat (limited to 'lib')
6 files changed, 147 insertions, 0 deletions
diff --git a/lib/rubygems/webauthn_listener/response.rb b/lib/rubygems/webauthn_listener/response.rb new file mode 100644 index 0000000000..c4ab492f82 --- /dev/null +++ b/lib/rubygems/webauthn_listener/response.rb @@ -0,0 +1,75 @@ +# frozen_string_literal: true + +## +# The WebauthnListener Response class is used by the WebauthnListener to print +# the specified response to the Gem host using the provided socket. It also closes +# the socket after printing the response. +# +# Types of response classes: +# - ResponseOk +# - ResponseNoContent +# - ResponseBadRequest +# - ResponseNotFound +# - ResponseMethodNotAllowed +# +# Example: +# socket = TCPSocket.new(host, port) +# Gem::WebauthnListener::ResponseOk.send(socket, host) +# + +class Gem::WebauthnListener + class Response + attr_reader :host + + def initialize(host) + @host = host + end + + def self.send(socket, host) + socket.print new(host).payload + socket.close + end + + def payload + status_line_and_connection + access_control_headers + content + end + + private + + def status_line_and_connection + <<~RESPONSE + HTTP/1.1 #{status} + Connection: close + RESPONSE + end + + def access_control_headers + return "" unless add_access_control_headers? + <<~RESPONSE + Access-Control-Allow-Origin: #{host} + Access-Control-Allow-Methods: POST + Access-Control-Allow-Headers: Content-Type, Authorization, x-csrf-token + RESPONSE + end + + def content + return "" unless body + <<~RESPONSE + Content-Type: text/plain + Content-Length: #{body.bytesize} + + #{body} + RESPONSE + end + + def status + raise NotImplementedError + end + + def add_access_control_headers? + false + end + + def body; end + end +end diff --git a/lib/rubygems/webauthn_listener/response/response_bad_request.rb b/lib/rubygems/webauthn_listener/response/response_bad_request.rb new file mode 100644 index 0000000000..031c72e08e --- /dev/null +++ b/lib/rubygems/webauthn_listener/response/response_bad_request.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true +require_relative "../response" + +class Gem::WebauthnListener::ResponseBadRequest < Gem::WebauthnListener::Response + private + + def status + "400 Bad Request" + end + + def body + "missing code parameter" + end +end diff --git a/lib/rubygems/webauthn_listener/response/response_method_not_allowed.rb b/lib/rubygems/webauthn_listener/response/response_method_not_allowed.rb new file mode 100644 index 0000000000..ae071fc242 --- /dev/null +++ b/lib/rubygems/webauthn_listener/response/response_method_not_allowed.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true +require_relative "../response" + +class Gem::WebauthnListener::ResponseMethodNotAllowed < Gem::WebauthnListener::Response + private + + def status + "405 Method Not Allowed" + end + + def content + <<~RESPONSE + Allow: GET, OPTIONS + RESPONSE + end +end diff --git a/lib/rubygems/webauthn_listener/response/response_no_content.rb b/lib/rubygems/webauthn_listener/response/response_no_content.rb new file mode 100644 index 0000000000..39aad7fe96 --- /dev/null +++ b/lib/rubygems/webauthn_listener/response/response_no_content.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true +require_relative "../response" + +class Gem::WebauthnListener::ResponseNoContent < Gem::WebauthnListener::Response + private + + def status + "204 No Content" + end + + def add_access_control_headers? + true + end +end diff --git a/lib/rubygems/webauthn_listener/response/response_not_found.rb b/lib/rubygems/webauthn_listener/response/response_not_found.rb new file mode 100644 index 0000000000..c1207cea36 --- /dev/null +++ b/lib/rubygems/webauthn_listener/response/response_not_found.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true +require_relative "../response" + +class Gem::WebauthnListener::ResponseNotFound < Gem::WebauthnListener::Response + private + + def status + "404 Not Found" + end +end diff --git a/lib/rubygems/webauthn_listener/response/response_ok.rb b/lib/rubygems/webauthn_listener/response/response_ok.rb new file mode 100644 index 0000000000..c4e7de3e2c --- /dev/null +++ b/lib/rubygems/webauthn_listener/response/response_ok.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true +require_relative "../response" + +class Gem::WebauthnListener::ResponseOk < Gem::WebauthnListener::Response + private + + def status + "200 OK" + end + + def add_access_control_headers? + true + end + + def body + "success" + end +end |