Class: GlobiGuard::Transport
- Inherits:
-
Object
- Object
- GlobiGuard::Transport
- Defined in:
- lib/globiguard.rb
Constant Summary collapse
- RESERVED_HEADERS =
%w[ x-globiguard-project-id x-globiguard-secret-key x-globiguard-publishable-key x-globiguard-local-mode x-globiguard-local-token x-globiguard-client x-globiguard-environment ].freeze
Class Method Summary collapse
Instance Method Summary collapse
- #auth_headers ⇒ Object
-
#initialize(environment:, services:, credential:) ⇒ Transport
constructor
A new instance of Transport.
- #request(method, path, body: nil, headers: {}) ⇒ Object
Constructor Details
#initialize(environment:, services:, credential:) ⇒ Transport
Returns a new instance of Transport.
66 67 68 69 70 71 72 73 74 75 76 77 78 |
# File 'lib/globiguard.rb', line 66 def initialize(environment:, services:, credential:) raise ArgumentError, "Environment must be local, sandbox, or live." unless ENVIRONMENTS.include?(environment) raise ArgumentError, "Credential environment must match client environment." unless credential.environment == environment @environment = environment @services = services @credential = credential @base_uri = URI(services.fetch("controlPlane")) raise ArgumentError, "HTTPS is required outside local." if environment != "local" && @base_uri.scheme != "https" if credential.kind == "local" && !%w[localhost 127.0.0.1 ::1].include?(@base_uri.host) raise ArgumentError, "Local credentials require localhost or loopback URLs." end end |
Class Method Details
.validate_path(path) ⇒ Object
114 115 116 117 118 119 120 121 |
# File 'lib/globiguard.rb', line 114 def self.validate_path(path) raise ArgumentError, "Request path must start with /." unless path.start_with?("/") if path.start_with?("//") || path.include?("\\") || path.include?("?") || path.include?("#") || path.match?(/%(?![0-9A-Fa-f]{2})/) raise ArgumentError, "Unsafe request path." end raise ArgumentError, "Absolute request paths are not allowed." if URI(path).absolute? raise ArgumentError, "Dot segments are not allowed." if path.split("/").any? { |segment| segment == "." || segment == ".." } end |
Instance Method Details
#auth_headers ⇒ Object
99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
# File 'lib/globiguard.rb', line 99 def auth_headers headers = { "x-globiguard-client" => "globiguard-ruby/#{VERSION}", "x-globiguard-environment" => @environment } if @credential.kind == "local" headers["x-globiguard-local-mode"] = "true" headers["x-globiguard-local-token"] = @credential.token if @credential.token && !@credential.token.empty? else headers["x-globiguard-project-id"] = require_value(@credential.project_id, "project id") headers[@credential.kind == "secret" ? "x-globiguard-secret-key" : "x-globiguard-publishable-key"] = require_value(@credential.token, "credential token") end headers end |
#request(method, path, body: nil, headers: {}) ⇒ Object
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
# File 'lib/globiguard.rb', line 80 def request(method, path, body: nil, headers: {}) self.class.validate_path(path) headers.each_key do |name| raise ArgumentError, "Reserved GlobiGuard header cannot be overridden: #{name}" if RESERVED_HEADERS.include?(name.downcase) end uri = URI(@base_uri.to_s.sub(%r{/+\z}, "") + path) request = Net::HTTP.const_get(method.capitalize).new(uri) auth_headers.merge(headers).each { |name, value| request[name] = value } request["content-type"] = "application/json" if body request.body = JSON.generate(body) if body response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == "https", read_timeout: 30, open_timeout: 30) do |http| http.request(request) end raise "GlobiGuard request failed with #{response.code}: #{response.body}" unless response.is_a?(Net::HTTPSuccess) response.body.nil? || response.body.empty? ? {} : JSON.parse(response.body) end |