diff options
-rw-r--r-- | lib/private/Settings/Admin/ServerInfo.php | 86 | ||||
-rw-r--r-- | lib/private/Settings/Personal/PersonalInfo.php | 14 | ||||
-rw-r--r-- | settings/Controller/ServerInfoSettingsController.php | 67 | ||||
-rw-r--r-- | settings/css/_server-info.scss | 4 | ||||
-rw-r--r-- | settings/css/_where-is-your-data.scss | 4 | ||||
-rw-r--r-- | settings/js/admin.js | 103 | ||||
-rw-r--r-- | settings/routes.php | 1 | ||||
-rw-r--r-- | settings/templates/settings/admin/server-info.php | 70 | ||||
-rw-r--r-- | tests/Settings/Controller/ServerInfoSettingsControllerTest.php | 94 |
9 files changed, 411 insertions, 32 deletions
diff --git a/lib/private/Settings/Admin/ServerInfo.php b/lib/private/Settings/Admin/ServerInfo.php index e4c7a83ed87..8ac4f890504 100644 --- a/lib/private/Settings/Admin/ServerInfo.php +++ b/lib/private/Settings/Admin/ServerInfo.php @@ -1,26 +1,104 @@ <?php +/** + * @copyright Copyright (c) 2018 Michael Weimann <mail@michael-weimann.eu> + * + * @author Michael Weimann <mail@michael-weimann.eu> + * + * @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 OC\Settings\Admin; use OCP\AppFramework\Http\TemplateResponse; +use OCP\IConfig; +use OCP\IGroupManager; +use OCP\IUser; use OCP\Settings\ISettings; /** - * Class ServerInfo - * - * @package OC\Settings\Admin + * This class describes the server info settings. */ class ServerInfo implements ISettings { + const SETTING_LOCATION = 'serverinfo.location'; + const SETTING_PROVIDER = 'serverinfo.provider'; + const SETTING_PROVIDER_WEBSITE = 'serverinfo.provider.website'; + const SETTING_PROVIDER_PRIVACY_LINK = 'serverinfo.provider.privacylink'; + const SETTING_PROVIDER_ADMIN_CONTACT = 'serverinfo.admincontact'; + + /** + * @var IConfig + */ + private $config; + + /** + * @var IGroupManager + */ + private $groupManager; + + /** + * ServerInfo constructor. + * + * @param IConfig $config + * @param IGroupManager $groupManager + */ + public function __construct(IConfig $config, IGroupManager $groupManager) { + $this->config = $config; + $this->groupManager = $groupManager; + } + /** * @return TemplateResponse */ public function getForm() { - $parameters = []; + $parameters = [ + 'location' => $this->config->getSystemValue(self::SETTING_LOCATION), + 'provider' => $this->config->getSystemValue(self::SETTING_PROVIDER), + 'providerWebsite' => $this->config->getSystemValue(self::SETTING_PROVIDER_WEBSITE), + 'providerPrivacyLink' => $this->config->getSystemValue(self::SETTING_PROVIDER_PRIVACY_LINK), + 'adminUsers' => $this->getAdminListValues(), + 'adminContact' => $this->config->getSystemValue(self::SETTING_PROVIDER_ADMIN_CONTACT), + ]; return new TemplateResponse('settings', 'settings/admin/server-info', $parameters, ''); } /** + * Returns the admin list values. + * + * @return array[] An array or arrays with the keys 'id' and 'displayName' + */ + private function getAdminListValues() { + $adminGroup = $this->groupManager->get('admin'); + $users = $adminGroup->getUsers(); + + $users = array_map(function(IUser $user) { + return [ + 'id' => $user->getUID(), + 'displayName' => $user->getDisplayName() + ]; + }, $users); + + usort($your_data, function(array $a, array $b) { + return strcmp($a['displayName'], $b['displayName']); + }); + + return $users; + } + + /** * Returns the server info section id. * * @return string diff --git a/lib/private/Settings/Personal/PersonalInfo.php b/lib/private/Settings/Personal/PersonalInfo.php index 42a89a5f309..444600f967a 100644 --- a/lib/private/Settings/Personal/PersonalInfo.php +++ b/lib/private/Settings/Personal/PersonalInfo.php @@ -26,6 +26,7 @@ namespace OC\Settings\Personal; use OC\Accounts\AccountManager; +use OC\Settings\Admin\ServerInfo; use OCA\FederatedFileSharing\AppInfo\Application; use OCP\App\IAppManager; use OCP\AppFramework\Http\TemplateResponse; @@ -115,6 +116,9 @@ class PersonalInfo implements ISettings { $localeParameters = $this->getLocales($user); $messageParameters = $this->getMessageParameters($userData); + $adminContactConfigId = $this->config->getSystemValue(ServerInfo::SETTING_PROVIDER_ADMIN_CONTACT); + $adminContact = $this->userManager->get($adminContactConfigId); + $parameters = [ 'total_space' => $totalSpace, 'usage' => \OC_Helper::humanFileSize($storageInfo['used']), @@ -141,12 +145,12 @@ class PersonalInfo implements ISettings { 'twitterVerification' => $userData[AccountManager::PROPERTY_TWITTER]['verified'], 'groups' => $this->getGroups($user), 'dataLocation' => 'Germany', - 'provider' => 'Mustermann GmbH', - 'providerLink' => 'https://www.hetzner.de/', - 'providerPrivacyLink' => 'https://www.hetzner.de/rechtliches/datenschutz', + 'provider' => $this->config->getSystemValue(ServerInfo::SETTING_PROVIDER), + 'providerLink' => $this->config->getSystemValue(ServerInfo::SETTING_PROVIDER_WEBSITE), + 'providerPrivacyLink' => $this->config->getSystemValue(ServerInfo::SETTING_PROVIDER_PRIVACY_LINK), 'encryptionEnabled' => true || $this->encryptionManager->isEnabled(), - 'adminName' => 'Michael Weimann', - 'adminMail' => 'mail@michael-weimann.eu' + 'adminName' => $adminContact !== null ? $adminContact->getDisplayName() : '', + 'adminMail' => $adminContact !== null ? $adminContact->getEMailAddress() : '', ] + $messageParameters + $languageParameters + $localeParameters; return new TemplateResponse('settings', 'settings/personal/personal.info', $parameters, ''); diff --git a/settings/Controller/ServerInfoSettingsController.php b/settings/Controller/ServerInfoSettingsController.php new file mode 100644 index 00000000000..d1f411592d4 --- /dev/null +++ b/settings/Controller/ServerInfoSettingsController.php @@ -0,0 +1,67 @@ +<?php +/** + * @copyright Copyright (c) 2018 Michael Weimann <mail@michael-weimann.eu> + * + * @author Michael Weimann <mail@michael-weimann.eu> + * + * @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 OC\Settings\Controller; + +use OC\Settings\Admin\ServerInfo; +use OCP\AppFramework\Controller; +use OCP\IConfig; +use OCP\IRequest; + +/** + * This controller handles server info settings requests. + */ +class ServerInfoSettingsController extends Controller { + + /** + * @var IConfig + */ + private $config; + + /** + * ServerInfoSettingsController constructor. + * + * @param IConfig $config + */ + public function __construct($appName, IRequest $request, IConfig $config) { + parent::__construct($appName, $request); + $this->config = $config; + } + + public function storeServerInfo( + string $location, + string $provider, + string $providerWebsite, + string $providerPrivacyLink, + string $adminContact + ) { + $configs = [ + ServerInfo::SETTING_LOCATION => $location, + ServerInfo::SETTING_PROVIDER => $provider, + ServerInfo::SETTING_PROVIDER_WEBSITE => $providerWebsite, + ServerInfo::SETTING_PROVIDER_PRIVACY_LINK => $providerPrivacyLink, + ServerInfo::SETTING_PROVIDER_ADMIN_CONTACT => $adminContact + ]; + $this->config->setSystemValues($configs); + } + +} diff --git a/settings/css/_server-info.scss b/settings/css/_server-info.scss index c9f89bd566a..1073cab2954 100644 --- a/settings/css/_server-info.scss +++ b/settings/css/_server-info.scss @@ -1,3 +1,7 @@ +/* Copyright (c) 2018 Michael Weimann <mail@michael-weimann.eu + This file is licensed under the Affero General Public License version 3 or later. + See the COPYING-README file. */ + .server-info-settings { .label { display: block; diff --git a/settings/css/_where-is-your-data.scss b/settings/css/_where-is-your-data.scss index 7414f6d36d6..fc71bb0a023 100644 --- a/settings/css/_where-is-your-data.scss +++ b/settings/css/_where-is-your-data.scss @@ -1,3 +1,7 @@ +/* Copyright (c) 2018 Michael Weimann <mail@michael-weimann.eu + This file is licensed under the Affero General Public License version 3 or later. + See the COPYING-README file. */ + .where-is-your-data { // @todo replace by common link style as soon as available a:not(.icon-info) { diff --git a/settings/js/admin.js b/settings/js/admin.js index b93c55a8a9c..1c9b5460eab 100644 --- a/settings/js/admin.js +++ b/settings/js/admin.js @@ -313,4 +313,107 @@ $(document).ready(function(){ if (document.getElementById('security-warning') !== null) { setupChecks(); } + + // server info + + var serverInfoForm = $('#server-info-form'); + var serverInfoWorkingTimeoutHandle; + var serverInfoSubmitButton = $('#server-info-submit-button'); + + /** + * Sets the server info submit button state to default. + */ + function setServerInfoButtonDefault() { + serverInfoSubmitButton.removeClass('button-success'); + serverInfoSubmitButton.removeClass('button-error'); + serverInfoSubmitButton.removeClass('button-working'); + } + + /** + * Sets the server info submit button state to working. + */ + function setServerInfoButtonWorking() { + serverInfoSubmitButton.removeClass('button-success'); + serverInfoSubmitButton.removeClass('button-error'); + serverInfoSubmitButton.addClass('button-working'); + } + + /** + * Sets the server info submit button state to success. + */ + function setServerInfoButtonSuccess() { + serverInfoSubmitButton.removeClass('button-error'); + serverInfoSubmitButton.removeClass('button-working'); + serverInfoSubmitButton.addClass('button-success'); + } + + /** + * Sets the server info submit button state to error. + */ + function setServerInfoButtonError() { + serverInfoSubmitButton.removeClass('button-success'); + serverInfoSubmitButton.removeClass('button-working'); + serverInfoSubmitButton.addClass('button-error'); + } + + /** + * Clears the server info working timeout, if present. + */ + function clearServerInfoWorkingTimeout() { + if (serverInfoWorkingTimeoutHandle) { + clearTimeout(serverInfoWorkingTimeoutHandle); + serverInfoWorkingTimeoutHandle = undefined; + } + } + + /** + * Unlocks the server info form, e.g. removing readonly from inputs. + */ + function unlockForm() { + serverInfoForm.find('input, select').prop('readonly', false); + serverInfoSubmitButton.prop('disabled', false); + } + + /** + * Resets the submit button state one of the form elements is changed. + */ + serverInfoForm.find('input, select').on('keyup change', function() { + setServerInfoButtonDefault(); + }); + + /** + * Handles the server info form submit. + */ + serverInfoForm.on('submit', function(event) { + event.stopImmediatePropagation(); + event.preventDefault(); + + serverInfoForm.find('input, select').prop('readonly', true); + serverInfoSubmitButton.prop('disabled', true); + + clearServerInfoWorkingTimeout(); + + // start show spinner only if request takes longer than one second + serverInfoWorkingTimeoutHandle = setTimeout(function() { + setServerInfoButtonWorking(); + }, 1000); + + $.ajax({ + url: OC.generateUrl('/settings/serverinfo'), + type: 'POST', + data: serverInfoForm.serialize(), + success: function() { + clearServerInfoWorkingTimeout(); + setServerInfoButtonSuccess(); + unlockForm(); + serverInfoSubmitButton.blur(); + }, + error: function() { + clearServerInfoWorkingTimeout(); + setServerInfoButtonError(); + unlockForm(); + serverInfoSubmitButton.blur(); + } + }); + }); }); diff --git a/settings/routes.php b/settings/routes.php index 7c8120f9be4..277bcca484f 100644 --- a/settings/routes.php +++ b/settings/routes.php @@ -83,6 +83,7 @@ $application->registerRoutes($this, [ ['name' => 'ChangePassword#changeUserPassword', 'url' => '/settings/users/changepassword', 'verb' => 'POST'], ['name' => 'TwoFactorSettings#index', 'url' => '/settings/api/admin/twofactorauth', 'verb' => 'GET'], ['name' => 'TwoFactorSettings#update', 'url' => '/settings/api/admin/twofactorauth', 'verb' => 'PUT'], + ['name' => 'ServerInfoSettings#storeServerInfo', 'url' => '/settings/serverinfo', 'verb' => 'POST'], ] ]); diff --git a/settings/templates/settings/admin/server-info.php b/settings/templates/settings/admin/server-info.php index 9c2b3fe4318..3690da6d3b4 100644 --- a/settings/templates/settings/admin/server-info.php +++ b/settings/templates/settings/admin/server-info.php @@ -1,11 +1,39 @@ -<?php ?> +<?php +/** + * @copyright Copyright (c) 2018 Michael Weimann <mail@michael-weimann.eu> + * + * @author Michael Weimann <mail@michael-weimann.eu> + * + * @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/>. + */ + +/** + * This file contains the server info settings template. + */ + +/** @var array $_ */ + +?> <div class="section server-info-settings"> <h2><?php p($l->t('Server info')); ?></h2> <p class="settings-hint"> <?php p($l->t('Enter common info about your Nextcloud instance here. These info are visible to all users.')) ?> </p> - <form> + <form id="server-info-form" name="server-info-form"> <div class="margin-bottom"> <label class="label" for="location"><?php p($l->t('Server location')); ?></label> <input @@ -14,6 +42,7 @@ name="location" type="text" maxlength="100" + value="<?php p($_['location']); ?>" placeholder="<?php p($l->t('country')); ?>"> </div> <div> @@ -24,6 +53,7 @@ name="provider" type="text" maxlength="100" + value="<?php p($_['provider']); ?>" placeholder="<?php p($l->t('company or person')); ?>"> </div> <div> @@ -34,6 +64,7 @@ name="providerWebsite" type="url" maxlength="200" + value="<?php p($_['providerWebsite']); ?>" placeholder="<?php p($l->t('link to website')); ?>"> </div> <div class="margin-bottom"> @@ -44,24 +75,30 @@ name="providerPrivacyLink" type="url" maxlength="200" + value="<?php p($_['providerPrivacyLink']); ?>" placeholder="<?php p($l->t('link to privacy policy')); ?>"> </div> <div class="margin-bottom"> - <label class="label" for="admin"><?php p($l->t('Admin contact')); ?></label> - <select class="form-input" name="admin"> - <option>Michael Weimann</option> - <option>Max Mustermann</option> - <option>Peter Petrowski</option> + <label class="label" for="adminContact"><?php p($l->t('Admin contact')); ?></label> + <select class="form-input" name="adminContact" id="adminContact"> + <option value=""><?php p($l->t('choose admin contact')); ?></option> + <?php foreach($_['adminUsers'] as $adminUser): ?> + <option + value="<?php p($adminUser['id']); ?>" + <?php if ($adminUser['id'] === $_['adminContact']): ?>selected="selected"<?php endif; ?>> + <?php p($adminUser['displayName']); ?> + </option> + <?php endforeach; ?> </select> </div> <div class="form-actions"> - <button id="test123" class="button"> + <button id="server-info-submit-button" class="button"> <span class="default-label"> - <?php p($l->t('Save')); ?> + <?php p($l->t('save')); ?> </span> <span class="working-label"> <span class="icon-loading-small-dark"></span> - <?php p($l->t('saving…')); ?> + <?php p($l->t('saving')); ?> </span> <span class="success-label"> <span class="icon-checkmark-white"></span> @@ -72,19 +109,6 @@ <?php p($l->t('error saving settings')); ?> </span> </button> - <script> - const button = $('#test123'); - button.on('click', (event) => { - event.stopImmediatePropagation(); - event.preventDefault(); - button.prop('disabled', true); - button.addClass('button-working'); - setTimeout(() => { - button.removeClass('button-working'); - button.addClass('button-success'); - }, 1500); - }); - </script> </div> </form> </div> diff --git a/tests/Settings/Controller/ServerInfoSettingsControllerTest.php b/tests/Settings/Controller/ServerInfoSettingsControllerTest.php new file mode 100644 index 00000000000..43dcb90855a --- /dev/null +++ b/tests/Settings/Controller/ServerInfoSettingsControllerTest.php @@ -0,0 +1,94 @@ +<?php +/** + * @copyright Copyright (c) 2018 Michael Weimann <mail@michael-weimann.eu> + * + * @author Michael Weimann <mail@michael-weimann.eu> + * + * @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 Settings\Controller; + +use OC\Settings\Admin\ServerInfo; +use OC\Settings\Controller\ServerInfoSettingsController; +use OCP\IConfig; +use OCP\IRequest; +use PHPUnit\Framework\MockObject\MockObject; +use Test\TestCase; + +/** + * This class provides tests for the server info settings controller. + */ +class ServerInfoSettingsControllerTest extends TestCase { + + /** + * @var IConfig|MockObject + */ + private $config; + + /** + * @var ServerInfoSettingsController + */ + private $controller; + + /** + * Does the test setup. + */ + protected function setUp() { + parent::setUp(); + + $request = $this->getMockBuilder(IRequest::class)->getMock(); + /* @var IRequest|MockObject $request */ + $this->config = $this->getMockBuilder(IConfig::class)->getMock(); + $this->controller = new ServerInfoSettingsController( + 'settings', + $request, + $this->config + ); + } + + /** + * Tests that the handler passes the params to the config. + */ + public function testStoreServerInfo() { + + $location = 'test-location'; + $provider = 'test-provider'; + $providerWebsite = 'https://example.com/'; + $providerPrivacyLink = 'https://example.com/privacy'; + $adminContact = 'testuser'; + + $this->config->expects($this->once()) + ->method('setSystemValues') + ->with([ + ServerInfo::SETTING_LOCATION => $location, + ServerInfo::SETTING_PROVIDER => $provider, + ServerInfo::SETTING_PROVIDER_WEBSITE => $providerWebsite, + ServerInfo::SETTING_PROVIDER_PRIVACY_LINK => $providerPrivacyLink, + ServerInfo::SETTING_PROVIDER_ADMIN_CONTACT => $adminContact, + ]); + + $this->controller->storeServerInfo( + $location, + $provider, + $providerWebsite, + $providerPrivacyLink, + $adminContact + ); + + } + +} |