diff options
Diffstat (limited to 'apps/settings/lib/Controller/CommonSettingsTrait.php')
-rw-r--r-- | apps/settings/lib/Controller/CommonSettingsTrait.php | 133 |
1 files changed, 82 insertions, 51 deletions
diff --git a/apps/settings/lib/Controller/CommonSettingsTrait.php b/apps/settings/lib/Controller/CommonSettingsTrait.php index 8ca62b9d1b3..75d2b1f2f9e 100644 --- a/apps/settings/lib/Controller/CommonSettingsTrait.php +++ b/apps/settings/lib/Controller/CommonSettingsTrait.php @@ -1,42 +1,32 @@ <?php + /** - * @copyright Copyright (c) 2017 Arthur Schiwon <blizzz@arthur-schiwon.de> - * - * @author Arthur Schiwon <blizzz@arthur-schiwon.de> - * @author Christoph Wurst <christoph@winzerhof-wurst.at> - * @author Joas Schilling <coding@schilljs.com> - * @author Julius Härtl <jus@bitgrid.net> - * @author Morris Jobke <hey@morrisjobke.de> - * @author Robin Appelman <robin@icewind.nl> - * @author Roeland Jago Douma <roeland@famdouma.nl> - * - * @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/>. - * + * SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later */ + namespace OCA\Settings\Controller; +use InvalidArgumentException; +use OC\AppFramework\Middleware\Security\Exceptions\NotAdminException; +use OCA\Settings\AppInfo\Application; use OCP\AppFramework\Http\TemplateResponse; +use OCP\AppFramework\Services\IInitialState; use OCP\Group\ISubAdmin; use OCP\IGroupManager; use OCP\INavigationManager; use OCP\IUserSession; +use OCP\Settings\IDeclarativeManager; +use OCP\Settings\IDeclarativeSettingsForm; use OCP\Settings\IIconSection; use OCP\Settings\IManager as ISettingsManager; use OCP\Settings\ISettings; +use OCP\Util; +/** + * @psalm-import-type DeclarativeSettingsFormSchemaWithValues from IDeclarativeSettingsForm + * @psalm-import-type DeclarativeSettingsFormSchemaWithoutValues from IDeclarativeSettingsForm + */ trait CommonSettingsTrait { /** @var ISettingsManager */ @@ -54,28 +44,26 @@ trait CommonSettingsTrait { /** @var ISubAdmin */ private $subAdmin; + private IDeclarativeManager $declarativeSettingsManager; + + /** @var IInitialState */ + private $initialState; + /** * @return array{forms: array{personal: array, admin: array}} */ private function getNavigationParameters(string $currentType, string $currentSection): array { - $templateParameters = [ - 'personal' => $this->formatPersonalSections($currentType, $currentSection), - 'admin' => [] - ]; - - $templateParameters['admin'] = $this->formatAdminSections( - $currentType, - $currentSection - ); - return [ - 'forms' => $templateParameters + 'forms' => [ + 'personal' => $this->formatPersonalSections($currentType, $currentSection), + 'admin' => $this->formatAdminSections($currentType, $currentSection), + ], ]; } /** * @param IIconSection[][] $sections - * @psam-param 'admin'|'personal' $type + * @psalm-param 'admin'|'personal' $type * @return list<array{anchor: string, section-name: string, active: bool, icon: string}> */ protected function formatSections(array $sections, string $currentSection, string $type, string $currentType): array { @@ -87,7 +75,11 @@ trait CommonSettingsTrait { } elseif ($type === 'personal') { $settings = $this->settingsManager->getPersonalSettings($section->getID()); } - if (empty($settings) && !($section->getID() === 'additional' && count(\OC_App::getForms('admin')) > 0)) { + + /** @psalm-suppress PossiblyNullArgument */ + $declarativeFormIDs = $this->declarativeSettingsManager->getFormIDs($this->userSession->getUser(), $type, $section->getID()); + + if (empty($settings) && empty($declarativeFormIDs)) { continue; } @@ -107,54 +99,93 @@ trait CommonSettingsTrait { return $templateParameters; } - protected function formatPersonalSections(string $currentType, string $currentSections): array { + protected function formatPersonalSections(string $currentType, string $currentSection): array { $sections = $this->settingsManager->getPersonalSections(); - return $this->formatSections($sections, $currentSections, 'personal', $currentType); + return $this->formatSections($sections, $currentSection, 'personal', $currentType); } - protected function formatAdminSections(string $currentType, string $currentSections): array { + protected function formatAdminSections(string $currentType, string $currentSection): array { $sections = $this->settingsManager->getAdminSections(); - return $this->formatSections($sections, $currentSections, 'admin', $currentType); + return $this->formatSections($sections, $currentSection, 'admin', $currentType); } /** - * @param array<int, list<\OCP\Settings\ISettings>> $settings + * @param list<ISettings> $settings + * @param list<DeclarativeSettingsFormSchemaWithValues> $declarativeSettings * @return array{content: string} */ - private function formatSettings(array $settings): array { + private function formatSettings(array $settings, array $declarativeSettings): array { + $settings = array_merge($settings, $declarativeSettings); + + usort($settings, function ($first, $second) { + $priorityOne = $first instanceof ISettings ? $first->getPriority() : $first['priority']; + $priorityTwo = $second instanceof ISettings ? $second->getPriority() : $second['priority']; + return $priorityOne - $priorityTwo; + }); + $html = ''; - foreach ($settings as $prioritizedSettings) { - foreach ($prioritizedSettings as $setting) { - /** @var ISettings $setting */ + foreach ($settings as $setting) { + if ($setting instanceof ISettings) { $form = $setting->getForm(); $html .= $form->renderAs('')->render(); + } else { + $html .= '<div id="' . $setting['app'] . '_' . $setting['id'] . '"></div>'; } } return ['content' => $html]; } + /** + * @psalm-param 'admin'|'personal' $type + */ private function getIndexResponse(string $type, string $section): TemplateResponse { + $user = $this->userSession->getUser(); + assert($user !== null, 'No user logged in for settings'); + + $this->declarativeSettingsManager->loadSchemas(); + $declarativeSettings = $this->declarativeSettingsManager->getFormsWithValues($user, $type, $section); + + foreach ($declarativeSettings as &$form) { + foreach ($form['fields'] as &$field) { + if (isset($field['sensitive']) && $field['sensitive'] === true && !empty($field['value'])) { + $field['value'] = 'dummySecret'; + } + } + } + if ($type === 'personal') { + $settings = array_values($this->settingsManager->getPersonalSettings($section)); if ($section === 'theming') { $this->navigationManager->setActiveEntry('accessibility_settings'); } else { $this->navigationManager->setActiveEntry('settings'); } } elseif ($type === 'admin') { + $settings = array_values($this->settingsManager->getAllowedAdminSettings($section, $user)); + if (empty($settings) && empty($declarativeSettings)) { + throw new NotAdminException('Logged in user does not have permission to access these settings.'); + } $this->navigationManager->setActiveEntry('admin_settings'); + } else { + throw new InvalidArgumentException('$type must be either "admin" or "personal"'); + } + + if (!empty($declarativeSettings)) { + Util::addScript(Application::APP_ID, 'declarative-settings-forms'); + $this->initialState->provideInitialState('declarative-settings-forms', $declarativeSettings); } - $templateParams = []; + $settings = array_merge(...$settings); + $templateParams = $this->formatSettings($settings, $declarativeSettings); $templateParams = array_merge($templateParams, $this->getNavigationParameters($type, $section)); - $templateParams = array_merge($templateParams, $this->getSettings($section)); + $activeSection = $this->settingsManager->getSection($type, $section); if ($activeSection) { $templateParams['pageTitle'] = $activeSection->getName(); $templateParams['activeSectionId'] = $activeSection->getID(); + $templateParams['activeSectionType'] = $type; } return new TemplateResponse('settings', 'settings/frame', $templateParams); } - - abstract protected function getSettings($section); } |