Implemented issue #439 - proxy support.
This commit is contained in:
parent
e406c4bcee
commit
a1a56f49c0
12 changed files with 377 additions and 2 deletions
|
@ -196,7 +196,18 @@ test:integration:user_agent:
|
|||
- rake db:migrate
|
||||
- ruby -I test/ test/integration/user_agent_test.rb
|
||||
- rake db:drop
|
||||
allow_failure: true
|
||||
|
||||
test:integration:user_agent_proxy:
|
||||
stage: test
|
||||
tags:
|
||||
- core
|
||||
script:
|
||||
- export ZAMMAD_PROXY_TEST=true
|
||||
- export RAILS_ENV=test
|
||||
- rake db:create
|
||||
- rake db:migrate
|
||||
- ruby -I test/ test/integration/user_agent_test.rb
|
||||
- rake db:drop
|
||||
|
||||
test:integration:user_device:
|
||||
stage: test
|
||||
|
|
|
@ -11,6 +11,8 @@ class System extends App.ControllerTabs
|
|||
@tabs.push { name: 'Services', 'target': 'services', controller: App.SettingsArea, params: { area: 'System::Services' } }
|
||||
if !App.Config.get('system_online_service')
|
||||
@tabs.push { name: 'Storage', 'target': 'storage', controller: App.SettingsArea, params: { area: 'System::Storage' } }
|
||||
if !App.Config.get('system_online_service')
|
||||
@tabs.push { name: 'Network', 'target': 'network', controller: App.SettingsArea, params: { area: 'System::Network' } }
|
||||
@tabs.push { name: 'Frontend', 'target': 'ui', controller: App.SettingsArea, params: { area: 'System::UI' } }
|
||||
@render()
|
||||
|
||||
|
|
|
@ -27,6 +27,12 @@ class App.SettingsArea extends App.Controller
|
|||
)
|
||||
return if _.isEmpty(settings)
|
||||
|
||||
# filter disabled settings
|
||||
settings = _.filter(settings, (setting) ->
|
||||
return if setting.preferences && setting.preferences.disabled
|
||||
setting
|
||||
)
|
||||
|
||||
# sort by prio
|
||||
settings = _.sortBy( settings, (setting) ->
|
||||
return if !setting.preferences
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
class App.SettingsAreaProxy extends App.Controller
|
||||
events:
|
||||
'submit form': 'update'
|
||||
'click .js-submit': 'update'
|
||||
'click .js-test': 'test2'
|
||||
|
||||
constructor: ->
|
||||
super
|
||||
@render()
|
||||
|
||||
render: =>
|
||||
@html App.view('settings/proxy')(
|
||||
setting: App.Setting.findByAttribute('name', 'proxy')
|
||||
proxy: App.Setting.get('proxy')
|
||||
proxy_username: App.Setting.get('proxy_username')
|
||||
proxy_password: App.Setting.get('proxy_password')
|
||||
)
|
||||
|
||||
update: (e) =>
|
||||
e.preventDefault()
|
||||
@formDisable(e)
|
||||
params = @formParam(e)
|
||||
console.log('params', params)
|
||||
App.Setting.set('proxy', params.proxy)
|
||||
App.Setting.set('proxy_username', params.proxy_username)
|
||||
App.Setting.set('proxy_password', params.proxy_password)
|
||||
@formEnable(e)
|
||||
@render()
|
||||
|
||||
test2: (e) =>
|
||||
e.preventDefault()
|
||||
params = @formParam(e)
|
||||
@ajax(
|
||||
id: 'proxy_test'
|
||||
type: 'POST'
|
||||
url: "#{@apiPath}/proxy"
|
||||
data: JSON.stringify(params)
|
||||
processData: true
|
||||
success: (data, status, xhr) =>
|
||||
if data.result is 'success'
|
||||
@$('.js-test').addClass('hide')
|
||||
@$('.js-submit').removeClass('hide')
|
||||
App.Event.trigger 'notify', {
|
||||
type: 'success'
|
||||
msg: App.i18n.translateContent('Connection test successful')
|
||||
timeout: 2000
|
||||
}
|
||||
return
|
||||
new App.ControllerConfirm(
|
||||
head: 'Error'
|
||||
message: data.message
|
||||
buttonClass: 'btn--success'
|
||||
buttonCancel: false
|
||||
buttonSubmit: 'Close'
|
||||
container: @el.closest('.content')
|
||||
)
|
||||
)
|
||||
|
|
@ -30,6 +30,12 @@ class App.SettingsForm extends App.Controller
|
|||
)
|
||||
return if _.isEmpty(settings)
|
||||
|
||||
# filter disabled settings
|
||||
settings = _.filter(settings, (setting) ->
|
||||
return if setting.preferences && setting.preferences.disabled
|
||||
setting
|
||||
)
|
||||
|
||||
# sort by prio
|
||||
settings = _.sortBy( settings, (setting) ->
|
||||
return if !setting.preferences
|
||||
|
|
25
app/assets/javascripts/app/views/settings/proxy.jst.eco
Normal file
25
app/assets/javascripts/app/views/settings/proxy.jst.eco
Normal file
|
@ -0,0 +1,25 @@
|
|||
<form class="settings-entry" id="<%= @setting.name %>">
|
||||
<h2><%- @T(@setting.title) %></h2>
|
||||
<p class="help-text"><%- @T('Proxy address.') %></p>
|
||||
<div class="horizontal end">
|
||||
<div class="form-item flex">
|
||||
<input type="text" name="proxy" value="<%= @proxy %>" placeholder="proxy.example.com:3128" class="form-control">
|
||||
</div>
|
||||
</div>
|
||||
<p class="help-text"><%- @T('Username for proxy connection.') %></p>
|
||||
<div class="horizontal end">
|
||||
<div class="form-item flex">
|
||||
<input type="text" name="proxy_username" value="<%= @proxy_username %>" class="form-control">
|
||||
</div>
|
||||
</div>
|
||||
<p class="help-text"><%- @T('Password for proxy connection.') %></p>
|
||||
<div class="horizontal end">
|
||||
<div class="form-item flex">
|
||||
<input type="text" name="proxy_password" value="<%= @proxy_password %>" class="form-control">
|
||||
</div>
|
||||
</div>
|
||||
<div class="horizontal justify-end form-controls">
|
||||
<button class="btn btn js-test"><%- @T('Test Connection') %></button>
|
||||
<button class="btn btn--primary js-submit hide"><%- @T('Submit') %></button>
|
||||
<div>
|
||||
</form>
|
37
app/controllers/proxy_controller.rb
Normal file
37
app/controllers/proxy_controller.rb
Normal file
|
@ -0,0 +1,37 @@
|
|||
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
|
||||
|
||||
class ProxyController < ApplicationController
|
||||
before_action { authentication_check(permission: 'admin.system') }
|
||||
|
||||
# POST /api/v1/proxy
|
||||
def test
|
||||
url = 'http://zammad.org'
|
||||
options = params
|
||||
options[:open_timeout] = 12
|
||||
options[:read_timeout] = 24
|
||||
begin
|
||||
result = UserAgent.get(
|
||||
url,
|
||||
{},
|
||||
options,
|
||||
)
|
||||
rescue => e
|
||||
render json: {
|
||||
result: 'failed',
|
||||
message: e.inspect
|
||||
}
|
||||
return
|
||||
end
|
||||
if result.success?
|
||||
render json: {
|
||||
result: 'success'
|
||||
}
|
||||
return
|
||||
end
|
||||
render json: {
|
||||
result: 'failed',
|
||||
message: result.body || result.error || result.code
|
||||
}
|
||||
end
|
||||
|
||||
end
|
6
config/routes/proxy.rb
Normal file
6
config/routes/proxy.rb
Normal file
|
@ -0,0 +1,6 @@
|
|||
Zammad::Application.routes.draw do
|
||||
api_path = Rails.configuration.api_path
|
||||
|
||||
match api_path + '/proxy', to: 'proxy#test', via: :post
|
||||
|
||||
end
|
82
db/migrate/20170115000001_add_proxy_settings_439.rb
Normal file
82
db/migrate/20170115000001_add_proxy_settings_439.rb
Normal file
|
@ -0,0 +1,82 @@
|
|||
class AddProxySettings439 < ActiveRecord::Migration
|
||||
def up
|
||||
|
||||
# return if it's a new setup
|
||||
return if !Setting.find_by(name: 'system_init_done')
|
||||
|
||||
Setting.create_if_not_exists(
|
||||
title: 'Proxy Settings',
|
||||
name: 'proxy',
|
||||
area: 'System::Network',
|
||||
description: 'Address of the proxy server for http and https resources.',
|
||||
options: {
|
||||
form: [
|
||||
{
|
||||
display: '',
|
||||
null: false,
|
||||
name: 'proxy',
|
||||
tag: 'input',
|
||||
placeholder: 'proxy.example.com:3128',
|
||||
},
|
||||
],
|
||||
},
|
||||
state: '',
|
||||
preferences: {
|
||||
online_service_disable: true,
|
||||
controller: 'SettingsAreaProxy',
|
||||
prio: 1,
|
||||
permission: ['admin.system'],
|
||||
},
|
||||
frontend: false
|
||||
)
|
||||
Setting.create_if_not_exists(
|
||||
title: 'Proxy User',
|
||||
name: 'proxy_username',
|
||||
area: 'System::Network',
|
||||
description: 'Username for proxy connection.',
|
||||
options: {
|
||||
form: [
|
||||
{
|
||||
display: '',
|
||||
null: false,
|
||||
name: 'proxy_username',
|
||||
tag: 'input',
|
||||
},
|
||||
],
|
||||
},
|
||||
state: '',
|
||||
preferences: {
|
||||
disabled: true,
|
||||
online_service_disable: true,
|
||||
prio: 2,
|
||||
permission: ['admin.system'],
|
||||
},
|
||||
frontend: false
|
||||
)
|
||||
Setting.create_if_not_exists(
|
||||
title: 'Proxy Password',
|
||||
name: 'proxy_password',
|
||||
area: 'System::Network',
|
||||
description: 'Password for proxy connection.',
|
||||
options: {
|
||||
form: [
|
||||
{
|
||||
display: '',
|
||||
null: false,
|
||||
name: 'proxy_passowrd',
|
||||
tag: 'input',
|
||||
},
|
||||
],
|
||||
},
|
||||
state: '',
|
||||
preferences: {
|
||||
disabled: true,
|
||||
online_service_disable: true,
|
||||
prio: 3,
|
||||
permission: ['admin.system'],
|
||||
},
|
||||
frontend: false
|
||||
)
|
||||
|
||||
end
|
||||
end
|
74
db/seeds.rb
74
db/seeds.rb
|
@ -394,6 +394,80 @@ Setting.create_if_not_exists(
|
|||
frontend: false
|
||||
)
|
||||
|
||||
Setting.create_if_not_exists(
|
||||
title: 'Proxy Settings',
|
||||
name: 'proxy',
|
||||
area: 'System::Network',
|
||||
description: 'Address of the proxy server for http and https resources.',
|
||||
options: {
|
||||
form: [
|
||||
{
|
||||
display: '',
|
||||
null: false,
|
||||
name: 'proxy',
|
||||
tag: 'input',
|
||||
placeholder: 'proxy.example.com:3128',
|
||||
},
|
||||
],
|
||||
},
|
||||
state: '',
|
||||
preferences: {
|
||||
online_service_disable: true,
|
||||
controller: 'SettingsAreaProxy',
|
||||
prio: 1,
|
||||
permission: ['admin.system'],
|
||||
},
|
||||
frontend: false
|
||||
)
|
||||
Setting.create_if_not_exists(
|
||||
title: 'Proxy User',
|
||||
name: 'proxy_username',
|
||||
area: 'System::Network',
|
||||
description: 'Username for proxy connection.',
|
||||
options: {
|
||||
form: [
|
||||
{
|
||||
display: '',
|
||||
null: false,
|
||||
name: 'proxy_username',
|
||||
tag: 'input',
|
||||
},
|
||||
],
|
||||
},
|
||||
state: '',
|
||||
preferences: {
|
||||
disabled: true,
|
||||
online_service_disable: true,
|
||||
prio: 2,
|
||||
permission: ['admin.system'],
|
||||
},
|
||||
frontend: false
|
||||
)
|
||||
Setting.create_if_not_exists(
|
||||
title: 'Proxy Password',
|
||||
name: 'proxy_password',
|
||||
area: 'System::Network',
|
||||
description: 'Password for proxy connection.',
|
||||
options: {
|
||||
form: [
|
||||
{
|
||||
display: '',
|
||||
null: false,
|
||||
name: 'proxy_passowrd',
|
||||
tag: 'input',
|
||||
},
|
||||
],
|
||||
},
|
||||
state: '',
|
||||
preferences: {
|
||||
disabled: true,
|
||||
online_service_disable: true,
|
||||
prio: 3,
|
||||
permission: ['admin.system'],
|
||||
},
|
||||
frontend: false
|
||||
)
|
||||
|
||||
Setting.create_if_not_exists(
|
||||
title: 'Send client stats',
|
||||
name: 'ui_send_client_stats',
|
||||
|
|
|
@ -262,7 +262,29 @@ returns
|
|||
end
|
||||
|
||||
def self.get_http(uri, options)
|
||||
|
||||
proxy = options['proxy'] || Setting.get('proxy')
|
||||
if proxy.present?
|
||||
if proxy =~ /^(.+?):(.+?)$/
|
||||
proxy_host = $1
|
||||
proxy_port = $2
|
||||
else
|
||||
raise "Invalid proxy address: #{proxy} - expect e.g. proxy.example.com:3128"
|
||||
end
|
||||
|
||||
proxy_username = options['proxy_username'] || Setting.get('proxy_username')
|
||||
if proxy_username.blank?
|
||||
proxy_username = nil
|
||||
end
|
||||
proxy_password = options['proxy_password'] || Setting.get('proxy_password')
|
||||
if proxy_password.blank?
|
||||
proxy_password = nil
|
||||
end
|
||||
|
||||
http = Net::HTTP::Proxy(proxy_host, proxy_port, proxy_username, proxy_password).new(uri.host, uri.port)
|
||||
else
|
||||
http = Net::HTTP.new(uri.host, uri.port)
|
||||
end
|
||||
|
||||
http.open_timeout = options[:open_timeout] || 4
|
||||
http.read_timeout = options[:read_timeout] || 10
|
||||
|
|
|
@ -5,6 +5,13 @@ class UserAgentTest < ActiveSupport::TestCase
|
|||
host = 'https://r2d2.znuny.com'
|
||||
#host = 'http://127.0.0.1:3003'
|
||||
|
||||
setup do
|
||||
return if ENV['ZAMMAD_PROXY_TEST'] != 'true'
|
||||
Setting.set('proxy', ENV['ZAMMAD_PROXY'])
|
||||
Setting.set('proxy_username', ENV['ZAMMAD_PROXY_USERNAME'])
|
||||
Setting.set('proxy_password', ENV['ZAMMAD_PROXY_PASSWORD'])
|
||||
end
|
||||
|
||||
# check
|
||||
test 'check some results' do
|
||||
|
||||
|
@ -19,6 +26,9 @@ class UserAgentTest < ActiveSupport::TestCase
|
|||
assert(result.body =~ /"get"/)
|
||||
assert(result.body =~ /"123"/)
|
||||
assert(result.body =~ /"content_type_requested":null/)
|
||||
if ENV['ZAMMAD_PROXY_TEST'] == 'true' && ENV['ZAMMAD_PROXY_REMOTE_IP_CHECK']
|
||||
assert(result.body =~ /"remote_ip":"#{ENV['ZAMMAD_PROXY_REMOTE_IP_CHECK']}"/)
|
||||
end
|
||||
|
||||
# get / 404
|
||||
result = UserAgent.get(
|
||||
|
@ -43,6 +53,9 @@ class UserAgentTest < ActiveSupport::TestCase
|
|||
assert(result.body =~ /"post"/)
|
||||
assert(result.body =~ /"some value"/)
|
||||
assert(result.body =~ %r{"application/x-www-form-urlencoded"})
|
||||
if ENV['ZAMMAD_PROXY_TEST'] == 'true' && ENV['ZAMMAD_PROXY_REMOTE_IP_CHECK']
|
||||
assert(result.body =~ /"remote_ip":"#{ENV['ZAMMAD_PROXY_REMOTE_IP_CHECK']}"/)
|
||||
end
|
||||
|
||||
# post / 404
|
||||
result = UserAgent.post(
|
||||
|
@ -70,6 +83,9 @@ class UserAgentTest < ActiveSupport::TestCase
|
|||
assert(result.body =~ /"put"/)
|
||||
assert(result.body =~ /"some value"/)
|
||||
assert(result.body =~ %r{"application/x-www-form-urlencoded"})
|
||||
if ENV['ZAMMAD_PROXY_TEST'] == 'true' && ENV['ZAMMAD_PROXY_REMOTE_IP_CHECK']
|
||||
assert(result.body =~ /"remote_ip":"#{ENV['ZAMMAD_PROXY_REMOTE_IP_CHECK']}"/)
|
||||
end
|
||||
|
||||
# put / 404
|
||||
result = UserAgent.put(
|
||||
|
@ -93,6 +109,9 @@ class UserAgentTest < ActiveSupport::TestCase
|
|||
assert_equal(String, result.body.class)
|
||||
assert(result.body =~ /"delete"/)
|
||||
assert(result.body =~ /"content_type_requested":null/)
|
||||
if ENV['ZAMMAD_PROXY_TEST'] == 'true' && ENV['ZAMMAD_PROXY_REMOTE_IP_CHECK']
|
||||
assert(result.body =~ /"remote_ip":"#{ENV['ZAMMAD_PROXY_REMOTE_IP_CHECK']}"/)
|
||||
end
|
||||
|
||||
# delete / 404
|
||||
result = UserAgent.delete(
|
||||
|
@ -121,6 +140,9 @@ class UserAgentTest < ActiveSupport::TestCase
|
|||
assert(result.body =~ /"get"/)
|
||||
assert(result.body =~ /"123"/)
|
||||
assert(result.body =~ /"content_type_requested":null/)
|
||||
if ENV['ZAMMAD_PROXY_TEST'] == 'true' && ENV['ZAMMAD_PROXY_REMOTE_IP_CHECK']
|
||||
assert(result.body =~ /"remote_ip":"#{ENV['ZAMMAD_PROXY_REMOTE_IP_CHECK']}"/)
|
||||
end
|
||||
|
||||
# get / 401
|
||||
result = UserAgent.get(
|
||||
|
@ -154,6 +176,9 @@ class UserAgentTest < ActiveSupport::TestCase
|
|||
assert(result.body =~ /"post"/)
|
||||
assert(result.body =~ /"some value"/)
|
||||
assert(result.body =~ %r{"application/x-www-form-urlencoded"})
|
||||
if ENV['ZAMMAD_PROXY_TEST'] == 'true' && ENV['ZAMMAD_PROXY_REMOTE_IP_CHECK']
|
||||
assert(result.body =~ /"remote_ip":"#{ENV['ZAMMAD_PROXY_REMOTE_IP_CHECK']}"/)
|
||||
end
|
||||
|
||||
# post / 401
|
||||
result = UserAgent.post(
|
||||
|
@ -189,6 +214,9 @@ class UserAgentTest < ActiveSupport::TestCase
|
|||
assert(result.body =~ /"put"/)
|
||||
assert(result.body =~ /"some value"/)
|
||||
assert(result.body =~ %r{"application/x-www-form-urlencoded"})
|
||||
if ENV['ZAMMAD_PROXY_TEST'] == 'true' && ENV['ZAMMAD_PROXY_REMOTE_IP_CHECK']
|
||||
assert(result.body =~ /"remote_ip":"#{ENV['ZAMMAD_PROXY_REMOTE_IP_CHECK']}"/)
|
||||
end
|
||||
|
||||
# put / 401
|
||||
result = UserAgent.put(
|
||||
|
@ -220,6 +248,9 @@ class UserAgentTest < ActiveSupport::TestCase
|
|||
assert_equal(String, result.body.class)
|
||||
assert(result.body =~ /"delete"/)
|
||||
assert(result.body =~ /"content_type_requested":null/)
|
||||
if ENV['ZAMMAD_PROXY_TEST'] == 'true' && ENV['ZAMMAD_PROXY_REMOTE_IP_CHECK']
|
||||
assert(result.body =~ /"remote_ip":"#{ENV['ZAMMAD_PROXY_REMOTE_IP_CHECK']}"/)
|
||||
end
|
||||
|
||||
# delete / 401
|
||||
result = UserAgent.delete(
|
||||
|
@ -249,6 +280,9 @@ class UserAgentTest < ActiveSupport::TestCase
|
|||
assert(result.body =~ /"get"/)
|
||||
assert(result.body =~ /"abc"/)
|
||||
assert(result.body =~ /"content_type_requested":null/)
|
||||
if ENV['ZAMMAD_PROXY_TEST'] == 'true' && ENV['ZAMMAD_PROXY_REMOTE_IP_CHECK']
|
||||
assert(result.body =~ /"remote_ip":"#{ENV['ZAMMAD_PROXY_REMOTE_IP_CHECK']}"/)
|
||||
end
|
||||
|
||||
# get / 301
|
||||
result = UserAgent.request(
|
||||
|
@ -265,6 +299,9 @@ class UserAgentTest < ActiveSupport::TestCase
|
|||
assert(result.body =~ /"get"/)
|
||||
assert(result.body =~ /"abc"/)
|
||||
assert(result.body =~ /"content_type_requested":null/)
|
||||
if ENV['ZAMMAD_PROXY_TEST'] == 'true' && ENV['ZAMMAD_PROXY_REMOTE_IP_CHECK']
|
||||
assert(result.body =~ /"remote_ip":"#{ENV['ZAMMAD_PROXY_REMOTE_IP_CHECK']}"/)
|
||||
end
|
||||
|
||||
# get / 401
|
||||
result = UserAgent.request(
|
||||
|
@ -294,6 +331,9 @@ class UserAgentTest < ActiveSupport::TestCase
|
|||
assert(result.body =~ /"get"/)
|
||||
assert(result.body =~ /"123"/)
|
||||
assert(result.body =~ /"content_type_requested":null/)
|
||||
if ENV['ZAMMAD_PROXY_TEST'] == 'true' && ENV['ZAMMAD_PROXY_REMOTE_IP_CHECK']
|
||||
assert(result.body =~ /"remote_ip":"#{ENV['ZAMMAD_PROXY_REMOTE_IP_CHECK']}"/)
|
||||
end
|
||||
|
||||
# ftp / 200
|
||||
result = UserAgent.request(
|
||||
|
@ -434,6 +474,9 @@ class UserAgentTest < ActiveSupport::TestCase
|
|||
assert(result.body =~ /"content_type_requested"/)
|
||||
assert(result.body =~ %r{"application/json"})
|
||||
assert_equal('some value ', result.data['submitted']['key'])
|
||||
if ENV['ZAMMAD_PROXY_TEST'] == 'true' && ENV['ZAMMAD_PROXY_REMOTE_IP_CHECK']
|
||||
assert(result.body =~ /"remote_ip":"#{ENV['ZAMMAD_PROXY_REMOTE_IP_CHECK']}"/)
|
||||
end
|
||||
|
||||
# get / 401
|
||||
result = UserAgent.get(
|
||||
|
@ -468,6 +511,9 @@ class UserAgentTest < ActiveSupport::TestCase
|
|||
assert(result.body =~ /"content_type_requested"/)
|
||||
assert(result.body =~ %r{"application/json"})
|
||||
assert_equal('some value ', result.data['submitted']['key'])
|
||||
if ENV['ZAMMAD_PROXY_TEST'] == 'true' && ENV['ZAMMAD_PROXY_REMOTE_IP_CHECK']
|
||||
assert(result.body =~ /"remote_ip":"#{ENV['ZAMMAD_PROXY_REMOTE_IP_CHECK']}"/)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue