M Gemfile => Gemfile +1 -1
@@ 18,7 18,7 @@ gem "multibases"
gem "multihashes"
gem "ougai"
gem "roda"
-gem "ruby-bandwidth-iris"
+gem "ruby-bandwidth-iris", git: "https://github.com/singpolyma/ruby-bandwidth-iris", branch: "sip_credential"
gem "sentry-ruby", "<= 4.3.1"
gem "slim"
gem "statsd-instrument", git: "https://github.com/singpolyma/statsd-instrument.git", branch: "graphite"
M config-schema.dhall => config-schema.dhall +1 -1
@@ 1,7 1,6 @@
{ activation_amount : Natural
, admins : List Text
, adr : Text
-, bandwidth_app : Text
, bandwidth_peer : Text
, bandwidth_site : Text
, braintree :
@@ 44,6 43,7 @@
}
, server : { host : Text, port : Natural }
, sgx : Text
+, sip : { app : Text, realm : Text }
, sip_host : Text
, upstream_domain : Text
, web : < Inet : { interface : Text, port : Natural } | Unix : Text >
M config.dhall.sample => config.dhall.sample +4 -1
@@ 33,7 33,6 @@ in
},
bandwidth_site = "",
bandwidth_peer = "",
- bandwidth_app = "", -- This can be any voice app
braintree = {
environment = "sandbox",
merchant_id = "",
@@ 47,6 46,10 @@ in
xep0157 = [
{ var = "support-addresses", value = "xmpp:+14169938000@cheogram.com", label = "Support" }
],
+ sip = {
+ realm = "",
+ app = ""
+ },
notify_admin = "muc@example.com",
sip_host = "sip.jmp.chat",
plans = [
M lib/customer.rb => lib/customer.rb +1 -3
@@ 92,9 92,7 @@ class Customer
end
def reset_sip_account
- SipAccount::New.new(username: customer_id).put.catch do
- sip_account.then { |acct| acct.with_random_password.put }
- end
+ sip_account.with_random_password.put
end
def btc_addresses
M lib/sip_account.rb => lib/sip_account.rb +44 -60
@@ 1,44 1,38 @@
# frozen_string_literal: true
-require "em-synchrony/em-http" # For aget vs get
+require "digest"
require "securerandom"
require "value_semantics/monkey_patched"
-require_relative "./catapult"
-require_relative "./mn_words"
+require_relative "mn_words"
class SipAccount
def self.find(name)
- CATAPULT.endpoint_find(name).then do |found|
- next New.new(username: name) unless found
-
- new(username: found["name"], url: found["url"])
- end
+ new(BandwidthIris::SipCredential.get(name))
+ rescue BandwidthIris::Errors::GenericError # 404
+ New.new(BandwidthIris::SipCredential.new(
+ user_name: name,
+ realm: CONFIG[:sip][:realm],
+ http_voice_v2_app_id: CONFIG[:sip][:app]
+ ))
end
- module Common
- def with_random_password
- with(password: MN_WORDS.sample(3).join(" "))
- end
-
- protected
-
- def create
- CATAPULT.create_endpoint(
- name: username,
- credentials: { password: password }
- ).then do |url|
- with(url: url)
- end
- end
+ def initialize(api_object, password: nil)
+ @api_object = api_object
+ @password = password
end
- include Common
+ def with(password:)
+ self.class.new(@api_object.class.new(@api_object.to_data.merge(
+ hash1: Digest::MD5.hexdigest("#{username}:#{server}:#{password}"),
+ hash1b: Digest::MD5.hexdigest(
+ "#{username}:#{server}:#{server}:#{password}"
+ )
+ )), password: password)
+ end
- value_semantics do
- url String
- username String
- password Either(String, nil), default: nil
+ def with_random_password
+ with(password: MN_WORDS.sample(3).join(" "))
end
def form
@@ 48,7 42,7 @@ class SipAccount
form.fields = [
{ var: "username", value: username, label: "Username" },
- { var: "password", value: password, label: "Password" },
+ { var: "password", value: @password, label: "Password" },
{ var: "server", value: server, label: "Server" }
]
@@ 56,47 50,37 @@ class SipAccount
end
def put
- delete.then { create }
+ @api_object.update(
+ hash1: @api_object.hash1,
+ hash1b: @api_object.hash1b,
+ realm: server,
+ http_voice_v2_app_id: @api_object.http_voice_v2_app_id
+ )
+ self
end
def delete
- CATAPULT.delete(url).then do |http|
- unless http.response_header.status == 200
- raise "Delete old SIP account failed"
- end
-
- self
- end
+ @api_object.delete
end
-protected
-
- protected :url, :username, :password
+ def username
+ @api_object.user_name.to_s
+ end
def server
- CATAPULT.sip_host
+ @api_object.realm
end
- class New
- include Common
-
- value_semantics do
- username String
- password String, default_generator: -> { MN_WORDS.sample(3).join(" ") }
- end
-
+ class New < SipAccount
def put
- create
- end
-
- def with(**kwargs)
- if kwargs.key?(:url)
- SipAccount.new(internal_to_h.merge(kwargs))
- else
- super
- end
+ BandwidthIris::SipCredential.create(
+ user_name: username,
+ hash1: @api_object.hash1,
+ hash1b: @api_object.hash1b,
+ realm: server,
+ http_voice_v2_app_id: @api_object.http_voice_v2_app_id
+ )
+ self
end
-
- protected :username, :password
end
end
M sgx_jmp.rb => sgx_jmp.rb +3 -3
@@ 473,7 473,7 @@ Command.new(
CONFIG[:creds][:account],
body: customer.fwd.create_call_request do |cc|
cc.from = customer.registered?.phone
- cc.application_id = CONFIG[:bandwidth_app]
+ cc.application_id = CONFIG[:sip][:app]
cc.answer_url = "#{CONFIG[:web_root]}/ogm/start?" \
"customer_id=#{customer.customer_id}"
end
@@ 599,9 599,9 @@ Command.new(
"reset sip account",
"Create or Reset SIP Account"
) {
- Command.customer.then(&:reset_sip_account).then do |sip_account|
+ Command.customer.then do |customer|
Command.finish do |reply|
- reply.command << sip_account.form
+ reply.command << customer.reset_sip_account.form
end
end
}.register(self).then(&CommandList.method(:register))
D test/data/catapult_create_sip.json => test/data/catapult_create_sip.json +0 -1
@@ 1,1 0,0 @@
-{"applicationId":"catapult_app","name":"12345","credentials":{"password":"old password"}}
M test/test_customer.rb => test/test_customer.rb +14 -42
@@ 13,14 13,6 @@ CustomerPlan::DB = Minitest::Mock.new
CustomerUsage::REDIS = Minitest::Mock.new
CustomerUsage::DB = Minitest::Mock.new
-class SipAccount
- public :username, :url
-
- class New
- public :username
- end
-end
-
class CustomerTest < Minitest::Test
def test_bill_plan_activate
CustomerPlan::DB.expect(:transaction, nil) do |&block|
@@ 152,14 144,13 @@ class CustomerTest < Minitest::Test
def test_sip_account_new
req = stub_request(
:get,
- "https://api.catapult.inetwork.com/v1/users/" \
- "catapult_user/domains/catapult_domain/endpoints?page=0&size=1000"
+ "https://dashboard.bandwidth.com/v1.0/accounts//sipcredentials/test"
).with(
headers: {
- "Authorization" => "Basic Y2F0YXB1bHRfdG9rZW46Y2F0YXB1bHRfc2VjcmV0"
+ "Authorization" => "Basic Og=="
}
).to_return(status: 404)
- sip = customer.sip_account.sync
+ sip = customer.sip_account
assert_kind_of SipAccount::New, sip
assert_equal "test", sip.username
assert_requested req
@@ 169,52 160,33 @@ class CustomerTest < Minitest::Test
def test_sip_account_existing
req1 = stub_request(
:get,
- "https://api.catapult.inetwork.com/v1/users/" \
- "catapult_user/domains/catapult_domain/endpoints?page=0&size=1000"
+ "https://dashboard.bandwidth.com/v1.0/accounts//sipcredentials/test"
).with(
headers: {
- "Authorization" => "Basic Y2F0YXB1bHRfdG9rZW46Y2F0YXB1bHRfc2VjcmV0"
+ "Authorization" => "Basic Og=="
}
- ).to_return(status: 200, body: [
- { name: "NOTtest", domainId: "domain", id: "endpoint" }
- ].to_json)
-
- req2 = stub_request(
- :get,
- "https://api.catapult.inetwork.com/v1/users/" \
- "catapult_user/domains/catapult_domain/endpoints?page=1&size=1000"
- ).with(
- headers: {
- "Authorization" => "Basic Y2F0YXB1bHRfdG9rZW46Y2F0YXB1bHRfc2VjcmV0"
+ ).to_return(status: 200, body: {
+ SipCredential: {
+ UserName: "test",
+ Realm: "sip.example.com"
}
- ).to_return(status: 200, body: [
- { name: "test", domainId: "domain", id: "endpoint" }
- ].to_json)
+ }.to_xml)
- sip = customer.sip_account.sync
+ sip = customer.sip_account
assert_kind_of SipAccount, sip
assert_equal "test", sip.username
- assert_equal(
- "https://api.catapult.inetwork.com/v1/users/" \
- "catapult_user/domains/domain/endpoints/endpoint",
- sip.url
- )
assert_requested req1
- assert_requested req2
end
em :test_sip_account_existing
def test_sip_account_error
stub_request(
:get,
- "https://api.catapult.inetwork.com/v1/users/" \
- "catapult_user/domains/catapult_domain/endpoints?page=0&size=1000"
- ).to_return(status: 400)
+ "https://dashboard.bandwidth.com/v1.0/accounts//sipcredentials/test"
+ ).to_return(status: 404)
- assert_raises(RuntimeError) do
- customer.sip_account.sync
- end
+ assert_equal "test", customer.sip_account.username
end
em :test_sip_account_error
M test/test_helper.rb => test/test_helper.rb +4 -0
@@ 94,6 94,10 @@ CONFIG = {
USD: "merchant_usd"
}
},
+ sip: {
+ realm: "sip.example.com",
+ app: "sipappid"
+ },
credit_card_url: ->(*) { "http://creditcard.example.com" },
electrum_notify_url: ->(*) { "http://notify.example.com" },
upstream_domain: "example.net"
M test/test_sip_account.rb => test/test_sip_account.rb +45 -57
@@ 4,21 4,18 @@ require "test_helper"
require "sip_account"
class SipAccount
- public :password, :url
-
- class New
- public :password
- end
+ attr_reader :password
end
class SipAccountTest < Minitest::Test
def setup
@sip = SipAccount.new(
- url: "https://api.catapult.inetwork.com/v1/" \
- "users/catapult_user/domains/catapult_domain/endpoints/test",
- username: "12345",
- password: "old password"
- )
+ BandwidthIris::SipCredential.new(
+ user_name: "12345",
+ realm: "sip.example.com",
+ http_voice_v2_app_id: "sipappid"
+ )
+ ).with(password: "old password")
end
def test_with_random_password
@@ 32,61 29,52 @@ class SipAccountTest < Minitest::Test
form = @sip.form
assert_equal "12345", form.field("username").value
assert_equal "old password", form.field("password").value
- assert_equal "host.bwapp.io.example.com", form.field("server").value
+ assert_equal "sip.example.com", form.field("server").value
end
def test_put
- delete = stub_request(:delete, @sip.url).with(
- headers: {
- "Authorization" => "Basic Y2F0YXB1bHRfdG9rZW46Y2F0YXB1bHRfc2VjcmV0"
- }
- ).to_return(status: 200)
-
- post = stub_request(
- :post,
- "https://api.catapult.inetwork.com/v1/users/" \
- "catapult_user/domains/catapult_domain/endpoints"
+ put = stub_request(
+ :put,
+ "https://dashboard.bandwidth.com/v1.0/accounts//sipcredentials/12345"
).with(
- body: open(__dir__ + "/data/catapult_create_sip.json").read.chomp,
+ body: {
+ Hash1: "73b05bcaf9096438c978aecff5f7cc45",
+ Hash1b: "2b7fe68f6337ef4db29e752684a18db4",
+ Realm: "sip.example.com",
+ HttpVoiceV2AppId: "sipappid"
+ }.to_xml(indent: 0, root: "SipCredential"),
headers: {
- "Authorization" => "Basic Y2F0YXB1bHRfdG9rZW46Y2F0YXB1bHRfc2VjcmV0",
- "Content-Type" => "application/json"
+ "Authorization" => "Basic Og=="
}
).to_return(
status: 201,
headers: { "Location" => "http://example.com/endpoint" }
)
- new_sip = @sip.put.sync
- assert_equal "http://example.com/endpoint", new_sip.url
- assert_requested delete
- assert_requested post
+ new_sip = @sip.put
+ assert_equal "12345", new_sip.username
+ assert_requested put
end
em :test_put
- def test_put_delete_fail
- stub_request(:delete, @sip.url).to_return(status: 400)
- assert_raises(RuntimeError) { @sip.put.sync }
- end
- em :test_put_delete_fail
-
- def test_put_post_fail
- stub_request(:delete, @sip.url).to_return(status: 200)
+ def test_put_fail
stub_request(
- :post,
- "https://api.catapult.inetwork.com/v1/users/" \
- "catapult_user/domains/catapult_domain/endpoints"
+ :put,
+ "https://dashboard.bandwidth.com/v1.0/accounts//sipcredentials/12345"
).to_return(status: 400)
- assert_raises(RuntimeError) { @sip.put.sync }
+ assert_raises(BandwidthIris::Errors::GenericError) { @sip.put }
end
- em :test_put_post_fail
+ em :test_put_fail
class NewTest < Minitest::Test
def setup
- @sip = SipAccount::New.new(
- username: "12345",
- password: "old password"
- )
+ @sip = SipAccount.new(
+ BandwidthIris::SipCredential.new(
+ user_name: "12345",
+ realm: "sip.example.com",
+ http_voice_v2_app_id: "sipappid"
+ )
+ ).with(password: "old password")
end
def test_with_random_password
@@ 98,22 86,22 @@ class SipAccountTest < Minitest::Test
def test_put
post = stub_request(
- :post,
- "https://api.catapult.inetwork.com/v1/users/" \
- "catapult_user/domains/catapult_domain/endpoints"
+ :put,
+ "https://dashboard.bandwidth.com/v1.0/accounts//sipcredentials/12345"
).with(
- body: open(__dir__ + "/data/catapult_create_sip.json").read.chomp,
+ body: {
+ Hash1: "73b05bcaf9096438c978aecff5f7cc45",
+ Hash1b: "2b7fe68f6337ef4db29e752684a18db4",
+ Realm: "sip.example.com",
+ HttpVoiceV2AppId: "sipappid"
+ }.to_xml(indent: 0, root: "SipCredential"),
headers: {
- "Authorization" => "Basic Y2F0YXB1bHRfdG9rZW46Y2F0YXB1bHRfc2VjcmV0",
- "Content-Type" => "application/json"
+ "Authorization" => "Basic Og=="
}
- ).to_return(
- status: 201,
- headers: { "Location" => "http://example.com/endpoint" }
- )
+ ).to_return(status: 201)
- new_sip = @sip.put.sync
- assert_equal "http://example.com/endpoint", new_sip.url
+ new_sip = @sip.put
+ assert_equal "12345", new_sip.username
assert_requested post
end
em :test_put