Module: OpenReceive::Server::LscUri

Defined in:
lib/openreceive/server/lsc_uri.rb

Constant Summary collapse

SCHEME =
"lightning+swapconnect"
ENV_NAMES =
%w[LSC_URI_PRIMARY LSC_URI_BACKUP].freeze
QUERY_PARAMETERS =
%w[key secret].freeze
MAX_URI_LENGTH =
8192
MAX_CREDENTIAL_LENGTH =
2048

Class Method Summary collapse

Class Method Details

.parse(value) ⇒ Object



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
# File 'lib/openreceive/server/lsc_uri.rb', line 16

def parse(value)
  input = credential(value, "LSC URI", MAX_URI_LENGTH)
  uri = URI.parse(input)
  raise ArgumentError, "LSC URI must use #{SCHEME}://." unless uri.scheme == SCHEME
  raise ArgumentError, "LSC URI must not use URI userinfo." unless uri.userinfo.nil?
  raise ArgumentError, "LSC URI requires a provider hostname." if uri.host.to_s.empty?
  raise ArgumentError, "LSC URI must not contain a fragment." unless uri.fragment.nil?
  raise ArgumentError, "LSC URI query encoding is invalid." if uri.query.to_s.match?(/%(?![0-9a-f]{2})/i)

  begin
    pairs = URI.decode_www_form(uri.query.to_s)
  rescue ArgumentError
    raise ArgumentError, "LSC URI query encoding is invalid."
  end
  unsupported = pairs.map(&:first).find { |name| !QUERY_PARAMETERS.include?(name) }
  raise ArgumentError, "LSC URI contains an unsupported query parameter." unless unsupported.nil?

  key = credential(single_parameter(pairs, "key"), "LSC URI key", MAX_CREDENTIAL_LENGTH)
  secret = credential(single_parameter(pairs, "secret"), "LSC URI secret", MAX_CREDENTIAL_LENGTH)
  path = normalize_path(uri.path)
  port = uri.port.nil? ? "" : ":#{uri.port}"

  {
    "uri_protocol" => "#{SCHEME}:",
    "base_url" => "https://#{uri.host}#{port}#{path}",
    "provider_id" => provider_id(uri),
    "key" => key,
    "secret" => secret
  }.freeze
rescue URI::InvalidURIError
  raise ArgumentError, "LSC URI is not a valid absolute URI."
end

.read_environment(env = ENV) ⇒ Object



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/openreceive/server/lsc_uri.rb', line 49

def read_environment(env = ENV)
  provider_ids = {}
  ENV_NAMES.each_with_object([]) do |name, connections|
    value = env[name].to_s.strip
    next if value.empty?

    connection = parse(value)
    id = connection.fetch("provider_id")
    raise ArgumentError, "#{name} duplicates another LSC provider id." if provider_ids[id]

    provider_ids[id] = true
    connections << connection
  rescue ArgumentError => e
    raise ArgumentError, "#{name} is invalid: #{e.message}"
  end.freeze
end