From 9bf62db3aaf332b867f69c368bc366358a908ebd Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Mon, 6 Nov 2017 13:54:56 +0100 Subject: [PATCH] Add option to enable the app only for users in a specific group (#135) Signed-off-by: Lukas Reschke --- appinfo/app.php | 10 +++ js/admin.js | 52 +++++++++--- lib/Controller/SettingsController.php | 7 ++ lib/PermissionManager.php | 65 ++++++++++++++ lib/Settings/Admin.php | 1 + templates/admin.php | 7 +- tests/lib/PermissionManagerTest.php | 118 ++++++++++++++++++++++++++ 7 files changed, 246 insertions(+), 14 deletions(-) create mode 100644 lib/PermissionManager.php create mode 100644 tests/lib/PermissionManagerTest.php diff --git a/appinfo/app.php b/appinfo/app.php index bafc3467..d99c18d4 100644 --- a/appinfo/app.php +++ b/appinfo/app.php @@ -23,6 +23,16 @@ namespace OCA\Richdocuments\AppInfo; use OC\Security\CSP\ContentSecurityPolicy; +use OCA\Richdocuments\PermissionManager; + +$currentUser = \OC::$server->getUserSession()->getUser(); +if($currentUser !== null) { + /** @var PermissionManager $permissionManager */ + $permissionManager = \OC::$server->query(PermissionManager::class); + if(!$permissionManager->isEnabledForUser($currentUser)) { + return; + } +} $eventDispatcher = \OC::$server->getEventDispatcher(); $eventDispatcher->addListener( diff --git a/js/admin.js b/js/admin.js index 58162f69..58ddbd06 100644 --- a/js/admin.js +++ b/js/admin.js @@ -40,15 +40,11 @@ var documentsSettings = { ); }, - saveGroups: function(groups) { - var data = { - 'edit_groups': groups - }; - + saveGroups: function(data) { $.post( OC.filePath('richdocuments', 'ajax', 'admin.php'), data - ); + ); }, saveDocFormat: function(format) { @@ -80,14 +76,23 @@ var documentsSettings = { OC.msg.finishedAction('#enable-external-apps-section-msg', response); }, - initEditGroups: function() { - var groups = $('#edit_group_select').val(); + initGroups: function() { + var selectorPrefixes = [ + 'edit', + 'use' + ]; + + for (i = 0; i < selectorPrefixes.length; i++) { + var selectorPrefix = selectorPrefixes[i]; + + var groups = $('#' + selectorPrefix + '_group_select').val(); if (groups !== '') { - OC.Settings.setupGroupsSelect($('#edit_group_select')); - $('.edit-groups-enable').attr('checked', 'checked'); + OC.Settings.setupGroupsSelect($('#' + selectorPrefix + '_group_select')); + $('.' + selectorPrefix + '-groups-enable').attr('checked', 'checked'); } else { - $('.edit-groups-enable').attr('checked', null); + $('.' + selectorPrefix + '-groups-enable').attr('checked', null); } + } }, initExternalApps: function() { @@ -106,7 +111,7 @@ var documentsSettings = { }, initialize: function() { - documentsSettings.initEditGroups(); + documentsSettings.initGroups(); documentsSettings.initExternalApps(); $('#wopi_apply').on('click', documentsSettings.save); @@ -189,7 +194,7 @@ var documentsSettings = { $(document).on('change', '#edit_group_select', function() { var element = $(this).parent().find('input.edit-groups-enable'); var groups = $(this).val(); - documentsSettings.saveGroups(groups); + documentsSettings.saveGroups({edit_groups: groups}); }); $(document).on('change', '.edit-groups-enable', function() { @@ -207,6 +212,27 @@ var documentsSettings = { $select.change(); }); + $(document).on('change', '#use_group_select', function() { + var element = $(this).parent().find('input.use-groups-enable'); + var groups = $(this).val(); + documentsSettings.saveGroups({use_groups: groups}); + }); + + $(document).on('change', '.use-groups-enable', function() { + var $select = $(this).parent().find('#use_group_select'); + $select.val(''); + + if (this.checked) { + OC.Settings.setupGroupsSelect($select, { + placeholder: t('core', 'All') + }); + } else { + $select.select2('destroy'); + } + + $select.change(); + }); + } }; diff --git a/lib/Controller/SettingsController.php b/lib/Controller/SettingsController.php index 850b28d1..60a4c10b 100644 --- a/lib/Controller/SettingsController.php +++ b/lib/Controller/SettingsController.php @@ -53,6 +53,7 @@ class SettingsController extends Controller{ public function getSettings() { return new JSONResponse([ 'wopi_url' => $this->appConfig->getAppValue('wopi_url'), + 'use_groups' => $this->appConfig->getAppValue('use_groups'), 'edit_groups' => $this->appConfig->getAppValue('edit_groups'), 'doc_format' => $this->appConfig->getAppValue('doc_format'), ]); @@ -61,11 +62,13 @@ class SettingsController extends Controller{ /** * @param string $wopi_url * @param string $edit_groups + * @param string $use_groups * @param string $doc_format * @return JSONResponse */ public function setSettings($wopi_url, $edit_groups, + $use_groups, $doc_format, $external_apps){ $message = $this->l10n->t('Saved'); @@ -83,6 +86,10 @@ class SettingsController extends Controller{ $this->appConfig->setAppValue('edit_groups', $edit_groups); } + if ($use_groups !== null){ + $this->appConfig->setAppValue('use_groups', $use_groups); + } + if ($doc_format !== null) { $this->appConfig->setAppValue('doc_format', $doc_format); } diff --git a/lib/PermissionManager.php b/lib/PermissionManager.php new file mode 100644 index 00000000..d956c50c --- /dev/null +++ b/lib/PermissionManager.php @@ -0,0 +1,65 @@ + + * + * @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 . + * + */ + +namespace OCA\Richdocuments; + +use OCP\IConfig; +use OCP\IGroupManager; +use OCP\IUser; + +class PermissionManager { + const APP_ID = 'richdocuments'; + /** @var IConfig */ + private $config; + /** @var IGroupManager */ + private $groupManager; + + public function __construct(IConfig $config, + IGroupManager $groupManager) { + $this->config = $config; + $this->groupManager = $groupManager; + } + + /** + * @param string $groupString + * @return array + */ + private function splitGroups($groupString) { + return explode('|', $groupString); + } + + public function isEnabledForUser(IUser $user) { + $enabledForGroups = $this->config->getAppValue(self::APP_ID, 'use_groups', ''); + if($enabledForGroups === '') { + return true; + } + + $groups = $this->splitGroups($enabledForGroups); + $uid = $user->getUID(); + foreach($groups as $group) { + if($this->groupManager->isInGroup($uid, $group)) { + return true; + } + } + + return false; + } +} diff --git a/lib/Settings/Admin.php b/lib/Settings/Admin.php index e4faa02f..7fffc285 100644 --- a/lib/Settings/Admin.php +++ b/lib/Settings/Admin.php @@ -48,6 +48,7 @@ class Admin implements ISettings { [ 'wopi_url' => $this->config->getAppValue('richdocuments', 'wopi_url'), 'edit_groups' => $this->config->getAppValue('richdocuments', 'edit_groups'), + 'use_groups' => $this->config->getAppValue('richdocuments', 'use_groups'), 'doc_format' => $this->config->getAppValue('richdocuments', 'doc_format'), 'external_apps' => $this->config->getAppValue('richdocuments', 'external_apps'), ], diff --git a/templates/admin.php b/templates/admin.php index 6dc8aa81..52c973ac 100644 --- a/templates/admin.php +++ b/templates/admin.php @@ -1,5 +1,6 @@

t('Collabora Online')) ?>

@@ -9,8 +10,12 @@ script('richdocuments', 'admin');

+ + + +
- +
/> diff --git a/tests/lib/PermissionManagerTest.php b/tests/lib/PermissionManagerTest.php new file mode 100644 index 00000000..ed498e63 --- /dev/null +++ b/tests/lib/PermissionManagerTest.php @@ -0,0 +1,118 @@ + + * + * @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 . + * + */ + +namespace Tests\Richdocuments; + +use OCA\Richdocuments\PermissionManager; +use OCP\IConfig; +use OCP\IGroupManager; +use OCP\IUser; +use Test\TestCase; + +class PermissionManagerTest extends TestCase { + /** @var IConfig|\PHPUnit_Framework_MockObject_MockBuilder */ + private $config; + /** @var IGroupManager|\PHPUnit_Framework_MockObject_MockBuilder */ + private $groupManager; + /** @var PermissionManager */ + private $permissionManager; + + public function setUp() { + parent::setUp(); + $this->config = $this->createMock(IConfig::class); + $this->groupManager = $this->createMock(IGroupManager::class); + $this->permissionManager = new PermissionManager($this->config, $this->groupManager); + } + + public function testIsEnabledForUserEnabledNoRestrictions() { + /** @var IUser|\PHPUnit_Framework_MockObject_MockBuilder $user */ + $user = $this->createMock(IUser::class); + + $this->config + ->expects($this->once()) + ->method('getAppValue') + ->with('richdocuments', 'use_groups', '') + ->willReturn(''); + + $this->assertTrue($this->permissionManager->isEnabledForUser($user)); + } + + public function testIsEnabledForUserEnabledNotInGroup() { + /** @var IUser|\PHPUnit_Framework_MockObject_MockBuilder $user */ + $user = $this->createMock(IUser::class); + $user + ->expects($this->once()) + ->method('getUID') + ->willReturn('TestUser'); + + $this->config + ->expects($this->once()) + ->method('getAppValue') + ->with('richdocuments', 'use_groups', '') + ->willReturn('Enabled1|Enabled2|Enabled3'); + + $this->groupManager + ->expects($this->at(0)) + ->method('isInGroup') + ->with('TestUser', 'Enabled1') + ->willReturn(false); + $this->groupManager + ->expects($this->at(1)) + ->method('isInGroup') + ->with('TestUser', 'Enabled2') + ->willReturn(false); + $this->groupManager + ->expects($this->at(2)) + ->method('isInGroup') + ->with('TestUser', 'Enabled3') + ->willReturn(false); + + $this->assertFalse($this->permissionManager->isEnabledForUser($user)); + } + + public function testIsEnabledForUserEnabledInGroup() { + /** @var IUser|\PHPUnit_Framework_MockObject_MockBuilder $user */ + $user = $this->createMock(IUser::class); + $user + ->expects($this->once()) + ->method('getUID') + ->willReturn('TestUser'); + + $this->config + ->expects($this->once()) + ->method('getAppValue') + ->with('richdocuments', 'use_groups', '') + ->willReturn('Enabled1|Enabled2|Enabled3'); + + $this->groupManager + ->expects($this->at(0)) + ->method('isInGroup') + ->with('TestUser', 'Enabled1') + ->willReturn(false); + $this->groupManager + ->expects($this->at(1)) + ->method('isInGroup') + ->with('TestUser', 'Enabled2') + ->willReturn(true); + + $this->assertTrue($this->permissionManager->isEnabledForUser($user)); + } +}