Browse Source

Allow setting multiple STUN servers

Signed-off-by: Joas Schilling <coding@schilljs.com>
pull/427/head
Joas Schilling 8 years ago
parent
commit
2a33f7fd1a
No known key found for this signature in database GPG Key ID: E166FD8976B3BAC8
  1. 7
      appinfo/info.xml
  2. 8
      css/settings-admin.css
  3. 19
      css/settings-admin.scss
  4. 100
      js/admin/stun-server.js
  5. 13
      js/settings-admin.js
  6. 11
      js/settings-personal.js
  7. 13
      lib/Config.php
  8. 40
      lib/Controller/AppSettingsController.php
  9. 4
      lib/Settings/Admin/Section.php
  10. 70
      lib/Settings/Admin/StunServer.php
  11. 7
      lib/Settings/Admin/TurnServer.php
  12. 56
      templates/settings-admin.php
  13. 14
      templates/settings/admin/stun-server.php
  14. 40
      templates/settings/admin/turn-server.php

7
appinfo/info.xml

@ -42,7 +42,7 @@ And in the works for the [coming versions](https://github.com/nextcloud/spreed/m
<bugs>https://github.com/nextcloud/spreed/issues</bugs>
<repository type="git">https://github.com/nextcloud/spreed.git</repository>
<version>2.1.5</version>
<version>2.1.6</version>
<dependencies>
<nextcloud min-version="13" max-version="13" />
@ -61,8 +61,9 @@ And in the works for the [coming versions](https://github.com/nextcloud/spreed/m
</navigations>
<settings>
<admin>OCA\Spreed\Settings\Admin</admin>
<admin-section>OCA\Spreed\Settings\AdminSection</admin-section>
<admin>OCA\Spreed\Settings\Admin\TurnServer</admin>
<admin>OCA\Spreed\Settings\Admin\StunServer</admin>
<admin-section>OCA\Spreed\Settings\Admin\Section</admin-section>
</settings>
<activity>

8
css/settings-admin.css

@ -1,8 +0,0 @@
#spreed_settings_form label {
min-width: 200px;
display: inline-block;
}
#spreed_settings_form input {
width: 300px;
}

19
css/settings-admin.scss

@ -0,0 +1,19 @@
.videocalls.section {
input {
width: 300px;
}
.icon-delete,
div.stun-server:last-child .icon-add {
display: inline-block;
}
.error {
border-color: $color-error;
}
label {
min-width: 200px;
display: inline-block;
}
}

100
js/admin/stun-server.js

@ -0,0 +1,100 @@
/* global OC, OCP, OCA, $, _ */
(function(OC, OCP, OCA, $, _) {
'use strict';
OCA.VideoCalls = OCA.VideoCalls || {};
OCA.VideoCalls.Admin = OCA.VideoCalls.Admin || {};
OCA.VideoCalls.Admin.StunServer = {
TEMPLATE: '<div class="stun-server">' +
' <input type="text" name="stun_server" placeholder="stunserver:port" value="{{server}}" />' +
' <a class="icon icon-delete" title="' + t('spreed', 'Delete server') + '"></a>' +
' <a class="icon icon-add" title="' + t('spreed', 'Add new server') + '"></a>' +
'</div>',
$list: undefined,
template: undefined,
init: function() {
this.template = Handlebars.compile(this.TEMPLATE);
this.$list = $('div.stun-servers');
this.renderList();
},
renderList: function() {
var servers = this.$list.data('servers');
_.each(servers, function(server) {
this.$list.append(
this.renderServer(server)
);
}.bind(this));
if (servers.length === 0) {
this.addNewTemplate('stun.nextcloud.com:443');
}
},
addNewTemplate: function(server) {
server = server || '';
this.$list.append(
this.renderServer(server)
);
},
deleteServer: function(e) {
e.stopPropagation();
var $server = $(e.currentTarget).parents('div.stun-server').first();
$server.remove();
this.saveServers();
if (this.$list.find('div.stun-server').length === 0) {
this.addNewTemplate('stun.nextcloud.com:443');
}
},
saveServers: function() {
var servers = [];
this.$list.find('input').each(function() {
var server = this.value,
parts = server.split(':');
if (parts.length !== 2) {
$(this).addClass('error');
} else {
if (parts[1].match(/^([1-9]\d{0,4})$/) === null ||
parseInt(parts[1]) > Math.pow(2, 16)) { //65536
$(this).addClass('error');
} else {
servers.push(this.value);
$(this).removeClass('error');
}
}
});
OCP.AppConfig.setValue('spreed', 'stun_server', JSON.stringify(servers));
},
renderServer: function(server) {
var $template = $(this.template({
server: server
}));
$template.find('a.icon-add').on('click', this.addNewTemplate.bind(this));
$template.find('a.icon-delete').on('click', this.deleteServer.bind(this));
$template.find('input').on('change', this.saveServers.bind(this));
return $template;
}
};
})(OC, OCP, OCA, $, _);
$(document).ready(function(){
OCA.VideoCalls.Admin.StunServer.init();
});

13
js/settings-admin.js

@ -1,13 +0,0 @@
$(document).ready(function(){
$('#spreed_settings_form').change(function(){
OC.msg.startSaving('#spreed_settings_msg');
var post = $( "#spreed_settings_form" ).serialize();
$.post(OC.generateUrl('/apps/spreed/settings/admin'), post, function(data){
OC.msg.finishedSaving('#spreed_settings_msg', data);
}).fail(function(){
OC.msg.finishedError('#spreed_settings_msg', t('spreed', 'Saving failed'));
});
});
});

11
js/settings-personal.js

@ -1,11 +0,0 @@
$(document).ready(function(){
$('#spreed_settings_form').change(function(){
OC.msg.startSaving('#spreed_settings_msg');
var post = $("#spreed_settings_form").serialize();
$.post(OC.generateUrl('/apps/spreed/settings/personal'), post, function(data){
OC.msg.finishedSaving('#spreed_settings_msg', data);
});
});
});

13
lib/Config.php

@ -47,7 +47,18 @@ class Config {
* @return string
*/
public function getStunServer() {
return $this->config->getAppValue('spreed', 'stun_server', 'stun.nextcloud.com:443');
$config = $this->config->getAppValue('spreed', 'stun_server', 'stun.nextcloud.com:443');
$servers = json_decode($config);
if ($servers === null) {
return $config ?: 'stun.nextcloud.com:443';
}
if (is_array($servers) && !empty($servers)) {
return $servers[mt_rand(0, count($servers) - 1)];
}
return 'stun.nextcloud.com:443';
}
/**

40
lib/Controller/AppSettingsController.php

@ -49,46 +49,14 @@ class AppSettingsController extends Controller {
}
/**
* Configure the settings of the Spreed app. The STUN server must be passed
* in the form "stunserver:port", e.g. "stun.domain.invalid:1234".
* Configure the settings of the Spreed app.
*
* @param string $stun_server
* @param string $turn_server
* @param string $turn_server_secret
* @param string $turn_server_protocols
* @return array
*/
public function setSpreedSettings($stun_server, $turn_server, $turn_server_secret, $turn_server_protocols) {
$stun_server = trim($stun_server);
if ($stun_server !== "") {
if (substr($stun_server, 0, 5) === "stun:") {
$stun_server = substr($stun_server, 5);
}
$parts = explode(":", $stun_server);
if (count($parts) > 2) {
return array('data' =>
array('message' =>
(string) $this->l10n->t('Invalid format, must be stunserver:port.')
),
'status' => 'error'
);
}
$options = array(
'options' => array(
'default' => 0,
'max_range' => 65535,
'min_range' => 1,
),
);
if (count($parts) === 2 && !filter_var($parts[1], FILTER_VALIDATE_INT, $options)) {
return array('data' =>
array('message' =>
(string) $this->l10n->t('Invalid port specified.')
),
'status' => 'error'
);
}
}
public function setSpreedSettings($turn_server, $turn_server_secret, $turn_server_protocols) {
if ($turn_server_protocols !== '') {
if (!in_array($turn_server_protocols, array('udp,tcp', 'tcp', 'udp'))) {
return array('data' =>

4
lib/Settings/AdminSection.php → lib/Settings/Admin/Section.php

@ -19,14 +19,14 @@
*
*/
namespace OCA\Spreed\Settings;
namespace OCA\Spreed\Settings\Admin;
use OCP\IL10N;
use OCP\IURLGenerator;
use OCP\Settings\IIconSection;
class AdminSection implements IIconSection {
class Section implements IIconSection {
/** @var IL10N */
private $l;

70
lib/Settings/Admin/StunServer.php

@ -0,0 +1,70 @@
<?php
/**
* @copyright Copyright (c) 2017 Joas Schilling <coding@schilljs.com>
*
* @author Joas Schilling <coding@schilljs.com>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\Spreed\Settings\Admin;
use OCP\AppFramework\Http\TemplateResponse;
use OCP\IConfig;
use OCP\Settings\ISettings;
class StunServer implements ISettings {
/** @var IConfig */
private $config;
public function __construct(IConfig $config) {
$this->config = $config;
}
/**
* @return TemplateResponse
*/
public function getForm() {
$parameters = [
'stunServer' => $this->config->getAppValue('spreed', 'stun_server', 'stun.nextcloud.com:443'),
];
return new TemplateResponse('spreed', 'settings/admin/stun-server', $parameters, '');
}
/**
* @return string the section ID, e.g. 'sharing'
*/
public function getSection() {
return 'stun_server';
}
/**
* @return int whether the form should be rather on the top or bottom of
* the admin section. The forms are arranged in ascending order of the
* priority values. It is required to return a value between 0 and 100.
*
* E.g.: 70
*/
public function getPriority() {
return 65;
}
}

7
lib/Settings/Admin.php → lib/Settings/Admin/TurnServer.php

@ -19,14 +19,14 @@
*
*/
namespace OCA\Spreed\Settings;
namespace OCA\Spreed\Settings\Admin;
use OCP\AppFramework\Http\TemplateResponse;
use OCP\IConfig;
use OCP\Settings\ISettings;
class Admin implements ISettings {
class TurnServer implements ISettings {
/** @var IConfig */
private $config;
@ -40,13 +40,12 @@ class Admin implements ISettings {
*/
public function getForm() {
$parameters = [
'stunServer' => $this->config->getAppValue('spreed', 'stun_server', 'stun.nextcloud.com:443'),
'turnServer' => $this->config->getAppValue('spreed', 'turn_server', ''),
'turnServerSecret' => $this->config->getAppValue('spreed', 'turn_server_secret', ''),
'turnServerProtocols' => $this->config->getAppValue('spreed', 'turn_server_protocols', ''),
];
return new TemplateResponse('spreed', 'settings-admin', $parameters, '');
return new TemplateResponse('spreed', 'settings/admin/turn-server', $parameters, '');
}
/**

56
templates/settings-admin.php

@ -1,56 +0,0 @@
<?php
/** @var array $_ */
/** @var \OCP\IL10N $l */
script('spreed', ['settings-admin']);
style('spreed', ['settings-admin']);
?>
<div id="spreed" class="section">
<form id="spreed_settings_form" class="spreed_settings">
<h2 class="app-name"><?php p($l->t('Video calls')) ?></h2>
<p class="settings-hint"><?php p($l->t('The STUN server is necessary so participants can connect to calls. The TURN server makes sure connection works even through firewalls.')); ?></p>
<span id="spreed_settings_msg" class="msg"></span>
<p>
<label for="stun_server"><?php p($l->t('STUN server')) ?></label>
<input type="text" id="stun_server"
name="stun_server" placeholder="stunserver:port"
value="<?php p($_['stunServer']) ?>" />
</p>
<p>
<em><?php p($l->t('The STUN server is used to determine the public IP address of participants behind a router.')) ?></em>
</p>
<p>
<label for="turn_server"><?php p($l->t('TURN server')) ?></label>
<input type="text" id="turn_server"
name="turn_server" placeholder="https://turn.example.org"
value="<?php p($_['turnServer']) ?>" />
</p>
<p>
<label for="turn_server_secret"><?php p($l->t('TURN server shared secret')) ?></label>
<input type="text" id="turn_server_secret"
name="turn_server_secret" placeholder="shared secret"
value="<?php p($_['turnServerSecret']) ?>" />
</p>
<p>
<label for="turn_server_protocols"><?php p($l->t('TURN server protocols')) ?></label>
<select id="turn_server_protocols" name="turn_server_protocols">
<option value="udp,tcp"
<?php p($_['turnServerProtocols'] === 'udp,tcp' ? 'selected' : '') ?>>
<?php p($l->t('UDP and TCP')) ?>
</option>
<option value="udp"
<?php p($_['turnServerProtocols'] === 'udp' ? 'selected' : '') ?>>
<?php p($l->t('UDP only')) ?>
</option>
<option value="tcp"
<?php p($_['turnServerProtocols'] === 'tcp' ? 'selected' : '') ?>>
<?php p($l->t('TCP only')) ?>
</option>
</select>
</p>
<p>
<em><?php p($l->t('The TURN server is used to proxy the traffic from participants behind a firewall.')) ?></em>
</p>
</form>
</div>

14
templates/settings/admin/stun-server.php

@ -0,0 +1,14 @@
<?php
/** @var array $_ */
/** @var \OCP\IL10N $l */
script('spreed', ['admin/stun-server']);
style('spreed', ['settings-admin']);
?>
<div class="videocalls section">
<h3><?php p($l->t('STUN servers')) ?></h3>
<p class="settings-hint"><?php p($l->t('A STUN server is used to determine the public IP address of participants behind a router.')); ?></p>
<div class="stun-servers" data-servers="<?php p($_['stunServer']) ?>">
</div>
</div>

40
templates/settings/admin/turn-server.php

@ -0,0 +1,40 @@
<?php
/** @var array $_ */
/** @var \OCP\IL10N $l */
script('spreed', ['settings-admin']);
style('spreed', ['settings-admin']);
?>
<div class="videocalls section">
<h3><?php p($l->t('TURN server')) ?></h3>
<p class="settings-hint"><?php p($l->t('The TURN server is used to proxy the traffic from participants behind a firewall.')); ?></p>
<p>
<label for="turn_server"><?php p($l->t('TURN server')) ?></label>
<input type="text" id="turn_server"
name="turn_server" placeholder="https://turn.example.org"
value="<?php p($_['turnServer']) ?>" />
</p>
<p>
<label for="turn_server_secret"><?php p($l->t('TURN server shared secret')) ?></label>
<input type="text" id="turn_server_secret"
name="turn_server_secret" placeholder="shared secret"
value="<?php p($_['turnServerSecret']) ?>" />
</p>
<p>
<label for="turn_server_protocols"><?php p($l->t('TURN server protocols')) ?></label>
<select id="turn_server_protocols" name="turn_server_protocols">
<option value="udp,tcp"
<?php p($_['turnServerProtocols'] === 'udp,tcp' ? 'selected' : '') ?>>
<?php p($l->t('UDP and TCP')) ?>
</option>
<option value="udp"
<?php p($_['turnServerProtocols'] === 'udp' ? 'selected' : '') ?>>
<?php p($l->t('UDP only')) ?>
</option>
<option value="tcp"
<?php p($_['turnServerProtocols'] === 'tcp' ? 'selected' : '') ?>>
<?php p($l->t('TCP only')) ?>
</option>
</select>
</p>
</div>
Loading…
Cancel
Save