From 1b16d8a641ae2b23c79075bc6c84e5c9ae06d50c Mon Sep 17 00:00:00 2001 From: Stephen Paul Weber Date: Wed, 12 Nov 2025 16:32:06 -0500 Subject: [PATCH] No more mixin --- lib/backend_sgx.rb | 22 +------- lib/customer.rb | 14 +++-- lib/port_out_pin.rb | 38 ++++++++++--- sgx_jmp.rb | 2 +- test/test_backend_sgx.rb | 115 --------------------------------------- 5 files changed, 39 insertions(+), 152 deletions(-) diff --git a/lib/backend_sgx.rb b/lib/backend_sgx.rb index 8be6b46a75dd8f3fea2d85de4a0c26c7af274847..4401dd0aefd3a56353a7b20b0e16519ca37f6103 100644 --- a/lib/backend_sgx.rb +++ b/lib/backend_sgx.rb @@ -5,7 +5,6 @@ require "blather/stanza/iq/command" require "value_semantics/monkey_patched" require_relative "customer_fwd" -require_relative "port_out_pin" require_relative "not_loaded" require_relative "form_to_h" @@ -16,8 +15,6 @@ class BackendSgx using FormToH - include PortOutPin - value_semantics do jid Blather::JID creds HashOf(Symbol => String) @@ -58,30 +55,13 @@ class BackendSgx end def commands - iq = Blather::Stanza::DiscoItems.new(:get, COMMANDS_DISCO_NODE) - iq.to = jid - iq.from = from_jid + iq = stanza(Blather::Stanza::DiscoItems.new(:get, COMMANDS_DISCO_NODE)) IQ_MANAGER.write(iq).then(&:items).catch { |e| Sentry.capture_exception(e) [] } end - def set_port_out_pin(pin) - cmd = build_port_out_command(:execute) - - IQ_MANAGER.write(cmd).then { |reply| - session_id = reply.command[:sessionid] - submit_cmd = build_submit_form(pin, session_id) - - IQ_MANAGER.write(submit_cmd).then { |submit_reply| - validate_submit_reply!(submit_reply) - }.catch { |e| - handle_pin_submission_error(e) - } - } - end - protected def ibr diff --git a/lib/customer.rb b/lib/customer.rb index b21576c27cb4ff9b8c774dc8943e2d26b0f90170..9201672b0fc612e52669f533557097e7f54d1fa6 100644 --- a/lib/customer.rb +++ b/lib/customer.rb @@ -12,6 +12,7 @@ require_relative "./invites_repo" require_relative "./payment_methods" require_relative "./plan" require_relative "./proxied_jid" +require_relative "./port_out_pin" require_relative "./sip_account" require_relative "./trivial_backend_sgx_repo" @@ -27,7 +28,7 @@ class Customer :expires_at, :monthly_price, :save_plan!, :auto_top_up_amount, :extend_plan, :status def_delegators :@sgx, :deregister!, :register!, :registered?, :set_ogm_url, - :fwd, :transcription_enabled, :set_port_out_pin, :commands + :fwd, :transcription_enabled, :commands def_delegators :@usage, :usage_report, :message_usage, :incr_message_usage, :calling_charges_this_month def_delegators :@financials, :payment_methods, :declines, :mark_decline, @@ -54,13 +55,10 @@ class Customer end def initialize( - customer_id, - jid, + customer_id, jid, sgx:, plan: CustomerPlan.new(customer_id), - balance: BigDecimal(0), - tndetails: {}, - feature_flags: [] + balance: BigDecimal(0), tndetails: {}, feature_flags: [] ) @plan = plan @usage = CustomerUsage.new(customer_id) @@ -126,6 +124,10 @@ class Customer @sgx.jid end + def port_out_pin + PortOutPin.new(@sgx) + end + def reset_sip_account sip_account.with_random_password.put end diff --git a/lib/port_out_pin.rb b/lib/port_out_pin.rb index 871571e2370c4617e081597c73b377003a9d9fac..63b78aa3d48980e9c00a4345f3e7f338684fdc13 100644 --- a/lib/port_out_pin.rb +++ b/lib/port_out_pin.rb @@ -3,25 +3,45 @@ require "blather" require "blather/stanza/iq/command" -module PortOutPin +class PortOutPin + def initialize(sgx) + @sgx = sgx + end + + def set(pin) + cmd = build_command(:execute) + + IQ_MANAGER.write(cmd).then { |reply| + session_id = reply.command[:sessionid] + submit_cmd = build_submit_form(pin, session_id) + + IQ_MANAGER.write(submit_cmd).then { |submit_reply| + validate_submit_reply!(submit_reply) + }.catch { |e| + handle_pin_submission_error(e) + } + } + end + +protected + def build_submit_form(pin, session_id) - build_port_out_command(:complete, session_id: session_id).tap { |iq| + build_command(:complete, session_id: session_id).tap { |iq| iq.form.type = :submit iq.form.fields = [ - { var: "pin", value: pin, type: "text-private" }, - { var: "confirm_pin", value: pin, type: "text-private" } + { var: "pin", value: pin }, + { var: "confirm_pin", value: pin } ] } end - def build_port_out_command(action, session_id: nil) - Blather::Stanza::Iq::Command.new.tap { |iq| - iq.to = jid - iq.from = from_jid + def build_command(action, session_id: nil) + @sgx.stanza(Blather::Stanza::Iq::Command.new.tap { |iq| + iq.to = "" iq.node = "set-port-out-pin" iq.action = action iq.sessionid = session_id if session_id - } + }) end def validate_submit_reply!(submit_reply) diff --git a/sgx_jmp.rb b/sgx_jmp.rb index 2d25a2c3356aa3e9e91d49f398b3e75ec109571e..77c4745c8f8ebd90fa937b7ff228fe7d8d746464 100644 --- a/sgx_jmp.rb +++ b/sgx_jmp.rb @@ -896,7 +896,7 @@ Command.new( raise "PIN and confirm PIN must match." unless pin == confirm_pin - customer.set_port_out_pin(pin) + customer.port_out_pin.set(pin) }.then { Command.finish("Your port-out PIN has been set.") }.catch_only(BackendSgx::CanceledError) do |e| diff --git a/test/test_backend_sgx.rb b/test/test_backend_sgx.rb index bb11b868402ad06633a143b04585b71f2f989116..3f7ff580e9fbabdaa80f313cb4162badeae8539f 100644 --- a/test/test_backend_sgx.rb +++ b/test/test_backend_sgx.rb @@ -59,119 +59,4 @@ class BackendSgxTest < Minitest::Test BackendSgx::IQ_MANAGER.verify end em :test_register! - - def test_set_port_out_pin_happy_path - sgx = TrivialBackendSgxRepo.new(redis: FakeRedis.new).get("test").sync - - port_out_pin = "74hwsn" - session_id = "session_yay_awesome" - - BackendSgx::IQ_MANAGER.expect( - :write, - EMPromise.resolve(Blather::Stanza::Iq::Command.new.tap { |iq| - iq.command[:sessionid] = session_id - }), - [Matching.new do |iq| - assert_equal CONFIG[:sgx], iq.to.to_s - assert_equal "customer_test@component", iq.from.to_s - assert_equal "set-port-out-pin", iq.node - assert_equal :execute, iq.action - end] - ) - - BackendSgx::IQ_MANAGER.expect( - :write, - EMPromise.resolve(OpenStruct.new( - status: :completed, - note_type: :info - )), - [Matching.new do |iq| - assert_equal :complete, iq.action - assert_equal :submit, iq.form.type - assert_equal CONFIG[:sgx], iq.to.to_s - assert_equal "customer_test@component", iq.from.to_s - assert_equal "set-port-out-pin", iq.node - assert_equal session_id, iq.sessionid - - pin_field = iq.form.fields.find { |f| f.var == "pin" } - assert_equal port_out_pin, pin_field.value - assert_equal "text-private", pin_field.type - - confirm_field = iq.form.fields.find { |f| f.var == "confirm_pin" } - assert_equal port_out_pin, confirm_field.value - assert_equal "text-private", confirm_field.type - end] - ) - - result = sgx.set_port_out_pin(port_out_pin).sync - assert_nil result - assert_mock BackendSgx::IQ_MANAGER - end - em :test_set_port_out_pin_happy_path - - def test_set_port_out_pin_validation - sgx = TrivialBackendSgxRepo.new(redis: FakeRedis.new).get("test").sync - - [ - ["123", "PIN must be 4-10 alphanumeric characters"], - ["12345678901", "PIN must be 4-10 alphanumeric characters"], - ["123!", "PIN must be 4-10 alphanumeric characters"], - ["pin with spaces", "PIN must be 4-10 alphanumeric characters"], - ["", "PIN must be 4-10 alphanumeric characters"] - ].each do |invalid_pin, expected_error| - session_id = "session_validation_#{invalid_pin.gsub(/[^a-zA-Z0-9]/, '')}" - - BackendSgx::IQ_MANAGER.expect( - :write, - EMPromise.resolve(Blather::Stanza::Iq::Command.new.tap { |iq| - iq.command[:sessionid] = session_id - }), - [Matching.new do |iq| - assert_equal CONFIG[:sgx], iq.to.to_s - assert_equal "customer_test@component", iq.from.to_s - assert_equal "set-port-out-pin", iq.node - assert_equal :execute, iq.action - end] - ) - - note = Struct.new(:text) do - def [](key) - "error" if key == "type" - end - end.new(expected_error) - - BackendSgx::IQ_MANAGER.expect( - :write, - EMPromise.resolve(OpenStruct.new( - status: :completed, - note: note - )), - [Matching.new do |iq| - assert_equal :complete, iq.action - assert_equal :submit, iq.form.type - assert_equal CONFIG[:sgx], iq.to.to_s - assert_equal "customer_test@component", iq.from.to_s - assert_equal "set-port-out-pin", iq.node - assert_equal session_id, iq.sessionid - - pin_field = iq.form.fields.find { |f| f.var == "pin" } - assert_equal invalid_pin, pin_field.value - assert_equal "text-private", pin_field.type - - confirm_field = iq.form.fields.find { |f| f.var == "confirm_pin" } - assert_equal invalid_pin, confirm_field.value - assert_equal "text-private", confirm_field.type - end] - ) - - error = assert_raises(RuntimeError) { - sgx.set_port_out_pin(invalid_pin).sync - } - - assert_equal expected_error, error.message - end - - assert_mock BackendSgx::IQ_MANAGER - end - em :test_set_port_out_pin_validation end