@@ -0,0 +1,83 @@ | |||
<?php | |||
/** | |||
* @copyright Copyright (c) 2016 Arthur Schiwon <blizzz@arthur-schiwon.de> | |||
* | |||
* @author Arthur Schiwon <blizzz@arthur-schiwon.de> | |||
* @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\Theming\Settings; | |||
use OCP\IL10N; | |||
use OCP\IURLGenerator; | |||
use OCP\Settings\IIconSection; | |||
class Section implements IIconSection { | |||
/** @var IL10N */ | |||
private $l; | |||
/** @var IURLGenerator */ | |||
private $url; | |||
/** | |||
* @param IURLGenerator $url | |||
* @param IL10N $l | |||
*/ | |||
public function __construct(IURLGenerator $url, IL10N $l) { | |||
$this->url = $url; | |||
$this->l = $l; | |||
} | |||
/** | |||
* returns the ID of the section. It is supposed to be a lower case string, | |||
* e.g. 'ldap' | |||
* | |||
* @returns string | |||
*/ | |||
public function getID() { | |||
return 'theming'; | |||
} | |||
/** | |||
* returns the translated name as it should be displayed, e.g. 'LDAP / AD | |||
* integration'. Use the L10N service to translate it. | |||
* | |||
* @return string | |||
*/ | |||
public function getName() { | |||
return $this->l->t('Theming'); | |||
} | |||
/** | |||
* @return int whether the form should be rather on the top or bottom of | |||
* the settings navigation. The sections are arranged in ascending order of | |||
* the priority values. It is required to return a value between 0 and 99. | |||
* | |||
* E.g.: 70 | |||
*/ | |||
public function getPriority() { | |||
return 30; | |||
} | |||
/** | |||
* {@inheritdoc} | |||
*/ | |||
public function getIcon() { | |||
return $this->url->imagePath('theming', 'app-dark.svg'); | |||
} | |||
} |
@@ -26,11 +26,13 @@ namespace OCA\Theming\Tests; | |||
use OCA\Theming\Capabilities; | |||
use OCA\Theming\Controller\ThemingController; | |||
use OCA\Theming\Settings\Admin; | |||
use OCA\Theming\Settings\Section; | |||
use OCA\Theming\ThemingDefaults; | |||
use OCA\Theming\Util; | |||
use OCP\AppFramework\App; | |||
use OCP\Capabilities\ICapability; | |||
use OCP\IL10N; | |||
use OCP\Settings\ISection; | |||
use OCP\Settings\ISettings; | |||
use Test\TestCase; | |||
@@ -70,6 +72,8 @@ class ServicesTest extends TestCase { | |||
// Settings | |||
[Admin::class], | |||
[Admin::class, ISettings::class], | |||
[Section::class], | |||
[Section::class, ISection::class], | |||
]; | |||
} | |||
@@ -0,0 +1,77 @@ | |||
<?php | |||
/** | |||
* @copyright Copyright (c) 2016 Lukas Reschke <lukas@statuscode.ch> | |||
* | |||
* @author Joas Schilling <coding@schilljs.com> | |||
* @author Lukas Reschke <lukas@statuscode.ch> | |||
* | |||
* @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\Theming\Tests\Settings; | |||
use OCA\Theming\Settings\Section; | |||
use OCP\IL10N; | |||
use OCP\IURLGenerator; | |||
use Test\TestCase; | |||
class SectionTest extends TestCase { | |||
/** @var IURLGenerator|\PHPUnit_Framework_MockObject_MockObject */ | |||
private $url; | |||
/** @var IL10N|\PHPUnit_Framework_MockObject_MockObject */ | |||
private $l; | |||
/** @var Section */ | |||
private $section; | |||
public function setUp() { | |||
parent::setUp(); | |||
$this->url = $this->createMock(IURLGenerator::class); | |||
$this->l = $this->createMock(IL10N::class); | |||
$this->section = new Section( | |||
$this->url, | |||
$this->l | |||
); | |||
} | |||
public function testGetID() { | |||
$this->assertSame('theming', $this->section->getID()); | |||
} | |||
public function testGetName() { | |||
$this->l | |||
->expects($this->once()) | |||
->method('t') | |||
->with('Theming') | |||
->willReturn('Theming'); | |||
$this->assertSame('Theming', $this->section->getName()); | |||
} | |||
public function testGetPriority() { | |||
$this->assertSame(30, $this->section->getPriority()); | |||
} | |||
public function testGetIcon() { | |||
$this->url->expects($this->once()) | |||
->method('imagePath') | |||
->with('theming', 'app-dark.svg') | |||
->willReturn('icon'); | |||
$this->assertSame('icon', $this->section->getIcon()); | |||
} | |||
} |
@@ -60,11 +60,11 @@ a { | |||
* { | |||
cursor: pointer; | |||
} | |||
} | |||
&.external { | |||
margin: 0 3px; | |||
text-decoration: underline; | |||
} | |||
a.external { | |||
margin: 0 3px; | |||
text-decoration: underline; | |||
} | |||
input { |
@@ -1089,7 +1089,6 @@ return array( | |||
'OC\\Settings\\Controller\\LogSettingsController' => $baseDir . '/settings/Controller/LogSettingsController.php', | |||
'OC\\Settings\\Controller\\MailSettingsController' => $baseDir . '/settings/Controller/MailSettingsController.php', | |||
'OC\\Settings\\Controller\\PersonalSettingsController' => $baseDir . '/settings/Controller/PersonalSettingsController.php', | |||
'OC\\Settings\\Controller\\ServerInfoSettingsController' => $baseDir . '/settings/Controller/ServerInfoSettingsController.php', | |||
'OC\\Settings\\Controller\\TwoFactorSettingsController' => $baseDir . '/settings/Controller/TwoFactorSettingsController.php', | |||
'OC\\Settings\\Controller\\UsersController' => $baseDir . '/settings/Controller/UsersController.php', | |||
'OC\\Settings\\Hooks' => $baseDir . '/settings/Hooks.php', | |||
@@ -1101,7 +1100,6 @@ return array( | |||
'OC\\Settings\\Personal\\Security' => $baseDir . '/lib/private/Settings/Personal/Security.php', | |||
'OC\\Settings\\Personal\\ServerDevNotice' => $baseDir . '/lib/private/Settings/Personal/ServerDevNotice.php', | |||
'OC\\Settings\\Section' => $baseDir . '/lib/private/Settings/Section.php', | |||
'OC\\Settings\\Theming\\ServerInfo' => $baseDir . '/lib/private/Settings/Theming/ServerInfo.php', | |||
'OC\\Setup' => $baseDir . '/lib/private/Setup.php', | |||
'OC\\Setup\\AbstractDatabase' => $baseDir . '/lib/private/Setup/AbstractDatabase.php', | |||
'OC\\Setup\\MySQL' => $baseDir . '/lib/private/Setup/MySQL.php', |
@@ -1119,7 +1119,6 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c | |||
'OC\\Settings\\Controller\\LogSettingsController' => __DIR__ . '/../../..' . '/settings/Controller/LogSettingsController.php', | |||
'OC\\Settings\\Controller\\MailSettingsController' => __DIR__ . '/../../..' . '/settings/Controller/MailSettingsController.php', | |||
'OC\\Settings\\Controller\\PersonalSettingsController' => __DIR__ . '/../../..' . '/settings/Controller/PersonalSettingsController.php', | |||
'OC\\Settings\\Controller\\ServerInfoSettingsController' => __DIR__ . '/../../..' . '/settings/Controller/ServerInfoSettingsController.php', | |||
'OC\\Settings\\Controller\\TwoFactorSettingsController' => __DIR__ . '/../../..' . '/settings/Controller/TwoFactorSettingsController.php', | |||
'OC\\Settings\\Controller\\UsersController' => __DIR__ . '/../../..' . '/settings/Controller/UsersController.php', | |||
'OC\\Settings\\Hooks' => __DIR__ . '/../../..' . '/settings/Hooks.php', | |||
@@ -1131,7 +1130,6 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c | |||
'OC\\Settings\\Personal\\Security' => __DIR__ . '/../../..' . '/lib/private/Settings/Personal/Security.php', | |||
'OC\\Settings\\Personal\\ServerDevNotice' => __DIR__ . '/../../..' . '/lib/private/Settings/Personal/ServerDevNotice.php', | |||
'OC\\Settings\\Section' => __DIR__ . '/../../..' . '/lib/private/Settings/Section.php', | |||
'OC\\Settings\\Theming\\ServerInfo' => __DIR__ . '/../../..' . '/lib/private/Settings/Theming/ServerInfo.php', | |||
'OC\\Setup' => __DIR__ . '/../../..' . '/lib/private/Setup.php', | |||
'OC\\Setup\\AbstractDatabase' => __DIR__ . '/../../..' . '/lib/private/Setup/AbstractDatabase.php', | |||
'OC\\Setup\\MySQL' => __DIR__ . '/../../..' . '/lib/private/Setup/MySQL.php', |
@@ -192,7 +192,6 @@ class Manager implements IManager { | |||
1 => [new Section('server', $this->l->t('Basic settings'), 0, $this->url->imagePath('core', 'actions/settings-dark.svg'))], | |||
5 => [new Section('sharing', $this->l->t('Sharing'), 0, $this->url->imagePath('core', 'actions/share.svg'))], | |||
10 => [new Section('security', $this->l->t('Security'), 0, $this->url->imagePath('core', 'actions/password.svg'))], | |||
30 => [new Section('theming', $this->l->t('Theming'), 0, $this->url->imagePath('settings', 'theming-dark.svg'))], | |||
50 => [new Section('groupware', $this->l->t('Groupware'), 0, $this->url->imagePath('core', 'places/contacts.svg'))], | |||
98 => [new Section('additional', $this->l->t('Additional settings'), 0, $this->url->imagePath('core', 'actions/settings-dark.svg'))], | |||
]; | |||
@@ -238,10 +237,6 @@ class Manager implements IManager { | |||
$form = $this->container->query(Admin\Security::class); | |||
$forms[$form->getPriority()] = [$form]; | |||
} | |||
if ($section === 'theming') { | |||
$form = $this->container->query(Theming\ServerInfo::class); | |||
$forms[$form->getPriority()] = [$form]; | |||
} | |||
if ($section === 'sharing') { | |||
/** @var ISettings $form */ | |||
$form = $this->container->query(Admin\Sharing::class); |
@@ -26,7 +26,6 @@ | |||
namespace OC\Settings\Personal; | |||
use OC\Accounts\AccountManager; | |||
use OC\Settings\Theming\ServerInfo; | |||
use OCA\FederatedFileSharing\AppInfo\Application; | |||
use OCP\App\IAppManager; | |||
use OCP\AppFramework\Http\TemplateResponse; | |||
@@ -39,7 +38,6 @@ use OCP\IUser; | |||
use OCP\IUserManager; | |||
use OCP\L10N\IFactory; | |||
use OCP\Settings\ISettings; | |||
use OCP\Encryption\IManager as EncryptionManager; | |||
class PersonalInfo implements ISettings { | |||
@@ -57,18 +55,14 @@ class PersonalInfo implements ISettings { | |||
private $l10nFactory; | |||
/** @var IL10N */ | |||
private $l; | |||
/** @var EncryptionManager */ | |||
private $encryptionManager; | |||
/** | |||
* @param IConfig $config | |||
* @param IUserManager $userManager | |||
* @param IGroupManager $groupManager | |||
* @param AccountManager $accountManager | |||
* @param IAppManager $appManager | |||
* @param IFactory $l10nFactory | |||
* @param IL10N $l | |||
* @param EncryptionManager $encryptionManager | |||
*/ | |||
public function __construct( | |||
IConfig $config, | |||
@@ -77,8 +71,7 @@ class PersonalInfo implements ISettings { | |||
AccountManager $accountManager, | |||
IAppManager $appManager, | |||
IFactory $l10nFactory, | |||
IL10N $l, | |||
EncryptionManager $encryptionManager | |||
IL10N $l | |||
) { | |||
$this->config = $config; | |||
$this->userManager = $userManager; | |||
@@ -87,7 +80,6 @@ class PersonalInfo implements ISettings { | |||
$this->appManager = $appManager; | |||
$this->l10nFactory = $l10nFactory; | |||
$this->l = $l; | |||
$this->encryptionManager = $encryptionManager; | |||
} | |||
/** | |||
@@ -143,38 +135,10 @@ class PersonalInfo implements ISettings { | |||
'twitterScope' => $userData[AccountManager::PROPERTY_TWITTER]['scope'], | |||
'twitterVerification' => $userData[AccountManager::PROPERTY_TWITTER]['verified'], | |||
'groups' => $this->getGroups($user), | |||
] + $this->getWhereIsYourDataParams() + $messageParameters + $languageParameters + $localeParameters; | |||
] + $messageParameters + $languageParameters + $localeParameters; | |||
return new TemplateResponse('settings', 'settings/personal/personal.info', $parameters, ''); | |||
} | |||
/** | |||
* Returns the "where is your data" template params. | |||
* | |||
* @return array | |||
*/ | |||
private function getWhereIsYourDataParams(): array { | |||
$adminContactConfigId = $this->config->getSystemValue(ServerInfo::SETTING_PROVIDER_ADMIN_CONTACT); | |||
$adminContact = $this->userManager->get($adminContactConfigId); | |||
$params = [ | |||
'dataLocation' => $this->config->getSystemValue(ServerInfo::SETTING_LOCATION), | |||
'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' => $this->encryptionManager->isEnabled(), | |||
'adminName' => $adminContact !== null ? $adminContact->getDisplayName() : '', | |||
'adminMail' => $adminContact !== null ? $adminContact->getEMailAddress() : '' | |||
]; | |||
$params['show_where_is_your_data_section'] = empty($params['dataLocation']) === false | |||
|| empty($params['provider']) === false | |||
|| $params['encryptionEnabled'] === true | |||
|| empty($params['adminName']) === false; | |||
return $params; | |||
return new TemplateResponse('settings', 'settings/personal/personal.info', $parameters, ''); | |||
} | |||
/** | |||
@@ -238,7 +202,7 @@ class PersonalInfo implements ISettings { | |||
$userLang = $languages['commonlanguages'][$userLangIndex]; | |||
// search in the other languages | |||
if ($userLangIndex === false) { | |||
$userLangIndex = array_search($userConfLang, array_column($languages['languages'], 'code')); | |||
$userLangIndex = array_search($userConfLang, array_column($languages['languages'], 'code')); | |||
$userLang = $languages['languages'][$userLangIndex]; | |||
} | |||
// if user language is not available but set somehow: show the actual code as name |
@@ -1,121 +0,0 @@ | |||
<?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\Theming; | |||
use OCP\AppFramework\Http\TemplateResponse; | |||
use OCP\IConfig; | |||
use OCP\IGroupManager; | |||
use OCP\IUser; | |||
use OCP\Settings\ISettings; | |||
/** | |||
* 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(): TemplateResponse { | |||
$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(): array { | |||
$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 | |||
*/ | |||
public function getSection(): string { | |||
return 'theming'; | |||
} | |||
/** | |||
* Returns the server info settings priority. | |||
* | |||
* @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. | |||
*/ | |||
public function getPriority(): int { | |||
return 10; | |||
} | |||
} |
@@ -1,67 +0,0 @@ | |||
<?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\Theming\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 | |||
): void { | |||
$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); | |||
} | |||
} |
@@ -1,99 +0,0 @@ | |||
/* 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; | |||
} | |||
.form-input { | |||
margin-bottom: 10px; | |||
width: 100%; | |||
} | |||
.margin-bottom { | |||
margin-bottom: 15px; | |||
} | |||
.form-actions { | |||
text-align: right; | |||
.button { | |||
align-items: center; | |||
display: inline-flex; | |||
margin: 0; | |||
transition: background-color 500ms linear; | |||
.default-label, | |||
.working-label, | |||
.success-label, | |||
.error-label { | |||
align-items: center; | |||
gap: 4px; | |||
} | |||
.working-label, | |||
.success-label, | |||
.error-label { | |||
display: none; | |||
} | |||
} | |||
.button-working, | |||
.button-success, | |||
.button-error { | |||
background-color: $color-background-dark; | |||
color: $color-text-lighter; | |||
opacity: 1; | |||
.default-label { | |||
display: none; | |||
} | |||
} | |||
.button-working { | |||
.working-label { | |||
display: inline-flex; | |||
} | |||
} | |||
.button-success { | |||
background-color: $color-success; | |||
border-color: darken($color-success, 10%); | |||
color: $color-primary-text-dark; | |||
.success-label { | |||
display: inline-flex; | |||
} | |||
} | |||
.button-error { | |||
background-color: $color-error; | |||
border-color: darken($color-error, 10%); | |||
color: $color-primary-text-dark; | |||
.error-label { | |||
display: inline-flex; | |||
} | |||
} | |||
} | |||
@media (min-width: 1000px) { | |||
.label { | |||
display: inline-block; | |||
text-align: right; | |||
width: 175px; | |||
} | |||
.form-input { | |||
margin-left: 5px; | |||
width: 225px; | |||
} | |||
.form-actions { | |||
margin-left: 180px; | |||
width: 225px; | |||
} | |||
} | |||
} |
@@ -1,10 +0,0 @@ | |||
/* 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) { | |||
border-bottom: 1px dotted; | |||
} | |||
} |
@@ -2,9 +2,6 @@ | |||
This file is licensed under the Affero General Public License version 3 or later. | |||
See the COPYING-README file. */ | |||
@import "server-info"; | |||
@import "where-is-your-data"; | |||
input { | |||
&#openid, &#webdav { | |||
width: 20em; | |||
@@ -101,7 +98,6 @@ input { | |||
#personal-settings-avatar-container { | |||
display: inline-grid; | |||
grid-row: span 3; | |||
grid-template-columns: 1fr; | |||
grid-template-rows: 2fr 1fr; | |||
vertical-align: top; | |||
@@ -182,15 +178,6 @@ select { | |||
grid-template-columns: 1fr; | |||
#personal-settings-avatar-container { | |||
grid-template-rows: 1fr; | |||
// swap "Where is my data" and "Detail" | |||
*:nth-child(2) { | |||
order: 3; | |||
} | |||
*:nth-child(3) { | |||
order: 2; | |||
} | |||
} | |||
.personal-settings-container { | |||
grid-template-columns: 1fr 1fr; |
@@ -1 +0,0 @@ | |||
<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="M10.707 11.412l-.587-.587-.03-.03a.513.513 0 0 1-.074-.526L13.07 3.4l-1.5-1.498-.15.15-.708-.706.505-.505a.538.538 0 0 1 .224-.128c.04-.01.05-.01.087-.016h.087c.04.006.05.006.086.016.072.02.134.055.192.1.74.676 1.42 1.415 2.127 2.124a.503.503 0 0 1 .103.556l-3.053 6.87.344.343.49-.49 3.01 3.01a1.192 1.192 0 0 1-1.685 1.686l-3.012-3.01.49-.488zm-.533-10.217a.986.986 0 0 0-1.396 0l-7.582 7.58a.99.99 0 0 0 0 1.398l1.397 1.396a.986.986 0 0 0 1.396 0l7.58-7.583a.988.988 0 0 0 0-1.396l-1.396-1.395z" fill="#000"/></svg> |
@@ -315,107 +315,4 @@ $(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(); | |||
} | |||
}); | |||
}); | |||
}); |
@@ -83,7 +83,6 @@ $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'], | |||
] | |||
]); | |||
@@ -1,114 +0,0 @@ | |||
<?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 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 | |||
class="form-input" | |||
id="location" | |||
name="location" | |||
type="text" | |||
maxlength="100" | |||
value="<?php p($_['location']); ?>" | |||
placeholder="<?php p($l->t('country')); ?>"> | |||
</div> | |||
<div> | |||
<label class="label" for="provider"><?php p($l->t('Service provider')); ?></label> | |||
<input | |||
class="form-input" | |||
id="provider" | |||
name="provider" | |||
type="text" | |||
maxlength="100" | |||
value="<?php p($_['provider']); ?>" | |||
placeholder="<?php p($l->t('company or person')); ?>"> | |||
</div> | |||
<div> | |||
<label class="label" for="providerWebsite"><?php p($l->t('Provider website')); ?></label> | |||
<input | |||
class="form-input" | |||
id="providerWebsite" | |||
name="providerWebsite" | |||
type="url" | |||
maxlength="200" | |||
value="<?php p($_['providerWebsite']); ?>" | |||
placeholder="<?php p($l->t('link to website')); ?>"> | |||
</div> | |||
<div class="margin-bottom"> | |||
<label class="label" for="providerPrivacyLink"><?php p($l->t('Link to privacy policy')); ?></label> | |||
<input | |||
class="form-input" | |||
id="providerPrivacyLink" | |||
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="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="server-info-submit-button" class="button"> | |||
<span class="default-label"> | |||
<?php p($l->t('save')); ?> | |||
</span> | |||
<span class="working-label"> | |||
<span class="icon-loading-small-dark"></span> | |||
<?php p($l->t('saving')); ?> | |||
</span> | |||
<span class="success-label"> | |||
<span class="icon-checkmark-white"></span> | |||
<?php p($l->t('saved')); ?> | |||
</span> | |||
<span class="error-label"> | |||
<span class="icon-error-white"></span> | |||
<?php p($l->t('error saving settings')); ?> | |||
</span> | |||
</button> | |||
</div> | |||
</form> | |||
</div> |
@@ -1,76 +0,0 @@ | |||
<div class="personal-settings-setting-box personal-settings-group-box section where-is-your-data"> | |||
<h3> | |||
<?php p($l->t('Where is your data?')); ?> | |||
<a | |||
target="_blank" | |||
rel="noreferrer noopener" | |||
class="icon-info" | |||
title="" | |||
href="https://nextcloud.com/yourdata/" | |||
data-original-title="Open documentation"></a> | |||
</h3> | |||
<?php if (empty($_['dataLocation']) === false): ?> | |||
<div class="personal-info icon-address"> | |||
<p> | |||
<?php echo $l->t('Your data is located in <b>%s</b>.', [$_['dataLocation']]); ?> | |||
</p> | |||
</div> | |||
<?php endif; ?> | |||
<?php if (empty($_['provider']) === false): ?> | |||
<div class="personal-info icon-home"> | |||
<p> | |||
<?php | |||
if (empty($_['providerLink']) === false) { | |||
echo $l->t('Your provider is %s%s%s.', [ | |||
'<a href="' . $_['providerLink'] . '" target="_blank" title="" rel="noreferrer noopener">', | |||
$_['provider'], | |||
'</a>' | |||
]); | |||
} else { | |||
echo $l->t('Your provider is %s.', [$_['provider']]); | |||
} | |||
?> | |||
<?php | |||
if (empty($_['providerPrivacyLink']) === false) { | |||
echo $l->t('Read the %sprivacy policy%s now.', [ | |||
'<a href="' . $_['providerPrivacyLink'] . '" target="_blank" title="" rel="noreferrer noopener">', | |||
'</a>' | |||
]); | |||
} | |||
?> | |||
</p> | |||
</div> | |||
<?php endif; ?> | |||
<?php if ($_['encryptionEnabled'] === true): ?> | |||
<div class="personal-info icon-password"> | |||
<p> | |||
<?php echo $l->t( | |||
'Your files are encrypted with %sserver side encryption%s.', | |||
[ | |||
'<a href="https://nextcloud.com/blog/encryption-in-nextcloud/" target="_blank" title="" rel="noreferrer noopener">', | |||
'</a>' | |||
] | |||
); ?> | |||
</p> | |||
</div> | |||
<?php endif; ?> | |||
<?php if (empty($_['adminName']) === false): ?> | |||
<div class="personal-info icon-user-admin"> | |||
<p> | |||
<?php echo $l->t( | |||
'%s%s%s is your admin. If you have any issues, %scontact them%s.', | |||
[ | |||
'<a href="mailto:' . $_['adminMail'] . '" target="_blank" title="" rel="noreferrer noopener">', | |||
$_['adminName'], | |||
'</a>', | |||
'<a href="mailto:' . $_['adminMail'] . '" target="_blank" title="" rel="noreferrer noopener">', | |||
'</a>' | |||
] | |||
); ?> | |||
</p> | |||
</div> | |||
<?php endif; ?> | |||
</div> |
@@ -95,11 +95,6 @@ script('settings', [ | |||
<progress value="<?php p($_['usage_relative']); ?>" max="100"<?php if($_['usage_relative'] > 80): ?> class="warn" <?php endif; ?>></progress> | |||
</div> | |||
</div> | |||
<?php | |||
if ($_['show_where_is_your_data_section']) { | |||
include __DIR__ . '/partials/where-is-your-data.php'; | |||
} | |||
?> | |||
</div> | |||
<div class="personal-settings-container"> | |||
@@ -380,4 +375,9 @@ script('settings', [ | |||
</div> | |||
<span class="msg"></span> | |||
</div> | |||
<div id="personal-settings-group-container"> | |||
</div> | |||
</div> |
@@ -1,94 +0,0 @@ | |||
<?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\Theming\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 | |||
); | |||
} | |||
} |
@@ -72,14 +72,13 @@ class ManagerTest extends TestCase { | |||
$this->manager->registerSection('admin', \OCA\WorkflowEngine\Settings\Section::class); | |||
$this->url->expects($this->exactly(7)) | |||
$this->url->expects($this->exactly(6)) | |||
->method('imagePath') | |||
->willReturnMap([ | |||
['settings', 'admin.svg', '0'], | |||
['core', 'actions/settings-dark.svg', '1'], | |||
['core', 'actions/share.svg', '2'], | |||
['core', 'actions/password.svg', '3'], | |||
['settings', 'theming-dark.svg', '6'], | |||
['core', 'places/contacts.svg', '5'], | |||
['settings', 'help.svg', '4'], | |||
]); | |||
@@ -89,7 +88,6 @@ class ManagerTest extends TestCase { | |||
1 => [new Section('server', 'Basic settings', 0, '1')], | |||
5 => [new Section('sharing', 'Sharing', 0, '2')], | |||
10 => [new Section('security', 'Security', 0, '3')], | |||
30 => [new Section('theming', 'Theming', 0, '6')], | |||
50 => [new Section('groupware', 'Groupware', 0, '5')], | |||
55 => [\OC::$server->query(\OCA\WorkflowEngine\Settings\Section::class)], | |||
98 => [new Section('additional', 'Additional settings', 0, '1')], | |||
@@ -126,14 +124,13 @@ class ManagerTest extends TestCase { | |||
->method('t') | |||
->will($this->returnArgument(0)); | |||
$this->url->expects($this->exactly(7)) | |||
$this->url->expects($this->exactly(6)) | |||
->method('imagePath') | |||
->willReturnMap([ | |||
['settings', 'admin.svg', '0'], | |||
['core', 'actions/settings-dark.svg', '1'], | |||
['core', 'actions/share.svg', '2'], | |||
['core', 'actions/password.svg', '3'], | |||
['settings', 'theming-dark.svg', '6'], | |||
['core', 'places/contacts.svg', '5'], | |||
['settings', 'help.svg', '4'], | |||
]); | |||
@@ -143,7 +140,6 @@ class ManagerTest extends TestCase { | |||
1 => [new Section('server', 'Basic settings', 0, '1')], | |||
5 => [new Section('sharing', 'Sharing', 0, '2')], | |||
10 => [new Section('security', 'Security', 0, '3')], | |||
30 => [new Section('theming', 'Theming', 0, '6')], | |||
50 => [new Section('groupware', 'Groupware', 0, '5')], | |||
98 => [new Section('additional', 'Additional settings', 0, '1')], | |||
], $this->manager->getAdminSections()); | |||
@@ -213,7 +209,7 @@ class ManagerTest extends TestCase { | |||
$this->manager->registerSection('personal', \OCA\WorkflowEngine\Settings\Section::class); | |||
$this->manager->registerSection('admin', \OCA\WorkflowEngine\Settings\Section::class); | |||
$this->url->expects($this->exactly(10)) | |||
$this->url->expects($this->exactly(9)) | |||
->method('imagePath') | |||
->willReturnMap([ | |||
['core', 'actions/info.svg', '1'], | |||
@@ -223,7 +219,6 @@ class ManagerTest extends TestCase { | |||
['core', 'actions/settings-dark.svg', '1'], | |||
['core', 'actions/share.svg', '2'], | |||
['core', 'actions/password.svg', '3'], | |||
['settings', 'theming-dark.svg', '6'], | |||
['core', 'places/contacts.svg', '5'], | |||
['settings', 'help.svg', '4'], | |||
]); | |||
@@ -240,7 +235,6 @@ class ManagerTest extends TestCase { | |||
1 => [new Section('server', 'Basic settings', 0, '1')], | |||
5 => [new Section('sharing', 'Sharing', 0, '2')], | |||
10 => [new Section('security', 'Security', 0, '3')], | |||
30 => [new Section('theming', 'Theming', 0, '6')], | |||
50 => [new Section('groupware', 'Groupware', 0, '5')], | |||
55 => [\OC::$server->query(\OCA\WorkflowEngine\Settings\Section::class)], | |||
98 => [new Section('additional', 'Additional settings', 0, '1')], |