diff options
author | Joas Schilling <213943+nickvergessen@users.noreply.github.com> | 2021-12-07 12:39:00 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-12-07 12:39:00 +0300 |
commit | aa7614399eafae49e62828fba06c08f0117398ae (patch) | |
tree | 1512eeb525ec3edef0356a82294e3f37ee1b3ced | |
parent | 35d28039116a30701e5981ba0e38237abb89d2e4 (diff) | |
parent | d15222fecdefa1c3101edb8116761343352a3663 (diff) |
Merge pull request #6430 from nextcloud/backport/6381/stable21
[stable21] Introduce event so other apps can override the list of TURN servers.
-rw-r--r-- | lib/Config.php | 23 | ||||
-rw-r--r-- | lib/Events/GetTurnServersEvent.php | 45 | ||||
-rw-r--r-- | lib/Settings/Admin/AdminSettings.php | 2 | ||||
-rw-r--r-- | tests/php/ConfigTest.php | 60 | ||||
-rw-r--r-- | tests/php/Controller/SignalingControllerTest.php | 3 | ||||
-rw-r--r-- | tests/php/Mocks/GetTurnServerListener.php | 41 | ||||
-rw-r--r-- | tests/php/Signaling/BackendNotifierTest.php | 4 |
7 files changed, 164 insertions, 14 deletions
diff --git a/lib/Config.php b/lib/Config.php index c3c807e1a..ba30a4833 100644 --- a/lib/Config.php +++ b/lib/Config.php @@ -24,6 +24,8 @@ declare(strict_types=1); namespace OCA\Talk; use OCP\AppFramework\Utility\ITimeFactory; +use OCA\Talk\Events\GetTurnServersEvent; +use OCP\EventDispatcher\IEventDispatcher; use OCP\IConfig; use OCP\IGroupManager; use OCP\IUser; @@ -42,6 +44,8 @@ class Config { private $groupManager; /** @var ISecureRandom */ private $secureRandom; + /** @var IEventDispatcher */ + private $dispatcher; /** @var array */ protected $canEnableSIP = []; @@ -49,11 +53,13 @@ class Config { public function __construct(IConfig $config, ISecureRandom $secureRandom, IGroupManager $groupManager, - ITimeFactory $timeFactory) { + ITimeFactory $timeFactory, + IEventDispatcher $dispatcher) { $this->config = $config; $this->secureRandom = $secureRandom; $this->groupManager = $groupManager; $this->timeFactory = $timeFactory; + $this->dispatcher = $dispatcher; } /** @@ -235,12 +241,18 @@ class Config { * * @return array */ - public function getTurnServers(): array { + public function getTurnServers($withEvent = true): array { $config = $this->config->getAppValue('spreed', 'turn_servers'); $servers = json_decode($config, true); if ($servers === null || empty($servers) || !is_array($servers)) { - return []; + $servers = []; + } + + if ($withEvent) { + $event = new GetTurnServersEvent($servers); + $this->dispatcher->dispatchTyped($event); + $servers = $event->getServers(); } foreach ($servers as $key => $server) { @@ -280,12 +292,13 @@ class Config { $timestamp = $this->timeFactory->getTime() + 86400; $rnd = $this->secureRandom->generate(16); $username = $timestamp . ':' . $rnd; - $password = base64_encode(hash_hmac('sha1', $username, $server['secret'], true)); + $u = $server['username'] ?? $username; + $password = $server['password'] ?? base64_encode(hash_hmac('sha1', $u, $server['secret'], true)); return [ 'schemes' => $server['schemes'], 'server' => $server['server'], - 'username' => $username, + 'username' => $u, 'password' => $password, 'protocols' => $server['protocols'], ]; diff --git a/lib/Events/GetTurnServersEvent.php b/lib/Events/GetTurnServersEvent.php new file mode 100644 index 000000000..b3611abe2 --- /dev/null +++ b/lib/Events/GetTurnServersEvent.php @@ -0,0 +1,45 @@ +<?php + +declare(strict_types=1); +/** + * @copyright Copyright (c) 2021 Joachim Bauch <mail@joachim-bauch.de> + * + * @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\Talk\Events; + +use OCP\EventDispatcher\Event; + +class GetTurnServersEvent extends Event { + + /** @var array */ + protected $servers; + + public function __construct(array $servers) { + parent::__construct(); + $this->servers = $servers; + } + + public function getServers(): array { + return $this->servers; + } + + public function setServers(array $servers) { + $this->servers = $servers; + } +} diff --git a/lib/Settings/Admin/AdminSettings.php b/lib/Settings/Admin/AdminSettings.php index 28ded4075..d534cdf61 100644 --- a/lib/Settings/Admin/AdminSettings.php +++ b/lib/Settings/Admin/AdminSettings.php @@ -160,7 +160,7 @@ class AdminSettings implements ISettings { } protected function initTurnServers(): void { - $this->initialState->provideInitialState('turn_servers', $this->talkConfig->getTurnServers()); + $this->initialState->provideInitialState('turn_servers', $this->talkConfig->getTurnServers(false)); } protected function initSignalingServers(): void { diff --git a/tests/php/ConfigTest.php b/tests/php/ConfigTest.php index c533e36f2..6bab9ba3b 100644 --- a/tests/php/ConfigTest.php +++ b/tests/php/ConfigTest.php @@ -21,7 +21,10 @@ namespace OCA\Talk\Tests\php; use OCA\Talk\Config; +use OCA\Talk\Events\GetTurnServersEvent; +use OCA\Talk\Tests\php\Mocks\GetTurnServerListener; use OCP\AppFramework\Utility\ITimeFactory; +use OCP\EventDispatcher\IEventDispatcher; use OCP\IConfig; use OCP\IGroupManager; use OCP\Security\ISecureRandom; @@ -41,6 +44,8 @@ class ConfigTest extends TestCase { $secureRandom = $this->createMock(ISecureRandom::class); /** @var MockObject|IGroupManager $secureRandom */ $groupManager = $this->createMock(IGroupManager::class); + /** @var MockObject|IEventDispatcher $dispatcher */ + $dispatcher = $this->createMock(IEventDispatcher::class); /** @var MockObject|IConfig $config */ $config = $this->createMock(IConfig::class); $config @@ -54,7 +59,7 @@ class ConfigTest extends TestCase { ->with('has_internet_connection', true) ->willReturn(true); - $helper = new Config($config, $secureRandom, $groupManager, $timeFactory); + $helper = new Config($config, $secureRandom, $groupManager, $timeFactory, $dispatcher); $this->assertTrue(in_array($helper->getStunServer(), $servers, true)); } @@ -65,6 +70,8 @@ class ConfigTest extends TestCase { $secureRandom = $this->createMock(ISecureRandom::class); /** @var MockObject|IGroupManager $secureRandom */ $groupManager = $this->createMock(IGroupManager::class); + /** @var MockObject|IEventDispatcher $dispatcher */ + $dispatcher = $this->createMock(IEventDispatcher::class); /** @var MockObject|IConfig $config */ $config = $this->createMock(IConfig::class); $config @@ -78,7 +85,7 @@ class ConfigTest extends TestCase { ->with('has_internet_connection', true) ->willReturn(true); - $helper = new Config($config, $secureRandom, $groupManager, $timeFactory); + $helper = new Config($config, $secureRandom, $groupManager, $timeFactory, $dispatcher); $this->assertSame('stun.nextcloud.com:443', $helper->getStunServer()); } @@ -89,6 +96,8 @@ class ConfigTest extends TestCase { $secureRandom = $this->createMock(ISecureRandom::class); /** @var MockObject|IGroupManager $secureRandom */ $groupManager = $this->createMock(IGroupManager::class); + /** @var MockObject|IEventDispatcher $dispatcher */ + $dispatcher = $this->createMock(IEventDispatcher::class); /** @var MockObject|IConfig $config */ $config = $this->createMock(IConfig::class); $config @@ -102,7 +111,7 @@ class ConfigTest extends TestCase { ->with('has_internet_connection', true) ->willReturn(false); - $helper = new Config($config, $secureRandom, $groupManager, $timeFactory); + $helper = new Config($config, $secureRandom, $groupManager, $timeFactory, $dispatcher); $this->assertSame('', $helper->getStunServer()); } @@ -138,6 +147,8 @@ class ConfigTest extends TestCase { /** @var MockObject|IGroupManager $secureRandom */ $groupManager = $this->createMock(IGroupManager::class); + /** @var MockObject|IEventDispatcher $dispatcher */ + $dispatcher = $this->createMock(IEventDispatcher::class); /** @var MockObject|ISecureRandom $secureRandom */ $secureRandom = $this->createMock(ISecureRandom::class); @@ -146,7 +157,7 @@ class ConfigTest extends TestCase { ->method('generate') ->with(16) ->willReturn('abcdefghijklmnop'); - $helper = new Config($config, $secureRandom, $groupManager, $timeFactory); + $helper = new Config($config, $secureRandom, $groupManager, $timeFactory, $dispatcher); // $server = $helper->getTurnSettings(); @@ -169,6 +180,43 @@ class ConfigTest extends TestCase { } } + public function testGenerateTurnSettingsEvent() { + /** @var MockObject|IConfig $config */ + $config = $this->createMock(IConfig::class); + $config + ->expects($this->once()) + ->method('getAppValue') + ->with('spreed', 'turn_servers', '') + ->willReturn(json_encode([])); + + /** @var MockObject|ITimeFactory $timeFactory */ + $timeFactory = $this->createMock(ITimeFactory::class); + + /** @var MockObject|IGroupManager $secureRandom */ + $groupManager = $this->createMock(IGroupManager::class); + + /** @var MockObject|ISecureRandom $secureRandom */ + $secureRandom = $this->createMock(ISecureRandom::class); + + /** @var IEventDispatcher $dispatcher */ + $dispatcher = \OC::$server->query(IEventDispatcher::class); + + $server = [ + 'schemes' => 'turn', + 'server' => 'turn.domain.invalid', + 'username' => 'john', + 'password' => 'abcde', + 'protocols' => 'udp,tcp', + ]; + + $dispatcher->addServiceListener(GetTurnServersEvent::class, GetTurnServerListener::class); + + $helper = new Config($config, $secureRandom, $groupManager, $timeFactory, $dispatcher); + + $settings = $helper->getTurnSettings(); + $this->assertSame($server, $settings); + } + public function dataGetWebSocketDomainForSignalingServer() { return [ ['http://blabla.nextcloud.com', 'ws://blabla.nextcloud.com'], @@ -237,10 +285,12 @@ class ConfigTest extends TestCase { $secureRandom = $this->createMock(ISecureRandom::class); /** @var MockObject|IGroupManager $secureRandom */ $groupManager = $this->createMock(IGroupManager::class); + /** @var MockObject|IEventDispatcher $dispatcher */ + $dispatcher = $this->createMock(IEventDispatcher::class); /** @var MockObject|IConfig $config */ $config = $this->createMock(IConfig::class); - $helper = new Config($config, $secureRandom, $groupManager, $timeFactory); + $helper = new Config($config, $secureRandom, $groupManager, $timeFactory, $dispatcher); $this->assertEquals( $expectedWebSocketDomain, diff --git a/tests/php/Controller/SignalingControllerTest.php b/tests/php/Controller/SignalingControllerTest.php index 2dc9453db..c5d6467ce 100644 --- a/tests/php/Controller/SignalingControllerTest.php +++ b/tests/php/Controller/SignalingControllerTest.php @@ -112,7 +112,8 @@ class SignalingControllerTest extends \Test\TestCase { ])); $config->setAppValue('spreed', 'signaling_ticket_secret', 'the-app-ticket-secret'); $config->setUserValue($this->userId, 'spreed', 'signaling_ticket_secret', 'the-user-ticket-secret'); - $this->config = new Config($config, $this->secureRandom, $groupManager, $timeFactory); + $this->dispatcher = \OC::$server->query(IEventDispatcher::class); + $this->config = new Config($config, $this->secureRandom, $groupManager, $timeFactory, $this->dispatcher); $this->session = $this->createMock(TalkSession::class); $this->dbConnection = \OC::$server->getDatabaseConnection(); $this->signalingManager = $this->createMock(\OCA\Talk\Signaling\Manager::class); diff --git a/tests/php/Mocks/GetTurnServerListener.php b/tests/php/Mocks/GetTurnServerListener.php new file mode 100644 index 000000000..d52d08997 --- /dev/null +++ b/tests/php/Mocks/GetTurnServerListener.php @@ -0,0 +1,41 @@ +<?php + +declare(strict_types=1); +/** + * @copyright Copyright (c) 2021 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\Talk\Tests\php\Mocks; + +use OCP\EventDispatcher\Event; +use OCP\EventDispatcher\IEventListener; + +class GetTurnServerListener implements IEventListener { + public function handle(Event $event): void { + $event->setServers([ + [ + 'schemes' => 'turn', + 'server' => 'turn.domain.invalid', + 'username' => 'john', + 'password' => 'abcde', + 'protocols' => 'udp,tcp', + ], + ]); + } +} diff --git a/tests/php/Signaling/BackendNotifierTest.php b/tests/php/Signaling/BackendNotifierTest.php index 39dabc43d..70195502b 100644 --- a/tests/php/Signaling/BackendNotifierTest.php +++ b/tests/php/Signaling/BackendNotifierTest.php @@ -131,13 +131,13 @@ class BackendNotifierTest extends \Test\TestCase { ->method('getSignalingServerForConversation') ->willReturn(['server' => $this->baseUrl]); - $this->config = new Config($config, $this->secureRandom, $groupManager, $this->timeFactory); + $this->dispatcher = \OC::$server->query(IEventDispatcher::class); + $this->config = new Config($config, $this->secureRandom, $groupManager, $this->timeFactory, $this->dispatcher); $this->recreateBackendNotifier(); $this->overwriteService(BackendNotifier::class, $this->controller); $dbConnection = \OC::$server->getDatabaseConnection(); - $this->dispatcher = \OC::$server->query(IEventDispatcher::class); $this->manager = new Manager( $dbConnection, $config, |