diff --git a/app/assets/javascripts/app/controllers/_integration/sipgate_io.coffee b/app/assets/javascripts/app/controllers/_integration/sipgate_io.coffee
index 5bb08853e..ba41f6935 100644
--- a/app/assets/javascripts/app/controllers/_integration/sipgate_io.coffee
+++ b/app/assets/javascripts/app/controllers/_integration/sipgate_io.coffee
@@ -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 = [
diff --git a/app/assets/javascripts/app/views/integration/sipgate.jst.eco b/app/assets/javascripts/app/views/integration/sipgate.jst.eco
index 5a194891b..4b69d2621 100644
--- a/app/assets/javascripts/app/views/integration/sipgate.jst.eco
+++ b/app/assets/javascripts/app/views/integration/sipgate.jst.eco
@@ -14,10 +14,10 @@
<%- @T('Inbound') %>
- |
+ |
|
<%- @T('Outbound') %>
- |
+ |
|
diff --git a/app/controllers/integration/sipgate_controller.rb b/app/controllers/integration/sipgate_controller.rb
index 87144bd04..2d726c90a 100644
--- a/app/controllers/integration/sipgate_controller.rb
+++ b/app/controllers/integration/sipgate_controller.rb
@@ -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!
diff --git a/config/routes/integration_sipgate.rb b/config/routes/integration_sipgate.rb
index d94ab5326..780671aec 100644
--- a/config/routes/integration_sipgate.rb
+++ b/config/routes/integration_sipgate.rb
@@ -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
diff --git a/db/migrate/20211118081558_maintenance_improve_sipgate_integration_handling.rb b/db/migrate/20211118081558_maintenance_improve_sipgate_integration_handling.rb
new file mode 100644
index 000000000..4517fb9e7
--- /dev/null
+++ b/db/migrate/20211118081558_maintenance_improve_sipgate_integration_handling.rb
@@ -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
diff --git a/db/seeds/settings.rb b/db/seeds/settings.rb
index b5e5f65c7..63c673c03 100644
--- a/db/seeds/settings.rb
+++ b/db/seeds/settings.rb
@@ -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',
diff --git a/i18n/zammad.pot b/i18n/zammad.pot
index 7ccd63ca6..9b10c3e53 100644
--- a/i18n/zammad.pot
+++ b/i18n/zammad.pot
@@ -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 ""
diff --git a/spec/requests/integration/sipgate_spec.rb b/spec/requests/integration/sipgate_spec.rb
index a7ed69193..bf4ad211a 100644
--- a/spec/requests/integration/sipgate_spec.rb
+++ b/spec/requests/integration/sipgate_spec.rb
@@ -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
diff --git a/spec/system/sipgate_spec.rb b/spec/system/sipgate_spec.rb
index cb2c307a5..d2c314efe 100644
--- a/spec/system/sipgate_spec.rb
+++ b/spec/system/sipgate_spec.rb
@@ -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