diff --git a/forms/snikket_launched.rb b/forms/snikket_launched.rb index 749ed11b8bfb1c87ee550d6e68dbdc8d45d4589f..76ac4360d45000460ce473556caf791c5140daf0 100644 --- a/forms/snikket_launched.rb +++ b/forms/snikket_launched.rb @@ -8,12 +8,12 @@ field( type: "text-single", var: "instance-id", label: "Instance ID", - value: @launched.instance_id + value: @instance.instance_id ) field( type: "text-single", var: "bootstrap-uri", label: "Admin Invite", - value: @launched.bootstrap_uri(@domain) + value: @instance.bootstrap_uri ) diff --git a/lib/registration.rb b/lib/registration.rb index aa30b164090b3967d3903947c42e390575c84fdc..3c7b00c2983a54379f11ed25a9bd0ea89bf30006 100644 --- a/lib/registration.rb +++ b/lib/registration.rb @@ -18,7 +18,7 @@ require_relative "./welcome_message" class Registration def self.for(customer, tel_selections) if (reg = customer.registered?) - Registered.new(reg.phone) + Registered.for(customer, reg.phone) else tel_selections[customer.jid].then(&:choose_tel).then do |tel| BandwidthTnReservationRepo.new.ensure(customer, tel) @@ -28,6 +28,15 @@ class Registration end class Registered + def self.for(customer, tel) + jid = ProxiedJID.new(customer.jid).unproxied + if jid.domain == CONFIG[:onboarding_domain] + FinishOnboarding.for(customer, tel) + else + new(tel) + end + end + def initialize(tel) @tel = tel end @@ -523,14 +532,15 @@ class Registration def self.for(customer, tel) jid = ProxiedJID.new(customer.jid).unproxied if jid.domain == CONFIG[:onboarding_domain] - Snikket.new(tel) + Snikket.new(customer, tel) else NotOnboarding.new(customer, tel) end end class Snikket - def initialize(tel, error: nil) + def initialize(customer, tel, error: nil) + @customer = customer @tel = tel @error = error end @@ -560,31 +570,31 @@ class Registration def launch(domain) IQ_MANAGER.write(::Snikket::Launch.new( - nil, CONFIG[:snikket_hosting_api], - domain: domain + nil, CONFIG[:snikket_hosting_api], domain: domain )).then { |launched| - GetInvite.for(domain, launched).then(&:write) + GetInvite.for( + ::Snikket::CustomerInstance.for(@customer, domain, launched) + ).then(&:write) }.catch { |e| next EMPromise.reject(e) unless e.respond_to?(:text) - Snikket.new(@tel, error: e.text).write + Snikket.new(@customer, @tel, error: e.text).write } end class GetInvite - def self.for(domain, launched) - launched.fetch_invite(domain).then do |xmpp_uri| + def self.for(instance) + instance.fetch_invite.then do |xmpp_uri| if xmpp_uri GoToInvite.new(xmpp_uri) else - new(domain, launched) + new(instance) end end end - def initialize(domain, launched) - @domain = domain - @launched = launched + def initialize(instance) + @instance = instance end def write @@ -592,10 +602,10 @@ class Registration reply.allowed_actions = [:next] reply.note_type = :info reply.note_text = - "Your instance #{@domain} is starting up. " \ + "Your instance #{@instance.domain} is starting up. " \ "This may take several minutes. " \ "Press next to check if it is ready." - }.then { GetInvite.for(@domain, @launched).then(&:write) } + }.then { GetInvite.for(@instance).then(&:write) } end end diff --git a/lib/snikket.rb b/lib/snikket.rb index aa69e8e8530a2b13f96b7f2155b6fdda09090bd4..cfcfa3ca33625dfba1bdb197df3f0e9a5a905605 100644 --- a/lib/snikket.rb +++ b/lib/snikket.rb @@ -47,23 +47,6 @@ module Snikket &.content end - def bootstrap_uri(instance_domain) - "https://#{instance_domain}/invites_bootstrap?token=#{bootstrap_token}" - end - - def fetch_invite(instance_domain) - url = bootstrap_uri(instance_domain) - EM::HttpRequest.new( - url, tls: { verify_peer: true } - ).ahead(redirects: 5).then { |res| - LinkHeaderParser.parse( - Array(res.response_header["LINK"]), base: url - ).group_by_relation_type[:alternate]&.find do |header| - URI.parse(header.target_uri).scheme == "xmpp" - end&.target_uri - }.catch { nil } - end - def query at_xpath("./ns:launched", ns: self.class.registered_ns) end @@ -118,4 +101,69 @@ module Snikket at_xpath("./ns:instance", ns: self.class.registered_ns) end end + + class CustomerInstance + def self.for(customer, domain, launched) + new( + instance_id: launched.instance_id, + bootstrap_token: launched.bootstrap_token, + customer_id: customer.customer_id, + domain: domain + ) + end + + value_semantics do + instance_id String + bootstrap_token String + customer_id String + domain String + end + + def bootstrap_uri + "https://#{domain}/invites_bootstrap?token=#{bootstrap_token}" + end + + def fetch_invite + url = bootstrap_uri + EM::HttpRequest.new( + url, tls: { verify_peer: true } + ).ahead(redirects: 5).then { |res| + LinkHeaderParser.parse( + Array(res.response_header["LINK"]), base: url + ).group_by_relation_type[:alternate]&.find do |header| + URI.parse(header.target_uri).scheme == "xmpp" + end&.target_uri + }.catch { nil } + end + end + + class Repo + def initialize(db: DB) + @db = db + end + + def find_by_customer(customer) + promise = @db.query(<<~SQL, [customer.customer_id]) + SELECT instance_id, bootstrap_token, customer_id, domain + FROM snikket_instances + WHERE customer_id=$1 + SQL + promise.then do |rows| + rows.map { |row| CustomerInstance.new(**row) } + end + end + + def put(instance) + params = [ + instance.instance_id, instance.bootstrap_token, + instance.customer_id, instance.domain + ] + @db.exec(<<~SQL, params) + INSERT INTO snikket_instances + (instance_id, boostrap_token, customer_id, domain) + VALUES + ($1, $2, $3, $4) + SQL + end + end end diff --git a/schemas b/schemas index a9f8b83487140f91fc8da3a3de99f5f28aa060b9..dfb88d581ced2cb82cd1bab454de1afafcb9668d 160000 --- a/schemas +++ b/schemas @@ -1 +1 @@ -Subproject commit a9f8b83487140f91fc8da3a3de99f5f28aa060b9 +Subproject commit dfb88d581ced2cb82cd1bab454de1afafcb9668d diff --git a/sgx_jmp.rb b/sgx_jmp.rb index b449e30889cc9f1c1ccea2a3ffc530fe8e49c781..25608cc5f5e611e2efd29537bf5c2979895bc492 100644 --- a/sgx_jmp.rb +++ b/sgx_jmp.rb @@ -857,14 +857,13 @@ Command.new( nil, CONFIG[:snikket_hosting_api], domain: domain )).then do |launched| - [domain, launched] + Snikket::CustomerInstance.for(customer, domain, launched) end - }.then { |(domain, launched)| + }.then { |instance| Command.finish do |reply| reply.command << FormTemplate.render( "snikket_launched", - launched: launched, - domain: domain + instance: instance ) end } diff --git a/test/test_registration.rb b/test/test_registration.rb index dae782c3fec67e3c6c145cd794e254d842fb47da..a344741a554ff501e5bc2c445ed04847d302e84c 100644 --- a/test/test_registration.rb +++ b/test/test_registration.rb @@ -946,7 +946,10 @@ class RegistrationTest < Minitest::Test def setup @sgx = Minitest::Mock.new(TrivialBackendSgxRepo.new.get("test")) - @snikket = Registration::FinishOnboarding::Snikket.new("+15555550000") + @snikket = Registration::FinishOnboarding::Snikket.new( + customer, + "+15555550000" + ) end def test_write @@ -961,6 +964,11 @@ class RegistrationTest < Minitest::Test launched << Niceogiri::XML::Node.new( :launched, launched.document, "xmpp:snikket.org/hosting/v1" ).tap { |inner| + inner << Niceogiri::XML::Node.new( + :'instance-id', launched.document, "xmpp:snikket.org/hosting/v1" + ).tap { |id| + id.content = "si-1234" + } inner << Niceogiri::XML::Node.new( :bootstrap, launched.document, "xmpp:snikket.org/hosting/v1" ).tap { |bootstrap| @@ -1040,6 +1048,11 @@ class RegistrationTest < Minitest::Test launched << Niceogiri::XML::Node.new( :launched, launched.document, "xmpp:snikket.org/hosting/v1" ).tap { |inner| + inner << Niceogiri::XML::Node.new( + :'instance-id', launched.document, "xmpp:snikket.org/hosting/v1" + ).tap { |id| + id.content = "si-1234" + } inner << Niceogiri::XML::Node.new( :bootstrap, launched.document, "xmpp:snikket.org/hosting/v1" ).tap { |bootstrap| diff --git a/test/test_snikket.rb b/test/test_snikket.rb index 26e89f258a7bcf51bf379146c7b947a7e6d2bf5a..8ea5df2c1bfc7105cf8429a40203f8e6b7023f94 100644 --- a/test/test_snikket.rb +++ b/test/test_snikket.rb @@ -30,10 +30,6 @@ class TestSnikket < Minitest::Test assert_equal :result, launched.type assert_equal NS, launched.query.namespace.href assert_equal "launched", launched.query.node_name - assert_equal( - "https://example.com/invites_bootstrap?token=fZLy6iTh", - launched.bootstrap_uri("example.com") - ) assert_equal "si-12345", launched.instance_id end @@ -70,4 +66,18 @@ class TestSnikket < Minitest::Test assert_kind_of Nokogiri::XML::Element, instance.operation assert_equal :up, instance.status end + + def test_bootstrap_uri + instance = Snikket::CustomerInstance.new( + instance_id: "si-1234", + bootstrap_token: "fZLy6iTh", + customer_id: "test", + domain: "example.com" + ) + + assert_equal( + "https://example.com/invites_bootstrap?token=fZLy6iTh", + instance.bootstrap_uri + ) + end end