Maintenance: Aligned the integration handling for sipgate.

This commit is contained in:
Dominik Klein 2021-11-26 14:07:03 +01:00 committed by Martin Gruner
parent b5feb6f4c9
commit 1cfd323845
9 changed files with 136 additions and 43 deletions

View file

@ -57,6 +57,7 @@ class Form extends App.Controller
@html App.view('integration/sipgate')(
config: @config
sipgate_token: App.Setting.get('sipgate_token')
)
configure_attributes = [

View file

@ -14,10 +14,10 @@
<tbody>
<tr>
<td class="settings-list-row-control"><%- @T('Inbound') %>
<td class="settings-list-control-cell"><input type="url" class="form-control form-control--small js-select" readonly value="<%- @C('http_type') %>://<%- @C('fqdn') %>/api/v1/sipgate/in">
<td class="settings-list-control-cell"><input type="url" class="form-control form-control--small js-select" readonly value="<%- @C('http_type') %>://<%- @C('fqdn') %>/api/v1/sipgate/<%= @sipgate_token %>/in">
<tr>
<td class="settings-list-row-control"><%- @T('Outbound') %>
<td class="settings-list-control-cell"><input type="url" class="form-control form-control--small js-select" readonly value="<%- @C('http_type') %>://<%- @C('fqdn') %>/api/v1/sipgate/out">
<td class="settings-list-control-cell"><input type="url" class="form-control form-control--small js-select" readonly value="<%- @C('http_type') %>://<%- @C('fqdn') %>/api/v1/sipgate/<%= @sipgate_token %>/out">
</tbody>
</table>
</div>

View file

@ -4,7 +4,7 @@ require 'builder'
class Integration::SipgateController < ApplicationController
skip_before_action :verify_csrf_token
before_action :check_configured
before_action :check_configured, :check_token
# notify about inbound call / block inbound call
def event
@ -38,6 +38,15 @@ class Integration::SipgateController < ApplicationController
private
def check_token
if Setting.get('sipgate_token') != params[:token]
response_unauthorized(__('Invalid token, please contact your admin!'))
return
end
true
end
def check_configured
http_log_config facility: 'sipgate.io'
@ -57,13 +66,13 @@ class Integration::SipgateController < ApplicationController
@config_integration ||= Setting.get('sipgate_config')
end
def xml_error(error)
def xml_error(error, code = 422)
xml = Builder::XmlMarkup.new(indent: 2)
xml.instruct!
content = xml.Response() do
xml.Error(error)
end
send_data content, type: 'application/xml; charset=UTF-8;', status: 422
send_data content, type: 'application/xml; charset=UTF-8;', status: code
end
def base_url
@ -72,13 +81,17 @@ class Integration::SipgateController < ApplicationController
if fqdn.blank?
fqdn = Setting.get('fqdn')
end
"#{http_type}://#{fqdn}/api/v1/sipgate"
"#{http_type}://#{fqdn}/api/v1/sipgate/#{Setting.get('sipgate_token')}"
end
def url
"#{base_url}/#{params['direction']}"
end
def response_unauthorized(error)
xml_error(error, 401)
end
def response_reject(_result)
xml = Builder::XmlMarkup.new(indent: 2)
xml.instruct!

View file

@ -2,7 +2,7 @@
Zammad::Application.routes.draw do
match '/api/v1/sipgate/in', to: 'integration/sipgate#event', via: :post
match '/api/v1/sipgate/out', to: 'integration/sipgate#event', via: :post
match '/api/v1/sipgate/:token/in/', to: 'integration/sipgate#event', via: :post
match '/api/v1/sipgate/:token/out/', to: 'integration/sipgate#event', via: :post
end

View file

@ -0,0 +1,29 @@
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
class MaintenanceImproveSipgateIntegrationHandling < ActiveRecord::Migration[6.0]
def change
return if !Setting.exists?(name: 'system_init_done')
Setting.create_if_not_exists(
title: __('sipgate.io Token'),
name: 'sipgate_token',
area: 'Integration::Sipgate',
description: __('Token for Sipgate.'),
options: {
form: [
{
display: '',
null: false,
name: 'sipgate_token',
tag: 'input',
},
],
},
state: ENV['SIPGATE_TOKEN'] || SecureRandom.urlsafe_base64(20),
preferences: {
permission: ['admin.integration'],
},
frontend: false
)
end
end

View file

@ -4515,6 +4515,27 @@ Setting.create_if_not_exists(
},
frontend: true
)
Setting.create_if_not_exists(
title: __('sipgate.io Token'),
name: 'sipgate_token',
area: 'Integration::Sipgate',
description: __('Token for Sipgate.'),
options: {
form: [
{
display: '',
null: false,
name: 'sipgate_token',
tag: 'input',
},
],
},
state: ENV['SIPGATE_TOKEN'] || SecureRandom.urlsafe_base64(20),
preferences: {
permission: ['admin.integration'],
},
frontend: false
)
Setting.create_if_not_exists(
title: __('sipgate.io config'),
name: 'sipgate_config',

View file

@ -5208,6 +5208,7 @@ msgstr ""
#: app/controllers/integration/cti_controller.rb
#: app/controllers/integration/placetel_controller.rb
#: app/controllers/integration/sipgate_controller.rb
msgid "Invalid token, please contact your admin!"
msgstr ""
@ -9491,6 +9492,11 @@ msgstr ""
msgid "Token for CTI."
msgstr ""
#: db/migrate/20211118081558_maintenance_improve_sipgate_integration_handling.rb
#: db/seeds/settings.rb
msgid "Token for Sipgate."
msgstr ""
#: db/seeds/settings.rb
msgid "Token for monitoring."
msgstr ""
@ -11340,6 +11346,11 @@ msgstr ""
msgid "show more"
msgstr ""
#: db/migrate/20211118081558_maintenance_improve_sipgate_integration_handling.rb
#: db/seeds/settings.rb
msgid "sipgate.io Token"
msgstr ""
#: db/seeds/settings.rb
msgid "sipgate.io alternative FQDN"
msgstr ""

View file

@ -74,12 +74,25 @@ RSpec.describe 'Integration Sipgate', type: :request do
end
describe 'request handling' do
it 'does token check' do
params = 'event=newCall&direction=in&from=4912347114711&to=4930600000000&callId=4991155921769858278-1&user%5B%5D=user+1&user%5B%5D=user+2'
post '/api/v1/sipgate/not_existing_token/in', params: params
expect(response).to have_http_status(:unauthorized)
error = nil
local_response = REXML::Document.new(response.body)
local_response.elements.each('Response/Error') do |element|
error = element.text
end
expect(error).to eq('Invalid token, please contact your admin!')
end
it 'does basic call' do
token = Setting.get('sipgate_token')
# inbound - I
params = 'event=newCall&direction=in&from=4912347114711&to=4930600000000&callId=4991155921769858278-1&user%5B%5D=user+1&user%5B%5D=user+2'
post '/api/v1/sipgate/in', params: params
post "/api/v1/sipgate/#{token}/in", params: params
expect(@response).to have_http_status(:ok)
on_hangup = nil
on_answer = nil
@ -89,12 +102,12 @@ RSpec.describe 'Integration Sipgate', type: :request do
on_hangup = element.attributes['onHangup']
on_answer = element.attributes['onAnswer']
end
expect(on_hangup).to eq('http://zammad.example.com/api/v1/sipgate/in')
expect(on_answer).to eq('http://zammad.example.com/api/v1/sipgate/in')
expect(on_hangup).to eq("http://zammad.example.com/api/v1/sipgate/#{token}/in")
expect(on_answer).to eq("http://zammad.example.com/api/v1/sipgate/#{token}/in")
# inbound - II - block caller
params = 'event=newCall&direction=in&from=491715000000&to=4930600000000&callId=4991155921769858278-2&user%5B%5D=user+1&user%5B%5D=user+2'
post '/api/v1/sipgate/in', params: params
post "/api/v1/sipgate/#{token}/in", params: params
expect(@response).to have_http_status(:ok)
on_hangup = nil
on_answer = nil
@ -104,8 +117,8 @@ RSpec.describe 'Integration Sipgate', type: :request do
on_hangup = element.attributes['onHangup']
on_answer = element.attributes['onAnswer']
end
expect(on_hangup).to eq('http://zammad.example.com/api/v1/sipgate/in')
expect(on_answer).to eq('http://zammad.example.com/api/v1/sipgate/in')
expect(on_hangup).to eq("http://zammad.example.com/api/v1/sipgate/#{token}/in")
expect(on_answer).to eq("http://zammad.example.com/api/v1/sipgate/#{token}/in")
reason = nil
response.elements.each('Response/Reject') do |element|
reason = element.attributes['reason']
@ -114,7 +127,7 @@ RSpec.describe 'Integration Sipgate', type: :request do
# outbound - I - set default_caller_id
params = 'event=newCall&direction=out&from=4930600000000&to=4912347114711&callId=8621106404543334274-3&user%5B%5D=user+1'
post '/api/v1/sipgate/out', params: params
post "/api/v1/sipgate/#{token}/out", params: params
expect(@response).to have_http_status(:ok)
on_hangup = nil
on_answer = nil
@ -134,12 +147,12 @@ RSpec.describe 'Integration Sipgate', type: :request do
end
expect(caller_id).to eq('4930777000000')
expect(number_to_dail).to eq('4912347114711')
expect(on_hangup).to eq('http://zammad.example.com/api/v1/sipgate/out')
expect(on_answer).to eq('http://zammad.example.com/api/v1/sipgate/out')
expect(on_hangup).to eq("http://zammad.example.com/api/v1/sipgate/#{token}/out")
expect(on_answer).to eq("http://zammad.example.com/api/v1/sipgate/#{token}/out")
# outbound - II - set caller_id based on routing_table by explicite number
params = 'event=newCall&direction=out&from=4930600000000&to=491714000000&callId=8621106404543334274-4&user%5B%5D=user+1'
post '/api/v1/sipgate/out', params: params
post "/api/v1/sipgate/#{token}/out", params: params
expect(@response).to have_http_status(:ok)
on_hangup = nil
on_answer = nil
@ -159,12 +172,12 @@ RSpec.describe 'Integration Sipgate', type: :request do
end
expect(caller_id).to eq('41715880339000')
expect(number_to_dail).to eq('491714000000')
expect(on_hangup).to eq('http://zammad.example.com/api/v1/sipgate/out')
expect(on_answer).to eq('http://zammad.example.com/api/v1/sipgate/out')
expect(on_hangup).to eq("http://zammad.example.com/api/v1/sipgate/#{token}/out")
expect(on_answer).to eq("http://zammad.example.com/api/v1/sipgate/#{token}/out")
# outbound - III - set caller_id based on routing_table by 41*
params = 'event=newCall&direction=out&from=4930600000000&to=4147110000000&callId=8621106404543334274-5&user%5B%5D=user+1'
post '/api/v1/sipgate/out', params: params
post "/api/v1/sipgate/#{token}/out", params: params
expect(@response).to have_http_status(:ok)
on_hangup = nil
on_answer = nil
@ -184,13 +197,13 @@ RSpec.describe 'Integration Sipgate', type: :request do
end
expect(caller_id).to eq('41715880339000')
expect(number_to_dail).to eq('4147110000000')
expect(on_hangup).to eq('http://zammad.example.com/api/v1/sipgate/out')
expect(on_answer).to eq('http://zammad.example.com/api/v1/sipgate/out')
expect(on_hangup).to eq("http://zammad.example.com/api/v1/sipgate/#{token}/out")
expect(on_answer).to eq("http://zammad.example.com/api/v1/sipgate/#{token}/out")
# no config
Setting.set('sipgate_config', {})
params = 'event=newCall&direction=in&from=4912347114711&to=4930600000000&callId=4991155921769858278-6&user%5B%5D=user+1&user%5B%5D=user+2'
post '/api/v1/sipgate/in', params: params
post "/api/v1/sipgate/#{token}/in", params: params
expect(@response).to have_http_status(:unprocessable_entity)
error = nil
content = @response.body
@ -203,10 +216,11 @@ RSpec.describe 'Integration Sipgate', type: :request do
end
it 'does log call' do
token = Setting.get('sipgate_token')
# outbound - I - new call
params = 'event=newCall&direction=out&from=4930600000000&to=4912347114711&callId=1234567890-1&user%5B%5D=user+1'
post '/api/v1/sipgate/out', params: params
post "/api/v1/sipgate/#{token}/out", params: params
expect(@response).to have_http_status(:ok)
log = Cti::Log.find_by(call_id: '1234567890-1')
expect(log).to be_truthy
@ -223,7 +237,7 @@ RSpec.describe 'Integration Sipgate', type: :request do
# outbound - I - hangup by agent
params = 'event=hangup&direction=out&callId=1234567890-1&cause=cancel'
post '/api/v1/sipgate/out', params: params
post "/api/v1/sipgate/#{token}/out", params: params
expect(@response).to have_http_status(:ok)
log = Cti::Log.find_by(call_id: '1234567890-1')
expect(log).to be_truthy
@ -240,7 +254,7 @@ RSpec.describe 'Integration Sipgate', type: :request do
# outbound - II - new call
params = 'event=newCall&direction=out&from=4930600000000&to=4912347114711&callId=1234567890-2&user%5B%5D=user+1'
post '/api/v1/sipgate/out', params: params
post "/api/v1/sipgate/#{token}/out", params: params
expect(@response).to have_http_status(:ok)
log = Cti::Log.find_by(call_id: '1234567890-2')
expect(log).to be_truthy
@ -257,7 +271,7 @@ RSpec.describe 'Integration Sipgate', type: :request do
# outbound - II - answer by customer
params = 'event=answer&direction=out&callId=1234567890-2&from=4930600000000&to=4912347114711'
post '/api/v1/sipgate/out', params: params
post "/api/v1/sipgate/#{token}/out", params: params
expect(@response).to have_http_status(:ok)
log = Cti::Log.find_by(call_id: '1234567890-2')
expect(log).to be_truthy
@ -274,7 +288,7 @@ RSpec.describe 'Integration Sipgate', type: :request do
# outbound - II - hangup by customer
params = 'event=hangup&direction=out&callId=1234567890-2&cause=normalClearing&from=4930600000000&to=4912347114711'
post '/api/v1/sipgate/out', params: params
post "/api/v1/sipgate/#{token}/out", params: params
expect(@response).to have_http_status(:ok)
log = Cti::Log.find_by(call_id: '1234567890-2')
expect(log).to be_truthy
@ -291,7 +305,7 @@ RSpec.describe 'Integration Sipgate', type: :request do
# inbound - I - new call
params = 'event=newCall&direction=in&to=4930600000000&from=4912347114711&callId=1234567890-3&user%5B%5D=user+1'
post '/api/v1/sipgate/in', params: params
post "/api/v1/sipgate/#{token}/in", params: params
expect(@response).to have_http_status(:ok)
log = Cti::Log.find_by(call_id: '1234567890-3')
expect(log).to be_truthy
@ -308,7 +322,7 @@ RSpec.describe 'Integration Sipgate', type: :request do
# inbound - I - answer by customer
params = 'event=answer&direction=in&callId=1234567890-3&to=4930600000000&from=4912347114711'
post '/api/v1/sipgate/in', params: params
post "/api/v1/sipgate/#{token}/in", params: params
expect(@response).to have_http_status(:ok)
log = Cti::Log.find_by(call_id: '1234567890-3')
expect(log).to be_truthy
@ -325,7 +339,7 @@ RSpec.describe 'Integration Sipgate', type: :request do
# inbound - I - hangup by customer
params = 'event=hangup&direction=in&callId=1234567890-3&cause=normalClearing&to=4930600000000&from=4912347114711'
post '/api/v1/sipgate/in', params: params
post "/api/v1/sipgate/#{token}/in", params: params
expect(@response).to have_http_status(:ok)
log = Cti::Log.find_by(call_id: '1234567890-3')
expect(log).to be_truthy
@ -342,7 +356,7 @@ RSpec.describe 'Integration Sipgate', type: :request do
# inbound - II - new call
params = 'event=newCall&direction=in&to=4930600000000&from=4912347114711&callId=1234567890-4&user%5B%5D=user+1,user+2'
post '/api/v1/sipgate/in', params: params
post "/api/v1/sipgate/#{token}/in", params: params
expect(@response).to have_http_status(:ok)
log = Cti::Log.find_by(call_id: '1234567890-4')
expect(log).to be_truthy
@ -359,7 +373,7 @@ RSpec.describe 'Integration Sipgate', type: :request do
# inbound - II - answer by voicemail
params = 'event=answer&direction=in&callId=1234567890-4&to=4930600000000&from=4912347114711&user=voicemail'
post '/api/v1/sipgate/in', params: params
post "/api/v1/sipgate/#{token}/in", params: params
expect(@response).to have_http_status(:ok)
log = Cti::Log.find_by(call_id: '1234567890-4')
expect(log).to be_truthy
@ -376,7 +390,7 @@ RSpec.describe 'Integration Sipgate', type: :request do
# inbound - II - hangup by customer
params = 'event=hangup&direction=in&callId=1234567890-4&cause=normalClearing&to=4930600000000&from=4912347114711'
post '/api/v1/sipgate/in', params: params
post "/api/v1/sipgate/#{token}/in", params: params
expect(@response).to have_http_status(:ok)
log = Cti::Log.find_by(call_id: '1234567890-4')
expect(log).to be_truthy
@ -393,7 +407,7 @@ RSpec.describe 'Integration Sipgate', type: :request do
# inbound - III - new call
params = 'event=newCall&direction=in&to=4930600000000&from=4912347114711&callId=1234567890-5&user%5B%5D=user+1,user+2'
post '/api/v1/sipgate/in', params: params
post "/api/v1/sipgate/#{token}/in", params: params
expect(@response).to have_http_status(:ok)
log = Cti::Log.find_by(call_id: '1234567890-5')
expect(log).to be_truthy
@ -410,7 +424,7 @@ RSpec.describe 'Integration Sipgate', type: :request do
# inbound - III - hangup by customer
params = 'event=hangup&direction=in&callId=1234567890-5&cause=normalClearing&to=4930600000000&from=4912347114711'
post '/api/v1/sipgate/in', params: params
post "/api/v1/sipgate/#{token}/in", params: params
expect(@response).to have_http_status(:ok)
log = Cti::Log.find_by(call_id: '1234567890-5')
expect(log).to be_truthy
@ -427,7 +441,7 @@ RSpec.describe 'Integration Sipgate', type: :request do
# inbound - IV - new call
params = 'event=newCall&direction=in&to=4930600000000&from=49999992222222&callId=1234567890-6&user%5B%5D=user+1,user+2'
post '/api/v1/sipgate/in', params: params
post "/api/v1/sipgate/#{token}/in", params: params
expect(@response).to have_http_status(:ok)
log = Cti::Log.find_by(call_id: '1234567890-6')
expect(log).to be_truthy
@ -471,11 +485,13 @@ RSpec.describe 'Integration Sipgate', type: :request do
end
it 'alternative fqdn' do
token = Setting.get('sipgate_token')
Setting.set('sipgate_alternative_fqdn', 'external.host.example.com')
# inbound - I
params = 'event=newCall&direction=in&from=4912347114711&to=4930600000000&callId=4991155921769858278-1&user%5B%5D=user+1&user%5B%5D=user+2'
post '/api/v1/sipgate/in', params: params
post "/api/v1/sipgate/#{token}/in", params: params
expect(@response).to have_http_status(:ok)
on_hangup = nil
on_answer = nil
@ -485,8 +501,8 @@ RSpec.describe 'Integration Sipgate', type: :request do
on_hangup = element.attributes['onHangup']
on_answer = element.attributes['onAnswer']
end
expect(on_hangup).to eq('http://external.host.example.com/api/v1/sipgate/in')
expect(on_answer).to eq('http://external.host.example.com/api/v1/sipgate/in')
expect(on_hangup).to eq("http://external.host.example.com/api/v1/sipgate/#{token}/in")
expect(on_answer).to eq("http://external.host.example.com/api/v1/sipgate/#{token}/in")
end
end
end

View file

@ -23,8 +23,10 @@ RSpec.describe 'Caller log', type: :system, authenticated_as: :authenticate do
let(:second_params) { params.merge(event: 'hangup') }
let(:place_call) do
post "#{Capybara.app_host}/api/v1/sipgate/in", params: first_params
post "#{Capybara.app_host}/api/v1/sipgate/in", params: second_params
token = Setting.get('sipgate_token')
post "#{Capybara.app_host}/api/v1/sipgate/#{token}/in", params: first_params
post "#{Capybara.app_host}/api/v1/sipgate/#{token}/in", params: second_params
end
def authenticate