From 247b305b79e16ef1e26b374a4efed7e44c241e91 Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Tue, 16 May 2017 01:38:12 +0200 Subject: [PATCH 01/42] add route and controller. consolidate common settings functions in a trait. Signed-off-by: Arthur Schiwon --- .../Controller/AdminSettingsController.php | 56 +------- settings/Controller/CommonSettingsTrait.php | 123 ++++++++++++++++++ .../Controller/PersonalSettingsController.php | 73 +++++++++++ settings/routes.php | 3 +- 4 files changed, 204 insertions(+), 51 deletions(-) create mode 100644 settings/Controller/CommonSettingsTrait.php create mode 100644 settings/Controller/PersonalSettingsController.php diff --git a/settings/Controller/AdminSettingsController.php b/settings/Controller/AdminSettingsController.php index 6c915be6f9..fb8b65d93a 100644 --- a/settings/Controller/AdminSettingsController.php +++ b/settings/Controller/AdminSettingsController.php @@ -28,15 +28,15 @@ use OCP\AppFramework\Controller; use OCP\AppFramework\Http\TemplateResponse; use OCP\INavigationManager; use OCP\IRequest; -use OCP\Settings\IIconSection; use OCP\Settings\IManager as ISettingsManager; -use OCP\Settings\ISection; use OCP\Template; /** * @package OC\Settings\Controller */ class AdminSettingsController extends Controller { + use CommonSettingsTrait; + /** @var INavigationManager */ private $navigationManager; /** @var ISettingsManager */ @@ -67,12 +67,7 @@ class AdminSettingsController extends Controller { */ public function index($section) { $this->navigationManager->setActiveEntry('admin'); - - $templateParams = []; - $templateParams = array_merge($templateParams, $this->getNavigationParameters($section)); - $templateParams = array_merge($templateParams, $this->getSettings($section)); - - return new TemplateResponse('settings', 'admin/frame', $templateParams); + return $this->getIndexResponse($section); } /** @@ -80,19 +75,13 @@ class AdminSettingsController extends Controller { * @return array */ private function getSettings($section) { - $html = ''; + // PhpStorm shows this as unused, but is required by CommonSettingsTrait $settings = $this->settingsManager->getAdminSettings($section); - foreach ($settings as $prioritizedSettings) { - foreach ($prioritizedSettings as $setting) { - /** @var \OCP\Settings\ISettings $setting */ - $form = $setting->getForm(); - $html .= $form->renderAs('')->render(); - } - } + $formatted = $this->formatSettings($settings); if($section === 'additional') { - $html .= $this->getLegacyForms(); + $formatted['content'] .= $this->getLegacyForms(); } - return ['content' => $html]; + return $formatted; } /** @@ -125,36 +114,5 @@ class AdminSettingsController extends Controller { return $out->fetchPage(); } - /** - * @param string $currentSection - * @return array - */ - private function getNavigationParameters($currentSection) { - $sections = $this->settingsManager->getAdminSections(); - $templateParameters = []; - /** @var \OC\Settings\Section[] $prioritizedSections */ - foreach($sections as $prioritizedSections) { - foreach ($prioritizedSections as $section) { - if (empty($this->settingsManager->getAdminSettings($section->getID()))) { - continue; - } - $icon = ''; - if ($section instanceof IIconSection) { - $icon = $section->getIcon(); - } - - $templateParameters[] = [ - 'anchor' => $section->getID(), - 'section-name' => $section->getName(), - 'active' => $section->getID() === $currentSection, - 'icon' => $icon, - ]; - } - } - - return [ - 'forms' => $templateParameters - ]; - } } diff --git a/settings/Controller/CommonSettingsTrait.php b/settings/Controller/CommonSettingsTrait.php new file mode 100644 index 0000000000..66ffabd84d --- /dev/null +++ b/settings/Controller/CommonSettingsTrait.php @@ -0,0 +1,123 @@ + + * + * @author Arthur Schiwon + * + * @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 OC\Settings\Controller; + +use OCP\AppFramework\Http\TemplateResponse; +use OCP\Settings\IManager as ISettingsManager; +use OCP\Settings\IIconSection; +use OCP\Settings\ISettings; + +trait CommonSettingsTrait { + /** @var ISettingsManager */ + private $settingsManager; + + /** + * @param string $currentSection + * @return array + */ + private function getNavigationParameters($currentSection) { + $templateParameters = [ + 'personal' => $this->formatPersonalSections($currentSection), + 'admin' => [] + ]; + + if(\OC_User::isAdminUser(\OC_User::getUser())) { + $templateParameters['admin'] = $this->formatAdminSections($currentSection); + } + + return [ + 'forms' => $templateParameters + ]; + } + + protected function formatSections($sections, $currentSection, $type) { + $templateParameters = []; + /** @var \OCP\Settings\ISection[] $prioritizedSections */ + foreach($sections as $prioritizedSections) { + foreach ($prioritizedSections as $section) { + if($type === 'admin') { + $settings = $this->settingsManager->getAdminSettings($section->getID()); + } else if($type === 'personal') { + $settings = $this->settingsManager->getPersonalSettings($section->getID()); + } + if (empty($settings)) { + continue; + } + + $icon = ''; + if ($section instanceof IIconSection) { + $icon = $section->getIcon(); + } + + $templateParameters[] = [ + 'anchor' => $section->getID(), + 'section-name' => $section->getName(), + 'active' => $section->getID() === $currentSection, + 'icon' => $icon, + ]; + } + } + return $templateParameters; + } + + protected function formatPersonalSections($currentSections) { + $sections = $this->settingsManager->getPersonalSections(); + $templateParameters = $this->formatSections($sections, $currentSections, 'personal'); + + return $templateParameters; + } + + protected function formatAdminSections($currentSections) { + $sections = $this->settingsManager->getAdminSections(); + $templateParameters = $this->formatSections($sections, $currentSections, 'admin'); + + return $templateParameters; + } + + /** + * @param ISettings[] $settings + * @return array + */ + private function formatSettings($settings) { + $html = ''; + foreach ($settings as $prioritizedSettings) { + foreach ($prioritizedSettings as $setting) { + /** @var \OCP\Settings\ISettings $setting */ + $form = $setting->getForm(); + $html .= $form->renderAs('')->render(); + } + } + return ['content' => $html]; + } + + private function getIndexResponse($section) { + $templateParams = []; + $templateParams = array_merge($templateParams, $this->getNavigationParameters($section)); + $templateParams = array_merge($templateParams, $this->getSettings($section)); + + return new TemplateResponse('settings', 'settings/frame', $templateParams); + } + + abstract public function getSettings($section); +} diff --git a/settings/Controller/PersonalSettingsController.php b/settings/Controller/PersonalSettingsController.php new file mode 100644 index 0000000000..546af54a7f --- /dev/null +++ b/settings/Controller/PersonalSettingsController.php @@ -0,0 +1,73 @@ + + * + * @author Arthur Schiwon + * + * @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 OC\Settings\Controller; + +use OCP\AppFramework\Controller; +use OCP\AppFramework\Http\TemplateResponse; +use OCP\INavigationManager; +use OCP\IRequest; +use OCP\Settings\IManager as ISettingsManager; + +class PersonalSettingsController extends Controller { + use CommonSettingsTrait { + getSettings as private; + } + + /** @var INavigationManager */ + private $navigationManager; + + public function __construct( + $appName, + IRequest $request, + INavigationManager $navigationManager, + ISettingsManager $settingsManager + ) { + parent::__construct($appName, $request); + $this->navigationManager = $navigationManager; + $this->settingsManager = $settingsManager; + } + + /** + * @param string $section + * @return TemplateResponse + * + * @NoCSRFRequired + * @NoAdminRequired + * @NoSubadminRequired + */ + public function index($section) { + $this->navigationManager->setActiveEntry('personal'); + return $this->getIndexResponse($section); + } + + /** + * @param string $section + * @return array + */ + private function getSettings($section) { + // PhpStorm shows this as unused, but is required by CommonSettingsTrait + $settings = $this->settingsManager->getPersonalSettings($section); + return $this->formatSettings($settings); + } +} diff --git a/settings/routes.php b/settings/routes.php index 048febaa12..52523ff50c 100644 --- a/settings/routes.php +++ b/settings/routes.php @@ -65,6 +65,7 @@ $application->registerRoutes($this, [ ['name' => 'Certificate#removePersonalRootCertificate', 'url' => '/settings/personal/certificate/{certificateIdentifier}', 'verb' => 'DELETE'], ['name' => 'Certificate#addSystemRootCertificate', 'url' => '/settings/admin/certificate', 'verb' => 'POST'], ['name' => 'Certificate#removeSystemRootCertificate', 'url' => '/settings/admin/certificate/{certificateIdentifier}', 'verb' => 'DELETE'], + ['name' => 'PersonalSettings#index', 'url' => '/settings/personal/{section}', 'verb' => 'GET', 'defaults' => ['section' => 'personal-info']], ['name' => 'AdminSettings#index', 'url' => '/settings/admin/{section}', 'verb' => 'GET', 'defaults' => ['section' => 'server']], ['name' => 'AdminSettings#form', 'url' => '/settings/admin/{section}', 'verb' => 'GET'], ['name' => 'ChangePassword#changePersonalPassword', 'url' => '/settings/personal/changepassword', 'verb' => 'POST'], @@ -82,8 +83,6 @@ $application->registerRoutes($this, [ // Settings pages $this->create('settings_help', '/settings/help') ->actionInclude('settings/help.php'); -$this->create('settings_personal', '/settings/personal') - ->actionInclude('settings/personal.php'); $this->create('settings_users', '/settings/users') ->actionInclude('settings/users.php'); // Settings ajax actions From 560ab2e91158fa57b12cb5f382dfd79cbbc1ffc4 Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Tue, 16 May 2017 01:40:10 +0200 Subject: [PATCH 02/42] one settings link, common template, styling Signed-off-by: Arthur Schiwon --- lib/private/NavigationManager.php | 20 +++--------- settings/css/settings.css | 8 +++++ .../templates/{admin => settings}/frame.php | 32 ++++++++++++++++++- 3 files changed, 43 insertions(+), 17 deletions(-) rename settings/templates/{admin => settings}/frame.php (65%) diff --git a/lib/private/NavigationManager.php b/lib/private/NavigationManager.php index 300c24ff94..e0b83fe5e4 100644 --- a/lib/private/NavigationManager.php +++ b/lib/private/NavigationManager.php @@ -177,14 +177,14 @@ class NavigationManager implements INavigationManager { ]); } - // Personal settings + // Personal and (if applicable) admin settings $this->add([ 'type' => 'settings', - 'id' => 'personal', + 'id' => 'settings', 'order' => 1, 'href' => $this->urlGenerator->linkToRoute('settings_personal'), - 'name' => $l->t('Personal'), - 'icon' => $this->urlGenerator->imagePath('settings', 'personal.svg'), + 'name' => $l->t('Settings'), + 'icon' => $this->urlGenerator->imagePath('settings', 'admin.svg'), ]); // Logout @@ -211,18 +211,6 @@ class NavigationManager implements INavigationManager { 'icon' => $this->urlGenerator->imagePath('settings', 'users.svg'), ]); } - - if ($this->isAdmin()) { - // Admin settings - $this->add([ - 'type' => 'settings', - 'id' => 'admin', - 'order' => 2, - 'href' => $this->urlGenerator->linkToRoute('settings.AdminSettings.index'), - 'name' => $l->t('Admin'), - 'icon' => $this->urlGenerator->imagePath('settings', 'admin.svg'), - ]); - } } if ($this->appManager === 'null') { diff --git a/settings/css/settings.css b/settings/css/settings.css index 0d68a3b622..4786af4733 100644 --- a/settings/css/settings.css +++ b/settings/css/settings.css @@ -1296,3 +1296,11 @@ doesnotexist:-o-prefocus, .strengthify-wrapper { margin-bottom: 12px; opacity: .7; } + +.settings-caption { + font-weight: bold; + line-height: 44px; + padding: 0 12px; + white-space: nowrap; + text-overflow: ellipsis; +} diff --git a/settings/templates/admin/frame.php b/settings/templates/settings/frame.php similarity index 65% rename from settings/templates/admin/frame.php rename to settings/templates/settings/frame.php index 2b234f4cd9..80737bc6f9 100644 --- a/settings/templates/admin/frame.php +++ b/settings/templates/settings/frame.php @@ -30,9 +30,39 @@ script('files', 'jquery.fileupload');
    +
  • Personal
  • getURLGenerator()->linkToRoute('settings.PersonalSettings.index', ['section' => $form['anchor']]); + $class = 'nav-icon-' . $form['anchor']; + $sectionName = $form['section-name']; + $active = $form['active'] ? ' class="active"' : ''; + ?> +
  • > + + + + + + + + +
  • + + + +
  • Administration
  • + getURLGenerator()->linkToRoute('settings.AdminSettings.index', ['section' => $form['anchor']]); $class = 'nav-icon-' . $form['anchor']; $sectionName = $form['section-name']; From b68fdb473d03878911b0874a75564c8a7f08d03d Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Tue, 16 May 2017 01:40:36 +0200 Subject: [PATCH 03/42] Extend interfaces Signed-off-by: Arthur Schiwon --- lib/private/Settings/Manager.php | 36 ++++++++++++++++++++++++++++++++ lib/public/Settings/IManager.php | 17 +++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/lib/private/Settings/Manager.php b/lib/private/Settings/Manager.php index d40dfd1e41..a307261c83 100644 --- a/lib/private/Settings/Manager.php +++ b/lib/private/Settings/Manager.php @@ -337,6 +337,24 @@ class Manager implements IManager { return $forms; } + /** + * @param string $section + * @return ISection[] + */ + private function getBuiltInPersonalSettings($section) { + $forms = []; + try { + if ($section === 'personal-info') { + /** @var ISettings $form */ + $form = new Personal\PersonalInfo(); + $forms[$form->getPriority()] = [$form]; + } + } catch (QueryException $e) { + // skip + } + return $forms; + } + /** * @inheritdoc */ @@ -358,4 +376,22 @@ class Manager implements IManager { ksort($settings); return $settings; } + + /** + * @inheritdoc + */ + public function getPersonalSections() { + $sections = [ + 0 => [new Section('personal-info', $this->l->t('Personal info'), 0, $this->url->imagePath('core', 'actions/info.svg'))], + ]; + return $sections; + } + + /** + * @inheritdoc + */ + public function getPersonalSettings($section) { + $settings = $this->getBuiltInPersonalSettings($section); + return $settings; + } } diff --git a/lib/public/Settings/IManager.php b/lib/public/Settings/IManager.php index a406915ad0..2c99239926 100644 --- a/lib/public/Settings/IManager.php +++ b/lib/public/Settings/IManager.php @@ -87,6 +87,14 @@ interface IManager { */ public function getAdminSections(); + /** + * returns a list of the personal sections + * + * @return array array of ISection[] where key is the priority + * @since 12.0.0 + */ + public function getPersonalSections(); + /** * returns a list of the admin settings * @@ -95,4 +103,13 @@ interface IManager { * @since 9.1.0 */ public function getAdminSettings($section); + + /** + * returns a list of the personal settings + * + * @param string $section the section id for which to load the settings + * @return array array of IPersonal[] where key is the priority + * @since 12.0.0 + */ + public function getPersonalSettings($section); } From 039ee7e3aa33284999526a15231ddd0b676c81bd Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Tue, 16 May 2017 01:41:17 +0200 Subject: [PATCH 04/42] brief, incomplete personal info settings implementation Signed-off-by: Arthur Schiwon --- .../Settings/Personal/PersonalInfo.php | 59 ++++ .../settings/personal/personal.info.php | 324 ++++++++++++++++++ 2 files changed, 383 insertions(+) create mode 100644 lib/private/Settings/Personal/PersonalInfo.php create mode 100644 settings/templates/settings/personal/personal.info.php diff --git a/lib/private/Settings/Personal/PersonalInfo.php b/lib/private/Settings/Personal/PersonalInfo.php new file mode 100644 index 0000000000..6815b7390b --- /dev/null +++ b/lib/private/Settings/Personal/PersonalInfo.php @@ -0,0 +1,59 @@ + + * + * @author Arthur Schiwon + * + * @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 OC\Settings\Personal; + +use OCP\AppFramework\Http\TemplateResponse; +use OCP\Settings\ISettings; + +class PersonalInfo implements ISettings { + + /** + * @return TemplateResponse returns the instance with all parameters set, ready to be rendered + * @since 9.1 + */ + public function getForm() { + return new TemplateResponse('settings', 'settings/personal/personal.info'); + } + + /** + * @return string the section ID, e.g. 'sharing' + * @since 9.1 + */ + public function getSection() { + return 'personal-info'; + } + + /** + * @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. + * + * E.g.: 70 + * @since 9.1 + */ + public function getPriority() { + return 10; + } +} diff --git a/settings/templates/settings/personal/personal.info.php b/settings/templates/settings/personal/personal.info.php new file mode 100644 index 0000000000..7a19752912 --- /dev/null +++ b/settings/templates/settings/personal/personal.info.php @@ -0,0 +1,324 @@ + + * + * @author Arthur Schiwon + * + * @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 . + * + */ + +/** @var \OCP\IL10N $l */ +/** @var array $_ */ + +?> + +
    +
    +
    +

    + + +

    +
    +
    + + + +
    + + +

    t('png or jpg, max. 20 MB')); ?>

    + + t('Picture provided by original account')); ?> + +
    + + +
    + +
    +
    +
    +

    + + +

    + + value="" + autocomplete="on" autocapitalize="none" autocorrect="off" /> + + t('No display name set')); } ?> + +
    +
    +
    +

    + + +

    +
    + +
    + + placeholder="t('Your email address')); ?>" + autocomplete="on" autocapitalize="none" autocorrect="off" /> + + t('No email address set')); }?> + + +
    + t('For password reset and notifications')); ?> + +
    + +
    +
    +

    + + +

    + +
    +
    +
    +

    + + +

    + +
    +
    +
    +

    + + +

    +
    + + > + +
    + +
    +
    +
    +

    + + +

    +
    + + > + +
    + +
    + + +
    +
    + +
    +

    t('Groups')); ?>

    +

    t('You are member of the following groups:')); ?>

    +

    + +

    +
    + + +
    +

    t('Password'));?>

    + +
    + + +
    + + + +
    + +
    +
    + + +
    +

    + +

    + + + t('Help translate'));?> + +
    + + +
    +

    t('Get the apps to sync your files'));?>

    + + <?php p($l->t('Desktop client'));?> + + + <?php p($l->t('Android app'));?> + + + <?php p($l->t('iOS app'));?> + + +

    + ', + '', + ], + $l->t('If you want to support the project {contributeopen}join development{linkclose} or {contributeopen}spread the word{linkclose}!'))); ?> +

    + + +

    t('Show First Run Wizard again'));?>

    + +
    + + From 045f652ef2844e3917b4ae7f3bbb5abb3422d02b Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Tue, 16 May 2017 02:46:42 +0200 Subject: [PATCH 05/42] completing PersonalInfo Signed-off-by: Arthur Schiwon --- lib/private/Server.php | 7 +- lib/private/Settings/Manager.php | 26 +- lib/private/Settings/Mapper.php | 8 +- .../Settings/Personal/PersonalInfo.php | 149 ++++++- settings/js/settings/personalInfo.js | 392 ++++++++++++++++++ settings/routes.php | 2 +- .../settings/personal/personal.info.php | 16 + 7 files changed, 591 insertions(+), 9 deletions(-) create mode 100644 settings/js/settings/personalInfo.js diff --git a/lib/private/Server.php b/lib/private/Server.php index 489683aa12..262f9f00a7 100644 --- a/lib/private/Server.php +++ b/lib/private/Server.php @@ -42,6 +42,7 @@ namespace OC; use bantu\IniGetWrapper\IniGetWrapper; +use OC\Accounts\AccountManager; use OC\App\AppManager; use OC\App\AppStore\Bundles\BundleFetcher; use OC\App\AppStore\Fetcher\AppFetcher; @@ -970,7 +971,11 @@ class Server extends ServerContainer implements IServerContainer { $c->getLockingProvider(), $c->getRequest(), new \OC\Settings\Mapper($c->getDatabaseConnection()), - $c->getURLGenerator() + $c->getURLGenerator(), + $c->query(AccountManager::class), + $c->getGroupManager(), + $c->getL10NFactory(), + $c->getThemingDefaults() ); return $manager; }); diff --git a/lib/private/Settings/Manager.php b/lib/private/Settings/Manager.php index a307261c83..d6b3398d0f 100644 --- a/lib/private/Settings/Manager.php +++ b/lib/private/Settings/Manager.php @@ -23,15 +23,18 @@ namespace OC\Settings; +use OC\Accounts\AccountManager; use OCP\AppFramework\QueryException; use OCP\Encryption\IManager as EncryptionManager; use OCP\IConfig; use OCP\IDBConnection; +use OCP\IGroupManager; use OCP\IL10N; use OCP\ILogger; use OCP\IRequest; use OCP\IURLGenerator; use OCP\IUserManager; +use OCP\L10N\IFactory; use OCP\Lock\ILockingProvider; use OCP\Settings\ISettings; use OCP\Settings\IManager; @@ -61,6 +64,14 @@ class Manager implements IManager { private $request; /** @var IURLGenerator */ private $url; + /** @var AccountManager */ + private $accountManager; + /** @var IGroupManager */ + private $groupManager; + /** @var IFactory */ + private $l10nFactory; + /** @var \OC_Defaults */ + private $defaults; /** * @param ILogger $log @@ -73,6 +84,9 @@ class Manager implements IManager { * @param IRequest $request * @param Mapper $mapper * @param IURLGenerator $url + * @param AccountManager $accountManager + * @param IGroupManager $groupManager + * @param IFactory $l10nFactory */ public function __construct( ILogger $log, @@ -84,7 +98,11 @@ class Manager implements IManager { ILockingProvider $lockingProvider, IRequest $request, Mapper $mapper, - IURLGenerator $url + IURLGenerator $url, + AccountManager $accountManager, + IGroupManager $groupManager, + IFactory $l10nFactory, + \OC_Defaults $defaults ) { $this->log = $log; $this->dbc = $dbc; @@ -96,6 +114,10 @@ class Manager implements IManager { $this->lockingProvider = $lockingProvider; $this->request = $request; $this->url = $url; + $this->accountManager = $accountManager; + $this->groupManager = $groupManager; + $this->l10nFactory = $l10nFactory; + $this->defaults = $defaults; } /** @@ -346,7 +368,7 @@ class Manager implements IManager { try { if ($section === 'personal-info') { /** @var ISettings $form */ - $form = new Personal\PersonalInfo(); + $form = new Personal\PersonalInfo($this->config, $this->userManager, $this->groupManager, $this->accountManager, $this->l10nFactory, $this->defaults); $forms[$form->getPriority()] = [$form]; } } catch (QueryException $e) { diff --git a/lib/private/Settings/Mapper.php b/lib/private/Settings/Mapper.php index 2525f2c985..7dea1fe3d8 100644 --- a/lib/private/Settings/Mapper.php +++ b/lib/private/Settings/Mapper.php @@ -143,10 +143,10 @@ class Mapper { } /** - * @param $table Mapper::TABLE_ADMIN_SECTIONS or Mapper::TABLE_ADMIN_SETTINGS - * @param $idCol - * @param $id - * @param $values + * @param string $table Mapper::TABLE_ADMIN_SECTIONS or Mapper::TABLE_ADMIN_SETTINGS + * @param string $idCol + * @param string $id + * @param array $values */ public function update($table, $idCol, $id, $values) { $query = $this->dbc->getQueryBuilder(); diff --git a/lib/private/Settings/Personal/PersonalInfo.php b/lib/private/Settings/Personal/PersonalInfo.php index 6815b7390b..c1b2e8acc7 100644 --- a/lib/private/Settings/Personal/PersonalInfo.php +++ b/lib/private/Settings/Personal/PersonalInfo.php @@ -24,17 +24,108 @@ namespace OC\Settings\Personal; +use OC\Accounts\AccountManager; use OCP\AppFramework\Http\TemplateResponse; +use OCP\IConfig; +use OCP\IGroupManager; +use OCP\IUser; +use OCP\IUserManager; +use OCP\L10N\IFactory; use OCP\Settings\ISettings; class PersonalInfo implements ISettings { + /** @var IConfig */ + private $config; + /** @var IUserManager */ + private $userManager; + /** @var AccountManager */ + private $accountManager; + /** @var IGroupManager */ + private $groupManager; + /** @var IFactory */ + private $l10nFactory; + + const COMMON_LANGUAGE_CODES = [ + 'en', 'es', 'fr', 'de', 'de_DE', 'ja', 'ar', 'ru', 'nl', 'it', + 'pt_BR', 'pt_PT', 'da', 'fi_FI', 'nb_NO', 'sv', 'tr', 'zh_CN', 'ko' + ]; + /** @var \OC_Defaults */ + private $defaults; + + /** + * @param IConfig $config + * @param IUserManager $userManager + * @param IGroupManager $groupManager + * @param AccountManager $accountManager + * @param IFactory $l10nFactory + */ + public function __construct( + IConfig $config, + IUserManager $userManager, + IGroupManager $groupManager, + AccountManager $accountManager, + IFactory $l10nFactory, + \OC_Defaults $defaults + ) { + $this->config = $config; + $this->userManager = $userManager; + $this->accountManager = $accountManager; + $this->groupManager = $groupManager; + $this->l10nFactory = $l10nFactory; + $this->defaults = $defaults; + } /** * @return TemplateResponse returns the instance with all parameters set, ready to be rendered * @since 9.1 */ public function getForm() { - return new TemplateResponse('settings', 'settings/personal/personal.info'); + $lookupServerUploadEnabled = $this->config->getAppValue('files_sharing', 'lookupServerUploadEnabled', 'yes'); + $lookupServerUploadEnabled = $lookupServerUploadEnabled === 'yes'; + + $uid = \OC_User::getUser(); + $user = $this->userManager->get($uid); + + $userData = $this->accountManager->getUser($user); + list($activeLanguage, $commonLanguages, $languages) = $this->getLanguages($user); + + //links to clients + $clients = [ + 'desktop' => $this->config->getSystemValue('customclient_desktop', $this->defaults->getSyncClientUrl()), + 'android' => $this->config->getSystemValue('customclient_android', $this->defaults->getAndroidClientUrl()), + 'ios' => $this->config->getSystemValue('customclient_ios', $this->defaults->getiOSClientUrl()) + ]; + + $parameters = [ + 'avatarChangeSupported' => \OC_User::canUserChangeAvatar($uid), + 'lookupServerUploadEnabled' => $lookupServerUploadEnabled, + 'avatar_scope' => $userData[AccountManager::PROPERTY_AVATAR]['scope'], + 'displayNameChangeSupported' => \OC_User::canUserChangeDisplayName($uid), + 'displayName' => $userData[AccountManager::PROPERTY_DISPLAYNAME]['value'], + 'email' => $userData[AccountManager::PROPERTY_EMAIL]['value'], + 'emailScope' => $userData[AccountManager::PROPERTY_EMAIL]['scope'], + 'emailMesage' => '', + 'emailVerification' => $userData[AccountManager::PROPERTY_EMAIL]['verified'], + 'phone' => $userData[AccountManager::PROPERTY_PHONE]['value'], + 'phoneScope' => $userData[AccountManager::PROPERTY_PHONE]['scope'], + 'address', $userData[AccountManager::PROPERTY_ADDRESS]['value'], + 'addressScope', $userData[AccountManager::PROPERTY_ADDRESS]['scope'], + 'website' => $userData[AccountManager::PROPERTY_WEBSITE]['value'], + 'websiteScope' => $userData[AccountManager::PROPERTY_WEBSITE]['scope'], + 'websiteVerification' => $userData[AccountManager::PROPERTY_WEBSITE]['verified'], + 'twitter' => $userData[AccountManager::PROPERTY_TWITTER]['value'], + 'twitterScope' => $userData[AccountManager::PROPERTY_TWITTER]['scope'], + 'twitterVerification' => $userData[AccountManager::PROPERTY_TWITTER]['verified'], + 'groups' => $this->groupManager->getUserGroups($user), + 'passwordChangeSupported' => \OC_User::canUserChangePassword($uid), + 'activelanguage' => $activeLanguage, + 'commonlanguages' => $commonLanguages, + 'languages' => $languages, + 'clients' => $clients, + ]; + + + return new TemplateResponse('settings', 'settings/personal/personal.info', $parameters, ''); } /** @@ -56,4 +147,60 @@ class PersonalInfo implements ISettings { public function getPriority() { return 10; } + + private function getLanguages(IUser $user) { + $uid = $user->getUID(); + + $commonLanguages = []; + $userLang = $this->config->getUserValue($uid, 'core', 'lang', $this->l10nFactory->findLanguage()); + $languageCodes = $this->l10nFactory->findAvailableLanguages(); + foreach($languageCodes as $lang) { + $l = \OC::$server->getL10N('settings', $lang); + // TRANSLATORS this is the language name for the language switcher in the personal settings and should be the localized version + $potentialName = (string) $l->t('__language_name__'); + if($l->getLanguageCode() === $lang && substr($potentialName, 0, 1) !== '_') {//first check if the language name is in the translation file + $ln = array('code' => $lang, 'name' => $potentialName); + } elseif ($lang === 'en') { + $ln = ['code' => $lang, 'name' => 'English (US)']; + }else{//fallback to language code + $ln=array('code'=>$lang, 'name'=>$lang); + } + + // put appropriate languages into appropriate arrays, to print them sorted + // used language -> common languages -> divider -> other languages + if ($lang === $userLang) { + $userLang = $ln; + } elseif (in_array($lang, self::COMMON_LANGUAGE_CODES)) { + $commonLanguages[array_search($lang, self::COMMON_LANGUAGE_CODES)]=$ln; + } else { + $languages[]=$ln; + } + } + + // if user language is not available but set somehow: show the actual code as name + if (!is_array($userLang)) { + $userLang = [ + 'code' => $userLang, + 'name' => $userLang, + ]; + } + + ksort($commonLanguages); + + // sort now by displayed language not the iso-code + usort( $languages, function ($a, $b) { + if ($a['code'] === $a['name'] && $b['code'] !== $b['name']) { + // If a doesn't have a name, but b does, list b before a + return 1; + } + if ($a['code'] !== $a['name'] && $b['code'] === $b['name']) { + // If a does have a name, but b doesn't, list a before b + return -1; + } + // Otherwise compare the names + return strcmp($a['name'], $b['name']); + }); + + return [$userLang, $commonLanguages, $languages]; + } } diff --git a/settings/js/settings/personalInfo.js b/settings/js/settings/personalInfo.js new file mode 100644 index 0000000000..9496f65a8f --- /dev/null +++ b/settings/js/settings/personalInfo.js @@ -0,0 +1,392 @@ +/* global OC */ + +/** + * Copyright (c) 2011, Robin Appelman + * 2013, Morris Jobke + * 2016, Christoph Wurst + * 2017, Arthur Schiwon + * This file is licensed under the Affero General Public License version 3 or later. + * See the COPYING-README file. + */ + +OC.Settings = OC.Settings || {}; + +/** + * The callback will be fired as soon as enter is pressed by the + * user or 1 second after the last data entry + * + * @param callback + * @param allowEmptyValue if this is set to true the callback is also called when the value is empty + */ +jQuery.fn.keyUpDelayedOrEnter = function (callback, allowEmptyValue) { + var cb = callback; + var that = this; + + this.on('input', _.debounce(function (event) { + // enter is already handled in keypress + if (event.keyCode === 13) { + return; + } + if (allowEmptyValue || that.val() !== '') { + cb(event); + } + }, 1000)); + + this.keypress(function (event) { + if (event.keyCode === 13 && (allowEmptyValue || that.val() !== '')) { + event.preventDefault(); + cb(event); + } + }); +}; + +function updateAvatar (hidedefault) { + var $headerdiv = $('#header .avatardiv'); + var $displaydiv = $('#displayavatar .avatardiv'); + + //Bump avatar avatarversion + oc_userconfig.avatar.version = -(Math.floor(Math.random() * 1000)); + + if (hidedefault) { + $headerdiv.hide(); + $('#header .avatardiv').removeClass('avatardiv-shown'); + } else { + $headerdiv.css({'background-color': ''}); + $headerdiv.avatar(OC.currentUser, 32, true); + $('#header .avatardiv').addClass('avatardiv-shown'); + } + $displaydiv.css({'background-color': ''}); + $displaydiv.avatar(OC.currentUser, 145, true, null, function() { + $displaydiv.removeClass('loading'); + $('#displayavatar img').show(); + if($('#displayavatar img').length === 0) { + $('#removeavatar').removeClass('inlineblock').addClass('hidden'); + } else { + $('#removeavatar').removeClass('hidden').addClass('inlineblock'); + } + }); +} + +function showAvatarCropper () { + var $cropper = $('#cropper'); + var $cropperImage = $(''); + $cropperImage.css('opacity', 0); // prevent showing the unresized image + $cropper.children('.inner-container').prepend($cropperImage); + + $cropperImage.attr('src', + OC.generateUrl('/avatar/tmp') + '?requesttoken=' + encodeURIComponent(oc_requesttoken) + '#' + Math.floor(Math.random() * 1000)); + + $cropperImage.load(function () { + var img = $cropperImage.get()[0]; + var selectSize = Math.min(img.width, img.height); + var offsetX = (img.width - selectSize) / 2; + var offsetY = (img.height - selectSize) / 2; + $cropperImage.Jcrop({ + onChange: saveCoords, + onSelect: saveCoords, + aspectRatio: 1, + boxHeight: Math.min(500, $('#app-content').height() -100), + boxWidth: Math.min(500, $('#app-content').width()), + setSelect: [offsetX, offsetY, selectSize, selectSize] + }, function() { + $cropper.show(); + }); + }); +} + +function sendCropData () { + cleanCropper(); + + var cropperData = $('#cropper').data(); + var data = { + x: cropperData.x, + y: cropperData.y, + w: cropperData.w, + h: cropperData.h + }; + $.post(OC.generateUrl('/avatar/cropped'), {crop: data}, avatarResponseHandler); +} + +function saveCoords (c) { + $('#cropper').data(c); +} + +function cleanCropper () { + var $cropper = $('#cropper'); + $('#displayavatar').show(); + $cropper.hide(); + $('.jcrop-holder').remove(); + $('#cropper img').removeData('Jcrop').removeAttr('style').removeAttr('src'); + $('#cropper img').remove(); +} + +function avatarResponseHandler (data) { + if (typeof data === 'string') { + data = JSON.parse(data); + } + var $warning = $('#avatarform .warning'); + $warning.hide(); + if (data.status === "success") { + updateAvatar(); + } else if (data.data === "notsquare") { + showAvatarCropper(); + } else { + $warning.show(); + $warning.text(data.data.message); + } +} + +$(document).ready(function () { + if($('#pass2').length) { + $('#pass2').showPassword().keyup(); + } + + var removeloader = function () { + setTimeout(function(){ + if ($('.password-state').length > 0) { + $('.password-state').remove(); + } + }, 5000) + }; + + $("#passwordbutton").click(function () { + var isIE8or9 = $('html').hasClass('lte9'); + // FIXME - TODO - once support for IE8 and IE9 is dropped + // for IE8 and IE9 this will check additionally if the typed in password + // is different from the placeholder, because in IE8/9 the placeholder + // is simply set as the value to look like a placeholder + if ($('#pass1').val() !== '' && $('#pass2').val() !== '' + && !(isIE8or9 && $('#pass2').val() === $('#pass2').attr('placeholder'))) { + // Serialize the data + var post = $("#passwordform").serialize(); + $('#passwordchanged').hide(); + $('#passworderror').hide(); + $("#passwordbutton").attr('disabled', 'disabled'); + $("#passwordbutton").after(""); + $(".personal-show-label").hide(); + // Ajax foo + $.post(OC.generateUrl('/settings/personal/changepassword'), post, function (data) { + if (data.status === "success") { + $("#passwordbutton").after(""); + removeloader(); + $(".personal-show-label").show(); + $('#pass1').val(''); + $('#pass2').val('').change(); + } + if (typeof(data.data) !== "undefined") { + OC.msg.finishedSaving('#password-error-msg', data); + } else { + OC.msg.finishedSaving('#password-error-msg', + { + 'status' : 'error', + 'data' : { + 'message' : t('core', 'Unable to change password') + } + } + ); + } + $(".password-loading").remove(); + $("#passwordbutton").removeAttr('disabled'); + }); + return false; + } else { + OC.msg.finishedSaving('#password-error-msg', + { + 'status' : 'error', + 'data' : { + 'message' : t('core', 'Unable to change password') + } + } + ); + return false; + } + }); + + var showVerifyDialog = function(dialog, howToVerify, verificationCode) { + var dialogContent = dialog.children('.verification-dialog-content'); + dialogContent.children(".explainVerification").text(howToVerify); + dialogContent.children(".verificationCode").text(verificationCode); + dialog.css('display', 'block'); + }; + + $(".verify").click(function (event) { + + event.stopPropagation(); + + var verify = $(this); + var indicator = $(this).children('img'); + var accountId = indicator.attr('id'); + var status = indicator.data('status'); + + var onlyVerificationCode = false; + if (parseInt(status) === 1) { + onlyVerificationCode = true; + } + + if (indicator.hasClass('verify-action')) { + $.ajax( + OC.generateUrl('/settings/users/{account}/verify', {account: accountId}), + { + method: 'GET', + data: {onlyVerificationCode: onlyVerificationCode} + } + ).done(function (data) { + var dialog = verify.children('.verification-dialog'); + showVerifyDialog($(dialog), data.msg, data.code); + indicator.attr('data-origin-title', t('core', 'Verifying …')); + indicator.attr('src', OC.imagePath('core', 'actions/verifying.svg')); + indicator.data('status', '1'); + }); + } + + }); + + // When the user clicks anywhere outside of the verification dialog we close it + $(document).click(function(event){ + var element = event.target; + var isDialog = $(element).hasClass('verificationCode') + || $(element).hasClass('explainVerification') + || $(element).hasClass('verification-dialog-content') + || $(element).hasClass('verification-dialog'); + if (!isDialog) { + $(document).find('.verification-dialog').css('display', 'none'); + } + }); + + + var federationSettingsView = new OC.Settings.FederationSettingsView({ + el: '#personal-settings' + }); + federationSettingsView.render(); + + $("#languageinput").change(function () { + // Serialize the data + var post = $("#languageinput").serialize(); + // Ajax foo + $.ajax( + 'ajax/setlanguage.php', + { + method: 'POST', + data: post + } + ).done(function() { + location.reload(); + }).fail(function(jqXHR) { + $('#passworderror').text(jqXHR.responseJSON.message); + }); + return false; + }); + + var uploadparms = { + pasteZone: null, + done: function (e, data) { + var response = data; + if (typeof data.result === 'string') { + response = JSON.parse(data.result); + } else if (data.result && data.result.length) { + // fetch response from iframe + response = JSON.parse(data.result[0].body.innerText); + } else { + response = data.result; + } + avatarResponseHandler(response); + }, + submit: function(e, data) { + $('#displayavatar img').hide(); + $('#displayavatar .avatardiv').addClass('loading'); + data.formData = _.extend(data.formData || {}, { + requesttoken: OC.requestToken + }); + }, + fail: function (e, data){ + var msg = data.jqXHR.statusText + ' (' + data.jqXHR.status + ')'; + if (!_.isUndefined(data.jqXHR.responseJSON) && + !_.isUndefined(data.jqXHR.responseJSON.data) && + !_.isUndefined(data.jqXHR.responseJSON.data.message) + ) { + msg = data.jqXHR.responseJSON.data.message; + } + avatarResponseHandler({ + data: { + message: msg + } + }); + } + }; + + $('#uploadavatar').fileupload(uploadparms); + + $('#selectavatar').click(function () { + OC.dialogs.filepicker( + t('settings', "Select a profile picture"), + function (path) { + $('#displayavatar img').hide(); + $('#displayavatar .avatardiv').addClass('loading'); + $.ajax({ + type: "POST", + url: OC.generateUrl('/avatar/'), + data: { path: path } + }).done(avatarResponseHandler) + .fail(function(jqXHR) { + var msg = jqXHR.statusText + ' (' + jqXHR.status + ')'; + if (!_.isUndefined(jqXHR.responseJSON) && + !_.isUndefined(jqXHR.responseJSON.data) && + !_.isUndefined(jqXHR.responseJSON.data.message) + ) { + msg = jqXHR.responseJSON.data.message; + } + avatarResponseHandler({ + data: { + message: msg + } + }); + }); + }, + false, + ["image/png", "image/jpeg"] + ); + }); + + $('#removeavatar').click(function () { + $.ajax({ + type: 'DELETE', + url: OC.generateUrl('/avatar/'), + success: function () { + updateAvatar(true); + } + }); + }); + + $('#abortcropperbutton').click(function () { + $('#displayavatar .avatardiv').removeClass('loading'); + $('#displayavatar img').show(); + cleanCropper(); + }); + + $('#sendcropperbutton').click(function () { + sendCropData(); + }); + + $('#pass2').strengthify({ + zxcvbn: OC.linkTo('core','vendor/zxcvbn/dist/zxcvbn.js'), + titles: [ + t('core', 'Very weak password'), + t('core', 'Weak password'), + t('core', 'So-so password'), + t('core', 'Good password'), + t('core', 'Strong password') + ], + drawTitles: true, + }); + + // Load the big avatar + $('#avatarform .avatardiv').avatar(OC.currentUser, 145, true, null, function() { + if($('#displayavatar img').length === 0) { + $('#removeavatar').removeClass('inlineblock').addClass('hidden'); + } else { + $('#removeavatar').removeClass('hidden').addClass('inlineblock'); + } + }); +}); + +OC.Settings.updateAvatar = updateAvatar; diff --git a/settings/routes.php b/settings/routes.php index 52523ff50c..12da950ed2 100644 --- a/settings/routes.php +++ b/settings/routes.php @@ -65,7 +65,7 @@ $application->registerRoutes($this, [ ['name' => 'Certificate#removePersonalRootCertificate', 'url' => '/settings/personal/certificate/{certificateIdentifier}', 'verb' => 'DELETE'], ['name' => 'Certificate#addSystemRootCertificate', 'url' => '/settings/admin/certificate', 'verb' => 'POST'], ['name' => 'Certificate#removeSystemRootCertificate', 'url' => '/settings/admin/certificate/{certificateIdentifier}', 'verb' => 'DELETE'], - ['name' => 'PersonalSettings#index', 'url' => '/settings/personal/{section}', 'verb' => 'GET', 'defaults' => ['section' => 'personal-info']], + ['name' => 'PersonalSettings#index', 'url' => '/settings/user/{section}', 'verb' => 'GET', 'defaults' => ['section' => 'personal-info']], ['name' => 'AdminSettings#index', 'url' => '/settings/admin/{section}', 'verb' => 'GET', 'defaults' => ['section' => 'server']], ['name' => 'AdminSettings#form', 'url' => '/settings/admin/{section}', 'verb' => 'GET'], ['name' => 'ChangePassword#changePersonalPassword', 'url' => '/settings/personal/changepassword', 'verb' => 'POST'], diff --git a/settings/templates/settings/personal/personal.info.php b/settings/templates/settings/personal/personal.info.php index 7a19752912..eb1bb43d26 100644 --- a/settings/templates/settings/personal/personal.info.php +++ b/settings/templates/settings/personal/personal.info.php @@ -24,6 +24,22 @@ /** @var \OCP\IL10N $l */ /** @var array $_ */ +script('settings', [ + 'usersettings', + 'federationsettingsview', + 'federationscopemenu', + 'settings/personalInfo', +]); +style('settings', 'settings'); +vendor_script('strengthify/jquery.strengthify'); +vendor_style('strengthify/strengthify'); +script('files', 'jquery.fileupload'); +vendor_script('jcrop/js/jquery.Jcrop'); +vendor_style('jcrop/css/jquery.Jcrop'); + +//TODO: delete js/personal.js once the Encryption and AuthToken things are, +// where they belong + ?>
    From 9e924d74c96f9d6545ab0d204719c8486c5c8cb7 Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Wed, 17 May 2017 11:51:22 +0200 Subject: [PATCH 06/42] fix displaying groups in personal info Signed-off-by: Arthur Schiwon --- .../Settings/Personal/PersonalInfo.php | 54 +++++++++++++++---- 1 file changed, 44 insertions(+), 10 deletions(-) diff --git a/lib/private/Settings/Personal/PersonalInfo.php b/lib/private/Settings/Personal/PersonalInfo.php index c1b2e8acc7..605d0c4df6 100644 --- a/lib/private/Settings/Personal/PersonalInfo.php +++ b/lib/private/Settings/Personal/PersonalInfo.php @@ -27,6 +27,7 @@ namespace OC\Settings\Personal; use OC\Accounts\AccountManager; use OCP\AppFramework\Http\TemplateResponse; use OCP\IConfig; +use OCP\IGroup; use OCP\IGroupManager; use OCP\IUser; use OCP\IUserManager; @@ -58,6 +59,7 @@ class PersonalInfo implements ISettings { * @param IGroupManager $groupManager * @param AccountManager $accountManager * @param IFactory $l10nFactory + * @param \OC_Defaults $defaults */ public function __construct( IConfig $config, @@ -85,16 +87,9 @@ class PersonalInfo implements ISettings { $uid = \OC_User::getUser(); $user = $this->userManager->get($uid); - $userData = $this->accountManager->getUser($user); - list($activeLanguage, $commonLanguages, $languages) = $this->getLanguages($user); - //links to clients - $clients = [ - 'desktop' => $this->config->getSystemValue('customclient_desktop', $this->defaults->getSyncClientUrl()), - 'android' => $this->config->getSystemValue('customclient_android', $this->defaults->getAndroidClientUrl()), - 'ios' => $this->config->getSystemValue('customclient_ios', $this->defaults->getiOSClientUrl()) - ]; + list($activeLanguage, $commonLanguages, $languages) = $this->getLanguages($user); $parameters = [ 'avatarChangeSupported' => \OC_User::canUserChangeAvatar($uid), @@ -116,12 +111,12 @@ class PersonalInfo implements ISettings { 'twitter' => $userData[AccountManager::PROPERTY_TWITTER]['value'], 'twitterScope' => $userData[AccountManager::PROPERTY_TWITTER]['scope'], 'twitterVerification' => $userData[AccountManager::PROPERTY_TWITTER]['verified'], - 'groups' => $this->groupManager->getUserGroups($user), + 'groups' => $this->getGroups($user), 'passwordChangeSupported' => \OC_User::canUserChangePassword($uid), 'activelanguage' => $activeLanguage, 'commonlanguages' => $commonLanguages, 'languages' => $languages, - 'clients' => $clients, + 'clients' => $this->getClientLinks(), ]; @@ -148,6 +143,31 @@ class PersonalInfo implements ISettings { return 10; } + /** + * returns a sorted list of the user's group GIDs + * + * @param IUser $user + * @return array + */ + private function getGroups(IUser $user) { + $groups = array_map( + function(IGroup $group) { + return $group->getGID(); + }, + $this->groupManager->getUserGroups($user) + ); + sort($groups); + + return $groups; + } + + /** + * returns the user language, common language and other languages in an + * associative array + * + * @param IUser $user + * @return array + */ private function getLanguages(IUser $user) { $uid = $user->getUID(); @@ -203,4 +223,18 @@ class PersonalInfo implements ISettings { return [$userLang, $commonLanguages, $languages]; } + + /** + * returns an array containing links to the various clients + * + * @return array + */ + private function getClientLinks() { + $clients = [ + 'desktop' => $this->config->getSystemValue('customclient_desktop', $this->defaults->getSyncClientUrl()), + 'android' => $this->config->getSystemValue('customclient_android', $this->defaults->getAndroidClientUrl()), + 'ios' => $this->config->getSystemValue('customclient_ios', $this->defaults->getiOSClientUrl()) + ]; + return $clients; + } } From 8bd887b2c6e821a5809b5e7eabc29358923c3ca7 Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Wed, 17 May 2017 12:06:51 +0200 Subject: [PATCH 07/42] add storage info, fix URL generation Signed-off-by: Arthur Schiwon --- lib/private/NavigationManager.php | 2 +- lib/private/Settings/Manager.php | 2 +- .../Settings/Personal/PersonalInfo.php | 20 ++++++++++++++++++- .../settings/personal/personal.info.php | 15 ++++++++++++++ 4 files changed, 36 insertions(+), 3 deletions(-) diff --git a/lib/private/NavigationManager.php b/lib/private/NavigationManager.php index e0b83fe5e4..1655200593 100644 --- a/lib/private/NavigationManager.php +++ b/lib/private/NavigationManager.php @@ -182,7 +182,7 @@ class NavigationManager implements INavigationManager { 'type' => 'settings', 'id' => 'settings', 'order' => 1, - 'href' => $this->urlGenerator->linkToRoute('settings_personal'), + 'href' => $this->urlGenerator->linkToRoute('settings.PersonalSettings.index'), 'name' => $l->t('Settings'), 'icon' => $this->urlGenerator->imagePath('settings', 'admin.svg'), ]); diff --git a/lib/private/Settings/Manager.php b/lib/private/Settings/Manager.php index d6b3398d0f..41db5be974 100644 --- a/lib/private/Settings/Manager.php +++ b/lib/private/Settings/Manager.php @@ -368,7 +368,7 @@ class Manager implements IManager { try { if ($section === 'personal-info') { /** @var ISettings $form */ - $form = new Personal\PersonalInfo($this->config, $this->userManager, $this->groupManager, $this->accountManager, $this->l10nFactory, $this->defaults); + $form = new Personal\PersonalInfo($this->config, $this->userManager, $this->groupManager, $this->accountManager, $this->l10nFactory, $this->defaults, $this->l); $forms[$form->getPriority()] = [$form]; } } catch (QueryException $e) { diff --git a/lib/private/Settings/Personal/PersonalInfo.php b/lib/private/Settings/Personal/PersonalInfo.php index 605d0c4df6..14c96d2fc4 100644 --- a/lib/private/Settings/Personal/PersonalInfo.php +++ b/lib/private/Settings/Personal/PersonalInfo.php @@ -26,9 +26,11 @@ namespace OC\Settings\Personal; use OC\Accounts\AccountManager; use OCP\AppFramework\Http\TemplateResponse; +use OCP\Files\FileInfo; use OCP\IConfig; use OCP\IGroup; use OCP\IGroupManager; +use OCP\IL10N; use OCP\IUser; use OCP\IUserManager; use OCP\L10N\IFactory; @@ -52,6 +54,8 @@ class PersonalInfo implements ISettings { ]; /** @var \OC_Defaults */ private $defaults; + /** @var IL10N */ + private $l; /** * @param IConfig $config @@ -60,6 +64,7 @@ class PersonalInfo implements ISettings { * @param AccountManager $accountManager * @param IFactory $l10nFactory * @param \OC_Defaults $defaults + * @param IL10N $l */ public function __construct( IConfig $config, @@ -67,7 +72,8 @@ class PersonalInfo implements ISettings { IGroupManager $groupManager, AccountManager $accountManager, IFactory $l10nFactory, - \OC_Defaults $defaults + \OC_Defaults $defaults, + IL10N $l ) { $this->config = $config; $this->userManager = $userManager; @@ -75,6 +81,7 @@ class PersonalInfo implements ISettings { $this->groupManager = $groupManager; $this->l10nFactory = $l10nFactory; $this->defaults = $defaults; + $this->l = $l; } /** @@ -89,9 +96,20 @@ class PersonalInfo implements ISettings { $user = $this->userManager->get($uid); $userData = $this->accountManager->getUser($user); + $storageInfo = \OC_Helper::getStorageInfo('/'); + if ($storageInfo['quota'] === FileInfo::SPACE_UNLIMITED) { + $totalSpace = $this->l->t('Unlimited'); + } else { + $totalSpace = \OC_Helper::humanFileSize($storageInfo['total']); + } + list($activeLanguage, $commonLanguages, $languages) = $this->getLanguages($user); $parameters = [ + 'total_space' => $totalSpace, + 'usage' => \OC_Helper::humanFileSize($storageInfo['used']), + 'usage_relative' => $storageInfo['relative'], + 'quota' => $storageInfo['quota'], 'avatarChangeSupported' => \OC_User::canUserChangeAvatar($uid), 'lookupServerUploadEnabled' => $lookupServerUploadEnabled, 'avatar_scope' => $userData[AccountManager::PROPERTY_AVATAR]['scope'], diff --git a/settings/templates/settings/personal/personal.info.php b/settings/templates/settings/personal/personal.info.php index eb1bb43d26..dd271563c6 100644 --- a/settings/templates/settings/personal/personal.info.php +++ b/settings/templates/settings/personal/personal.info.php @@ -42,6 +42,21 @@ vendor_style('jcrop/css/jquery.Jcrop'); ?> +
    +
    80): ?> class="quota-warning" > +

    + + t('You are using %s of %s', + [$_['usage'], $_['total_space']]));?> + + t('You are using %s of %s (%s %%)', + [$_['usage'], $_['total_space'], $_['usage_relative']]));?> + +

    +
    +
    +
    From 489ac4391b9d5022103609a972e12b55fd4733e2 Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Wed, 17 May 2017 13:41:20 +0200 Subject: [PATCH 08/42] convert Sessions section Signed-off-by: Arthur Schiwon --- lib/private/Settings/Manager.php | 7 +++ lib/private/Settings/Personal/Sessions.php | 59 +++++++++++++++++++ settings/js/settings/sessions.js | 7 +++ .../templates/settings/personal/sessions.php | 48 +++++++++++++++ 4 files changed, 121 insertions(+) create mode 100644 lib/private/Settings/Personal/Sessions.php create mode 100644 settings/js/settings/sessions.js create mode 100644 settings/templates/settings/personal/sessions.php diff --git a/lib/private/Settings/Manager.php b/lib/private/Settings/Manager.php index 41db5be974..10f7224b9a 100644 --- a/lib/private/Settings/Manager.php +++ b/lib/private/Settings/Manager.php @@ -371,6 +371,11 @@ class Manager implements IManager { $form = new Personal\PersonalInfo($this->config, $this->userManager, $this->groupManager, $this->accountManager, $this->l10nFactory, $this->defaults, $this->l); $forms[$form->getPriority()] = [$form]; } + if($section === 'sessions') { + /** @var ISettings $form */ + $form = new Personal\Sessions(); + $forms[$form->getPriority()] = [$form]; + } } catch (QueryException $e) { // skip } @@ -405,6 +410,8 @@ class Manager implements IManager { public function getPersonalSections() { $sections = [ 0 => [new Section('personal-info', $this->l->t('Personal info'), 0, $this->url->imagePath('core', 'actions/info.svg'))], + 1 => [new Section('sessions', $this->l->t('Sessions'), 0, $this->url->imagePath('settings', 'admin.svg'))], + ]; return $sections; } diff --git a/lib/private/Settings/Personal/Sessions.php b/lib/private/Settings/Personal/Sessions.php new file mode 100644 index 0000000000..22f8a44b17 --- /dev/null +++ b/lib/private/Settings/Personal/Sessions.php @@ -0,0 +1,59 @@ + + * + * @author Arthur Schiwon + * + * @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 OC\Settings\Personal; + + +use OCP\AppFramework\Http\TemplateResponse; +use OCP\Settings\ISettings; + +class Sessions implements ISettings { + + /** + * @return TemplateResponse returns the instance with all parameters set, ready to be rendered + * @since 9.1 + */ + public function getForm() { + return new TemplateResponse('settings', 'settings/personal/sessions'); + } + + /** + * @return string the section ID, e.g. 'sharing' + * @since 9.1 + */ + public function getSection() { + return 'sessions'; + } + + /** + * @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. + * + * E.g.: 70 + * @since 9.1 + */ + public function getPriority() { + return 10; + } +} diff --git a/settings/js/settings/sessions.js b/settings/js/settings/sessions.js new file mode 100644 index 0000000000..953727e39d --- /dev/null +++ b/settings/js/settings/sessions.js @@ -0,0 +1,7 @@ +$(document).ready(function () { + var collection = new OC.Settings.AuthTokenCollection(); + var view = new OC.Settings.AuthTokenView({ + collection: collection + }); + view.reload(); +}); diff --git a/settings/templates/settings/personal/sessions.php b/settings/templates/settings/personal/sessions.php new file mode 100644 index 0000000000..81613f0f27 --- /dev/null +++ b/settings/templates/settings/personal/sessions.php @@ -0,0 +1,48 @@ + + * + * @author Arthur Schiwon + * + * @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 . + * + */ + +script('settings', [ + 'authtoken', + 'authtoken_collection', + 'authtoken_view', + 'settings/sessions' +]); + +?> + + +
    +

    t('Sessions'));?>

    +

    t('Web, desktop and mobile clients currently logged in to your account.'));?>

    + + + + + + + + + + +
    t('Device'));?>t('Last activity'));?>
    +
    From 8c076e0bda8f0580929f6f3150b18d9ed710dd87 Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Wed, 17 May 2017 14:12:55 +0200 Subject: [PATCH 09/42] take over app passwords Signed-off-by: Arthur Schiwon --- lib/private/Settings/Manager.php | 8 ++- .../Settings/Personal/AppPasswords.php | 59 +++++++++++++++++ .../{sessions.js => authtoken-init.js} | 0 .../settings/personal/app-passwords.php | 66 +++++++++++++++++++ .../settings/personal/personal.info.php | 2 - .../templates/settings/personal/sessions.php | 2 +- 6 files changed, 133 insertions(+), 4 deletions(-) create mode 100644 lib/private/Settings/Personal/AppPasswords.php rename settings/js/settings/{sessions.js => authtoken-init.js} (100%) create mode 100644 settings/templates/settings/personal/app-passwords.php diff --git a/lib/private/Settings/Manager.php b/lib/private/Settings/Manager.php index 10f7224b9a..f914ac634f 100644 --- a/lib/private/Settings/Manager.php +++ b/lib/private/Settings/Manager.php @@ -376,6 +376,11 @@ class Manager implements IManager { $form = new Personal\Sessions(); $forms[$form->getPriority()] = [$form]; } + if($section === 'app-passwords') { + /** @var ISettings $form */ + $form = new Personal\AppPasswords(); + $forms[$form->getPriority()] = [$form]; + } } catch (QueryException $e) { // skip } @@ -410,7 +415,8 @@ class Manager implements IManager { public function getPersonalSections() { $sections = [ 0 => [new Section('personal-info', $this->l->t('Personal info'), 0, $this->url->imagePath('core', 'actions/info.svg'))], - 1 => [new Section('sessions', $this->l->t('Sessions'), 0, $this->url->imagePath('settings', 'admin.svg'))], + 5 => [new Section('sessions', $this->l->t('Sessions'), 0, $this->url->imagePath('settings', 'admin.svg'))], + 10 => [new Section('app-passwords', $this->l->t('App passwords'), 0, $this->url->imagePath('settings', 'password.svg'))], ]; return $sections; diff --git a/lib/private/Settings/Personal/AppPasswords.php b/lib/private/Settings/Personal/AppPasswords.php new file mode 100644 index 0000000000..3f2886326d --- /dev/null +++ b/lib/private/Settings/Personal/AppPasswords.php @@ -0,0 +1,59 @@ + + * + * @author Arthur Schiwon + * + * @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 OC\Settings\Personal; + + +use OCP\AppFramework\Http\TemplateResponse; +use OCP\Settings\ISettings; + +class AppPasswords implements ISettings { + + /** + * @return TemplateResponse returns the instance with all parameters set, ready to be rendered + * @since 9.1 + */ + public function getForm() { + return new TemplateResponse('settings', 'settings/personal/app-passwords'); + } + + /** + * @return string the section ID, e.g. 'sharing' + * @since 9.1 + */ + public function getSection() { + return 'app-passwords'; + } + + /** + * @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. + * + * E.g.: 70 + * @since 9.1 + */ + public function getPriority() { + return 5; + } +} diff --git a/settings/js/settings/sessions.js b/settings/js/settings/authtoken-init.js similarity index 100% rename from settings/js/settings/sessions.js rename to settings/js/settings/authtoken-init.js diff --git a/settings/templates/settings/personal/app-passwords.php b/settings/templates/settings/personal/app-passwords.php new file mode 100644 index 0000000000..b9f8c4867e --- /dev/null +++ b/settings/templates/settings/personal/app-passwords.php @@ -0,0 +1,66 @@ + + * + * @author Arthur Schiwon + * + * @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 . + * + */ +script('settings', [ + 'authtoken', + 'authtoken_collection', + 'authtoken_view', + 'settings/authtoken-init' +]); + +?> + +
    +

    t('App passwords'));?>

    +

    t('Here you can generate individual passwords for apps so you don’t have to give out your password. You can revoke them individually too.'));?>

    + + + + + + + + + + +
    t('Name'));?>t('Last activity'));?>
    +
    + + +
    + +
    diff --git a/settings/templates/settings/personal/personal.info.php b/settings/templates/settings/personal/personal.info.php index dd271563c6..0e628e7e61 100644 --- a/settings/templates/settings/personal/personal.info.php +++ b/settings/templates/settings/personal/personal.info.php @@ -30,10 +30,8 @@ script('settings', [ 'federationscopemenu', 'settings/personalInfo', ]); -style('settings', 'settings'); vendor_script('strengthify/jquery.strengthify'); vendor_style('strengthify/strengthify'); -script('files', 'jquery.fileupload'); vendor_script('jcrop/js/jquery.Jcrop'); vendor_style('jcrop/css/jquery.Jcrop'); diff --git a/settings/templates/settings/personal/sessions.php b/settings/templates/settings/personal/sessions.php index 81613f0f27..60b38d6648 100644 --- a/settings/templates/settings/personal/sessions.php +++ b/settings/templates/settings/personal/sessions.php @@ -25,7 +25,7 @@ script('settings', [ 'authtoken', 'authtoken_collection', 'authtoken_view', - 'settings/sessions' + 'settings/authtoken-init' ]); ?> From d56e86cfde49910d3af564fb7e6dd553279dfc3c Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Wed, 17 May 2017 14:22:44 +0200 Subject: [PATCH 10/42] sync clients have their own place Signed-off-by: Arthur Schiwon --- lib/private/Settings/Manager.php | 8 +- .../Settings/Personal/PersonalInfo.php | 20 +---- lib/private/Settings/Personal/SyncClients.php | 85 +++++++++++++++++++ .../settings/personal/personal.info.php | 36 -------- .../settings/personal/sync-clients.php | 59 +++++++++++++ 5 files changed, 152 insertions(+), 56 deletions(-) create mode 100644 lib/private/Settings/Personal/SyncClients.php create mode 100644 settings/templates/settings/personal/sync-clients.php diff --git a/lib/private/Settings/Manager.php b/lib/private/Settings/Manager.php index f914ac634f..19937bd7af 100644 --- a/lib/private/Settings/Manager.php +++ b/lib/private/Settings/Manager.php @@ -368,7 +368,7 @@ class Manager implements IManager { try { if ($section === 'personal-info') { /** @var ISettings $form */ - $form = new Personal\PersonalInfo($this->config, $this->userManager, $this->groupManager, $this->accountManager, $this->l10nFactory, $this->defaults, $this->l); + $form = new Personal\PersonalInfo($this->config, $this->userManager, $this->groupManager, $this->accountManager, $this->l10nFactory, $this->l); $forms[$form->getPriority()] = [$form]; } if($section === 'sessions') { @@ -381,6 +381,11 @@ class Manager implements IManager { $form = new Personal\AppPasswords(); $forms[$form->getPriority()] = [$form]; } + if($section === 'sync-clients') { + /** @var ISettings $form */ + $form = new Personal\SyncClients($this->config, $this->defaults); + $forms[$form->getPriority()] = [$form]; + } } catch (QueryException $e) { // skip } @@ -417,6 +422,7 @@ class Manager implements IManager { 0 => [new Section('personal-info', $this->l->t('Personal info'), 0, $this->url->imagePath('core', 'actions/info.svg'))], 5 => [new Section('sessions', $this->l->t('Sessions'), 0, $this->url->imagePath('settings', 'admin.svg'))], 10 => [new Section('app-passwords', $this->l->t('App passwords'), 0, $this->url->imagePath('settings', 'password.svg'))], + 15 => [new Section('sync-clients', $this->l->t('Sync clients'), 0, $this->url->imagePath('settings', 'change.svg'))], ]; return $sections; diff --git a/lib/private/Settings/Personal/PersonalInfo.php b/lib/private/Settings/Personal/PersonalInfo.php index 14c96d2fc4..ea7cecaa79 100644 --- a/lib/private/Settings/Personal/PersonalInfo.php +++ b/lib/private/Settings/Personal/PersonalInfo.php @@ -52,8 +52,7 @@ class PersonalInfo implements ISettings { 'en', 'es', 'fr', 'de', 'de_DE', 'ja', 'ar', 'ru', 'nl', 'it', 'pt_BR', 'pt_PT', 'da', 'fi_FI', 'nb_NO', 'sv', 'tr', 'zh_CN', 'ko' ]; - /** @var \OC_Defaults */ - private $defaults; + /** @var IL10N */ private $l; @@ -63,7 +62,6 @@ class PersonalInfo implements ISettings { * @param IGroupManager $groupManager * @param AccountManager $accountManager * @param IFactory $l10nFactory - * @param \OC_Defaults $defaults * @param IL10N $l */ public function __construct( @@ -72,7 +70,6 @@ class PersonalInfo implements ISettings { IGroupManager $groupManager, AccountManager $accountManager, IFactory $l10nFactory, - \OC_Defaults $defaults, IL10N $l ) { $this->config = $config; @@ -80,7 +77,6 @@ class PersonalInfo implements ISettings { $this->accountManager = $accountManager; $this->groupManager = $groupManager; $this->l10nFactory = $l10nFactory; - $this->defaults = $defaults; $this->l = $l; } @@ -134,7 +130,6 @@ class PersonalInfo implements ISettings { 'activelanguage' => $activeLanguage, 'commonlanguages' => $commonLanguages, 'languages' => $languages, - 'clients' => $this->getClientLinks(), ]; @@ -242,17 +237,4 @@ class PersonalInfo implements ISettings { return [$userLang, $commonLanguages, $languages]; } - /** - * returns an array containing links to the various clients - * - * @return array - */ - private function getClientLinks() { - $clients = [ - 'desktop' => $this->config->getSystemValue('customclient_desktop', $this->defaults->getSyncClientUrl()), - 'android' => $this->config->getSystemValue('customclient_android', $this->defaults->getAndroidClientUrl()), - 'ios' => $this->config->getSystemValue('customclient_ios', $this->defaults->getiOSClientUrl()) - ]; - return $clients; - } } diff --git a/lib/private/Settings/Personal/SyncClients.php b/lib/private/Settings/Personal/SyncClients.php new file mode 100644 index 0000000000..c4efcb63fe --- /dev/null +++ b/lib/private/Settings/Personal/SyncClients.php @@ -0,0 +1,85 @@ + + * + * @author Arthur Schiwon + * + * @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 OC\Settings\Personal; + + +use OCP\AppFramework\Http\TemplateResponse; +use OCP\IConfig; +use OCP\Settings\ISettings; + +class SyncClients implements ISettings { + + /** @var IConfig */ + private $config; + /** @var \OC_Defaults */ + private $defaults; + + public function __construct(IConfig $config, \OC_Defaults $defaults) { + $this->config = $config; + $this->defaults = $defaults; + } + + /** + * @return TemplateResponse returns the instance with all parameters set, ready to be rendered + * @since 9.1 + */ + public function getForm() { + $parameters = [ 'clients' => $this->getClientLinks() ]; + return new TemplateResponse('settings', 'settings/personal/sync-clients', $parameters); + } + + /** + * @return string the section ID, e.g. 'sharing' + * @since 9.1 + */ + public function getSection() { + return 'sync-clients'; + } + + /** + * @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. + * + * E.g.: 70 + * @since 9.1 + */ + public function getPriority() { + return 20; + } + + /** + * returns an array containing links to the various clients + * + * @return array + */ + private function getClientLinks() { + $clients = [ + 'desktop' => $this->config->getSystemValue('customclient_desktop', $this->defaults->getSyncClientUrl()), + 'android' => $this->config->getSystemValue('customclient_android', $this->defaults->getAndroidClientUrl()), + 'ios' => $this->config->getSystemValue('customclient_ios', $this->defaults->getiOSClientUrl()) + ]; + return $clients; + } +} diff --git a/settings/templates/settings/personal/personal.info.php b/settings/templates/settings/personal/personal.info.php index 0e628e7e61..9fe0e546db 100644 --- a/settings/templates/settings/personal/personal.info.php +++ b/settings/templates/settings/personal/personal.info.php @@ -315,39 +315,3 @@ if($_['passwordChangeSupported']) { t('Help translate'));?> - - -
    -

    t('Get the apps to sync your files'));?>

    - - <?php p($l->t('Desktop client'));?> - - - <?php p($l->t('Android app'));?> - - - <?php p($l->t('iOS app'));?> - - -

    - ', - '', - ], - $l->t('If you want to support the project {contributeopen}join development{linkclose} or {contributeopen}spread the word{linkclose}!'))); ?> -

    - - -

    t('Show First Run Wizard again'));?>

    - -
    - - diff --git a/settings/templates/settings/personal/sync-clients.php b/settings/templates/settings/personal/sync-clients.php new file mode 100644 index 0000000000..ac76ef4f59 --- /dev/null +++ b/settings/templates/settings/personal/sync-clients.php @@ -0,0 +1,59 @@ + + * + * @author Arthur Schiwon + * + * @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 . + * + */ + +/** @var array $_ */ + +?> + +
    +

    t('Get the apps to sync your files'));?>

    + + <?php p($l->t('Desktop client'));?> + + + <?php p($l->t('Android app'));?> + + + <?php p($l->t('iOS app'));?> + + +

    + ', + '', + ], + $l->t('If you want to support the project {contributeopen}join development{linkclose} or {contributeopen}spread the word{linkclose}!'))); ?> +

    + + +

    t('Show First Run Wizard again'));?>

    + +
    From 7f48b6f14faf42774332ef90a7fa660f1bbd1633 Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Fri, 19 May 2017 12:11:07 +0200 Subject: [PATCH 11/42] Adopt DB and Manager to personal settings structure Signed-off-by: Arthur Schiwon --- db_structure.xml | 121 +++++++++++++++++++++++++++++++ lib/private/Settings/Manager.php | 100 ++++++++++++++++--------- lib/private/Settings/Mapper.php | 37 ++++++++-- lib/public/Settings/IManager.php | 10 +++ version.php | 2 +- 5 files changed, 229 insertions(+), 41 deletions(-) diff --git a/db_structure.xml b/db_structure.xml index 583e9bb852..ac7f4b3c71 100644 --- a/db_structure.xml +++ b/db_structure.xml @@ -2135,6 +2135,127 @@ + + + *dbprefix*personal_sections + + + + + id + text + + false + 64 + + + + class + text + + true + 255 + + + + priority + integer + + true + 1 + + + + personal_sections_id_index + true + + id + ascending + + + + + personal_sections_class + true + + class + ascending + + + + +
    + + + + *dbprefix*personal_settings + + + + + id + integer + 0 + true + 1 + 4 + + + + class + text + + true + 255 + + + + + section + text + + false + 64 + + + + priority + integer + + true + 1 + + + + personal_settings_id_index + true + + id + ascending + + + + + personal_settings_class + true + + class + ascending + + + + + personal_settings_section + false + + section + ascending + + + + +
    + *dbprefix*accounts diff --git a/lib/private/Settings/Manager.php b/lib/private/Settings/Manager.php index 19937bd7af..707550c0bb 100644 --- a/lib/private/Settings/Manager.php +++ b/lib/private/Settings/Manager.php @@ -41,9 +41,6 @@ use OCP\Settings\IManager; use OCP\Settings\ISection; class Manager implements IManager { - const TABLE_ADMIN_SETTINGS = 'admin_settings'; - const TABLE_ADMIN_SECTIONS = 'admin_sections'; - /** @var ILogger */ private $log; /** @var IDBConnection */ @@ -87,6 +84,7 @@ class Manager implements IManager { * @param AccountManager $accountManager * @param IGroupManager $groupManager * @param IFactory $l10nFactory + * @param \OC_Defaults $defaults */ public function __construct( ILogger $log, @@ -125,10 +123,17 @@ class Manager implements IManager { */ public function setupSettings(array $settings) { if (isset($settings[IManager::KEY_ADMIN_SECTION])) { - $this->setupAdminSection($settings[IManager::KEY_ADMIN_SECTION]); + $this->setupSectionEntry($settings[IManager::KEY_ADMIN_SECTION], 'admin'); } if (isset($settings[IManager::KEY_ADMIN_SETTINGS])) { - $this->setupAdminSettings($settings[IManager::KEY_ADMIN_SETTINGS]); + $this->setupSettingsEntry($settings[IManager::KEY_ADMIN_SETTINGS], 'admin'); + } + + if (isset($settings[IManager::KEY_PERSONAL_SECTION])) { + $this->setupSectionEntry($settings[IManager::KEY_PERSONAL_SECTION], 'personal'); + } + if (isset($settings[IManager::KEY_PERSONAL_SETTINGS])) { + $this->setupSettingsEntry($settings[IManager::KEY_PERSONAL_SETTINGS], 'personal'); } } @@ -144,15 +149,22 @@ class Manager implements IManager { $appInfo = \OC_App::getAppInfo($appId); // hello static legacy if (isset($appInfo['settings'][IManager::KEY_ADMIN_SECTION])) { - $this->mapper->remove(self::TABLE_ADMIN_SECTIONS, trim($appInfo['settings'][IManager::KEY_ADMIN_SECTION], '\\')); + $this->mapper->remove(Mapper::TABLE_ADMIN_SECTIONS, trim($appInfo['settings'][IManager::KEY_ADMIN_SECTION], '\\')); } if (isset($appInfo['settings'][IManager::KEY_ADMIN_SETTINGS])) { - $this->mapper->remove(self::TABLE_ADMIN_SETTINGS, trim($appInfo['settings'][IManager::KEY_ADMIN_SETTINGS], '\\')); + $this->mapper->remove(Mapper::TABLE_ADMIN_SETTINGS, trim($appInfo['settings'][IManager::KEY_ADMIN_SETTINGS], '\\')); + } + + if (isset($appInfo['settings'][IManager::KEY_PERSONAL_SECTION])) { + $this->mapper->remove(Mapper::TABLE_PERSONAL_SECTIONS, trim($appInfo['settings'][IManager::KEY_PERSONAL_SECTION], '\\')); + } + if (isset($appInfo['settings'][IManager::KEY_PERSONAL_SETTINGS])) { + $this->mapper->remove(Mapper::TABLE_PERSONAL_SETTINGS, trim($appInfo['settings'][IManager::KEY_PERSONAL_SETTINGS], '\\')); } } public function checkForOrphanedClassNames() { - $tables = [self::TABLE_ADMIN_SECTIONS, self::TABLE_ADMIN_SETTINGS]; + $tables = [Mapper::TABLE_ADMIN_SECTIONS, Mapper::TABLE_ADMIN_SETTINGS, Mapper::TABLE_PERSONAL_SECTIONS, Mapper::TABLE_PERSONAL_SETTINGS]; foreach ($tables as $table) { $classes = $this->mapper->getClasses($table); foreach ($classes as $className) { @@ -167,10 +179,11 @@ class Manager implements IManager { /** * @param string $sectionClassName + * @param string $type either 'admin' or 'personal' */ - private function setupAdminSection($sectionClassName) { + private function setupSectionEntry($sectionClassName, $type) { if (!class_exists($sectionClassName)) { - $this->log->debug('Could not find admin section class ' . $sectionClassName); + $this->log->debug('Could not find ' . ucfirst($type) . ' section class ' . $sectionClassName); return; } try { @@ -182,37 +195,38 @@ class Manager implements IManager { if (!$section instanceof ISection) { $this->log->error( - 'Admin section instance must implement \OCP\ISection. Invalid class: {class}', + ucfirst($type) .' section instance must implement \OCP\ISection. Invalid class: {class}', ['class' => $sectionClassName] ); return; } - if (!$this->hasAdminSection(get_class($section))) { - $this->addAdminSection($section); + $table = $this->getSectionTableForType($type); + if(!$this->hasSection(get_class($section), $table)) { + $this->addSection($section, $table); } else { - $this->updateAdminSection($section); + $this->updateSection($section, $table); } } - private function addAdminSection(ISection $section) { - $this->mapper->add(self::TABLE_ADMIN_SECTIONS, [ + private function addSection(ISection $section, $table) { + $this->mapper->add($table, [ 'id' => $section->getID(), 'class' => get_class($section), 'priority' => $section->getPriority(), ]); } - private function addAdminSettings(ISettings $settings) { - $this->mapper->add(self::TABLE_ADMIN_SETTINGS, [ + private function addSettings(ISettings $settings, $table) { + $this->mapper->add($table, [ 'class' => get_class($settings), 'section' => $settings->getSection(), 'priority' => $settings->getPriority(), ]); } - private function updateAdminSettings(ISettings $settings) { + private function updateSettings(ISettings $settings, $table) { $this->mapper->update( - self::TABLE_ADMIN_SETTINGS, + $table, 'class', get_class($settings), [ @@ -222,9 +236,9 @@ class Manager implements IManager { ); } - private function updateAdminSection(ISection $section) { + private function updateSection(ISection $section, $table) { $this->mapper->update( - self::TABLE_ADMIN_SECTIONS, + $table, 'class', get_class($section), [ @@ -236,23 +250,24 @@ class Manager implements IManager { /** * @param string $className + * @param string $table * @return bool */ - private function hasAdminSection($className) { - return $this->mapper->has(self::TABLE_ADMIN_SECTIONS, $className); + private function hasSection($className, $table) { + return $this->mapper->has($table, $className); } /** * @param string $className * @return bool */ - private function hasAdminSettings($className) { - return $this->mapper->has(self::TABLE_ADMIN_SETTINGS, $className); + private function hasSettings($className, $table) { + return $this->mapper->has($table, $className); } - private function setupAdminSettings($settingsClassName) { + private function setupSettingsEntry($settingsClassName, $type) { if (!class_exists($settingsClassName)) { - $this->log->debug('Could not find admin section class ' . $settingsClassName); + $this->log->debug('Could not find ' . $type . ' section class ' . $settingsClassName); return; } @@ -266,18 +281,37 @@ class Manager implements IManager { if (!$settings instanceof ISettings) { $this->log->error( - 'Admin section instance must implement \OCP\Settings\ISection. Invalid class: {class}', + ucfirst($type) . ' section instance must implement \OCP\Settings\ISettings. Invalid class: {class}', ['class' => $settingsClassName] ); return; } - if (!$this->hasAdminSettings(get_class($settings))) { - $this->addAdminSettings($settings); + $table = $this->getSettingsTableForType($type); + if (!$this->hasSettings(get_class($settings), $table)) { + $this->addSettings($settings, $table); } else { - $this->updateAdminSettings($settings); + $this->updateSettings($settings, $table); } } + private function getSectionTableForType($type) { + if($type === 'admin') { + return Mapper::TABLE_ADMIN_SECTIONS; + } else if($type === 'personal') { + return Mapper::TABLE_PERSONAL_SECTIONS; + } + throw new \InvalidArgumentException('"admin" or "personal" expected'); + } + + private function getSettingsTableForType($type) { + if($type === 'admin') { + return Mapper::TABLE_ADMIN_SETTINGS; + } else if($type === 'personal') { + return Mapper::TABLE_PERSONAL_SETTINGS; + } + throw new \InvalidArgumentException('"admin" or "personal" expected'); + } + private function query($className) { try { return \OC::$server->query($className); @@ -423,7 +457,7 @@ class Manager implements IManager { 5 => [new Section('sessions', $this->l->t('Sessions'), 0, $this->url->imagePath('settings', 'admin.svg'))], 10 => [new Section('app-passwords', $this->l->t('App passwords'), 0, $this->url->imagePath('settings', 'password.svg'))], 15 => [new Section('sync-clients', $this->l->t('Sync clients'), 0, $this->url->imagePath('settings', 'change.svg'))], - + 98 => [new Section('additional', $this->l->t('Additional settings'), 0, $this->url->imagePath('core', 'actions/settings-dark.svg'))], ]; return $sections; } diff --git a/lib/private/Settings/Mapper.php b/lib/private/Settings/Mapper.php index 7dea1fe3d8..44ba7dd9cb 100644 --- a/lib/private/Settings/Mapper.php +++ b/lib/private/Settings/Mapper.php @@ -28,6 +28,8 @@ use OCP\IDBConnection; class Mapper { const TABLE_ADMIN_SETTINGS = 'admin_settings'; const TABLE_ADMIN_SECTIONS = 'admin_sections'; + const TABLE_PERSONAL_SETTINGS = 'personal_settings'; + const TABLE_PERSONAL_SECTIONS = 'personal_sections'; /** @var IDBConnection */ private $dbc; @@ -46,9 +48,30 @@ class Mapper { * @return array[] [['class' => string, 'priority' => int], ...] */ public function getAdminSettingsFromDB($section) { + return $this->getSettingsFromDB(self::TABLE_ADMIN_SETTINGS, $section); + } + + /** + * Get the configured personal settings from the database for the provided section + * + * @param string $section + * @return array[] [['class' => string, 'priority' => int], ...] + */ + public function getPersonalSettingsFromDB($section) { + return $this->getSettingsFromDB(self::TABLE_PERSONAL_SETTINGS, $section); + } + + /** + * Get the configured settings from the database for the provided table and section + * + * @param $table + * @param $section + * @return array + */ + private function getSettingsFromDB($table, $section) { $query = $this->dbc->getQueryBuilder(); $query->select(['class', 'priority']) - ->from(self::TABLE_ADMIN_SETTINGS) + ->from($table) ->where($query->expr()->eq('section', $this->dbc->getQueryBuilder()->createParameter('section'))) ->setParameter('section', $section); @@ -76,7 +99,7 @@ class Mapper { } /** - * @param string $table Mapper::TABLE_ADMIN_SECTIONS or Mapper::TABLE_ADMIN_SETTINGS + * @param string $table one of the Mapper::TABLE_* constants * @param array $values */ public function add($table, array $values) { @@ -91,7 +114,7 @@ class Mapper { /** * returns the registered classes in the given table * - * @param $table Mapper::TABLE_ADMIN_SECTIONS or Mapper::TABLE_ADMIN_SETTINGS + * @param string $table one of the Mapper::TABLE_* constants * @return string[] */ public function getClasses($table) { @@ -110,7 +133,7 @@ class Mapper { /** * Check if a class is configured in the database * - * @param string $table Mapper::TABLE_ADMIN_SECTIONS or Mapper::TABLE_ADMIN_SETTINGS + * @param string $table one of the Mapper::TABLE_* constants * @param string $className * @return bool */ @@ -131,8 +154,8 @@ class Mapper { /** * deletes an settings or admin entry from the given table * - * @param $table Mapper::TABLE_ADMIN_SECTIONS or Mapper::TABLE_ADMIN_SETTINGS - * @param $className + * @param string $table one of the Mapper::TABLE_* constants + * @param string $className */ public function remove($table, $className) { $query = $this->dbc->getQueryBuilder(); @@ -143,7 +166,7 @@ class Mapper { } /** - * @param string $table Mapper::TABLE_ADMIN_SECTIONS or Mapper::TABLE_ADMIN_SETTINGS + * @param string $table one of the Mapper::TABLE_* constants * @param string $idCol * @param string $id * @param array $values diff --git a/lib/public/Settings/IManager.php b/lib/public/Settings/IManager.php index 2c99239926..1242f83515 100644 --- a/lib/public/Settings/IManager.php +++ b/lib/public/Settings/IManager.php @@ -37,6 +37,16 @@ interface IManager { */ const KEY_ADMIN_SECTION = 'admin-section'; + /** + * @since 12.0.0 + */ + const KEY_PERSONAL_SETTINGS = 'personal'; + + /** + * @since 12.0.0 + */ + const KEY_PERSONAL_SECTION = 'personal-section'; + /** * sets up settings according to data specified by an apps info.xml, within * the element. diff --git a/version.php b/version.php index e237770c82..d9e26eafce 100644 --- a/version.php +++ b/version.php @@ -26,7 +26,7 @@ // between betas, final and RCs. This is _not_ the public version number. Reset minor/patchlevel // when updating major/minor version number. -$OC_Version = array(13, 0, 0, 0); +$OC_Version = array(13, 0, 0, 1); // The human readable string $OC_VersionString = '13.0.0 alpha'; From 3dca4de8b385b34eb2c2a910b61e44b00f094334 Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Fri, 19 May 2017 12:57:45 +0200 Subject: [PATCH 12/42] add Additional (+ Fallback) section for Personal settings Signed-off-by: Arthur Schiwon --- lib/private/Settings/Manager.php | 5 ++ lib/private/Settings/Personal/Additional.php | 59 +++++++++++++++++++ .../Controller/AdminSettingsController.php | 2 +- .../Controller/PersonalSettingsController.php | 37 +++++++++++- .../{admin => settings}/additional.php | 0 settings/templates/settings/empty.php | 26 ++++++++ 6 files changed, 127 insertions(+), 2 deletions(-) create mode 100644 lib/private/Settings/Personal/Additional.php rename settings/templates/{admin => settings}/additional.php (100%) create mode 100644 settings/templates/settings/empty.php diff --git a/lib/private/Settings/Manager.php b/lib/private/Settings/Manager.php index 707550c0bb..62a74b706f 100644 --- a/lib/private/Settings/Manager.php +++ b/lib/private/Settings/Manager.php @@ -420,6 +420,11 @@ class Manager implements IManager { $form = new Personal\SyncClients($this->config, $this->defaults); $forms[$form->getPriority()] = [$form]; } + if ($section === 'additional') { + /** @var ISettings $form */ + $form = new Personal\Additional($this->config); + $forms[$form->getPriority()] = [$form]; + } } catch (QueryException $e) { // skip } diff --git a/lib/private/Settings/Personal/Additional.php b/lib/private/Settings/Personal/Additional.php new file mode 100644 index 0000000000..b2bb26dc6b --- /dev/null +++ b/lib/private/Settings/Personal/Additional.php @@ -0,0 +1,59 @@ + + * + * @author Arthur Schiwon + * + * @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 OC\Settings\Personal; + + +use OCP\AppFramework\Http\TemplateResponse; +use OCP\Settings\ISettings; + +class Additional implements ISettings { + + /** + * @return TemplateResponse returns the instance with all parameters set, ready to be rendered + * @since 9.1 + */ + public function getForm() { + return new TemplateResponse('settings', 'settings/empty'); + } + + /** + * @return string the section ID, e.g. 'sharing' + * @since 9.1 + */ + public function getSection() { + return 'additional'; + } + + /** + * @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. + * + * E.g.: 70 + * @since 9.1 + */ + public function getPriority() { + return '5'; + } +} diff --git a/settings/Controller/AdminSettingsController.php b/settings/Controller/AdminSettingsController.php index fb8b65d93a..087700ee55 100644 --- a/settings/Controller/AdminSettingsController.php +++ b/settings/Controller/AdminSettingsController.php @@ -108,7 +108,7 @@ class AdminSettingsController extends Controller { ); }, $forms); - $out = new Template('settings', 'admin/additional'); + $out = new Template('settings', 'settings/additional'); $out->assign('forms', $forms); return $out->fetchPage(); diff --git a/settings/Controller/PersonalSettingsController.php b/settings/Controller/PersonalSettingsController.php index 546af54a7f..11bd9a9d94 100644 --- a/settings/Controller/PersonalSettingsController.php +++ b/settings/Controller/PersonalSettingsController.php @@ -28,6 +28,7 @@ use OCP\AppFramework\Http\TemplateResponse; use OCP\INavigationManager; use OCP\IRequest; use OCP\Settings\IManager as ISettingsManager; +use OCP\Template; class PersonalSettingsController extends Controller { use CommonSettingsTrait { @@ -68,6 +69,40 @@ class PersonalSettingsController extends Controller { private function getSettings($section) { // PhpStorm shows this as unused, but is required by CommonSettingsTrait $settings = $this->settingsManager->getPersonalSettings($section); - return $this->formatSettings($settings); + $formatted = $this->formatSettings($settings); + if($section === 'additional') { + $formatted['content'] .= $this->getLegacyForms(); + } + return $formatted; + } + + /** + * @return bool|string + */ + private function getLegacyForms() { + $forms = \OC_App::getForms('personal'); + + $forms = array_map(function ($form) { + if (preg_match('%([^>]*)>.*?)%i', $form, $regs)) { + $sectionName = str_replace('', '', $regs[0]); + $sectionName = str_replace('', '', $sectionName); + $anchor = strtolower($sectionName); + $anchor = str_replace(' ', '-', $anchor); + + return array( + 'anchor' => $anchor, + 'section-name' => $sectionName, + 'form' => $form + ); + } + return array( + 'form' => $form + ); + }, $forms); + + $out = new Template('settings', 'settings/additional'); + $out->assign('forms', $forms); + + return $out->fetchPage(); } } diff --git a/settings/templates/admin/additional.php b/settings/templates/settings/additional.php similarity index 100% rename from settings/templates/admin/additional.php rename to settings/templates/settings/additional.php diff --git a/settings/templates/settings/empty.php b/settings/templates/settings/empty.php new file mode 100644 index 0000000000..e7e728f87b --- /dev/null +++ b/settings/templates/settings/empty.php @@ -0,0 +1,26 @@ + + * + * @author Arthur Schiwon + * + * @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 . + * + */ + +?> + + From f87318296578178ceed8ba18c0a3f99e4aa11334 Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Fri, 19 May 2017 16:30:31 +0200 Subject: [PATCH 13/42] remove obsolete files Signed-off-by: Arthur Schiwon --- settings/js/personal.js | 444 ------------------ settings/personal.php | 281 ----------- .../settings/personal/personal.info.php | 3 - 3 files changed, 728 deletions(-) delete mode 100644 settings/js/personal.js delete mode 100644 settings/personal.php diff --git a/settings/js/personal.js b/settings/js/personal.js deleted file mode 100644 index effce9de07..0000000000 --- a/settings/js/personal.js +++ /dev/null @@ -1,444 +0,0 @@ -/* global OC */ - -/** - * Copyright (c) 2011, Robin Appelman - * 2013, Morris Jobke - * 2016, Christoph Wurst - * This file is licensed under the Affero General Public License version 3 or later. - * See the COPYING-README file. - */ - -OC.Settings = OC.Settings || {}; - -/** - * The callback will be fired as soon as enter is pressed by the - * user or 1 second after the last data entry - * - * @param callback - * @param allowEmptyValue if this is set to true the callback is also called when the value is empty - */ -jQuery.fn.keyUpDelayedOrEnter = function (callback, allowEmptyValue) { - var cb = callback; - var that = this; - - this.on('input', _.debounce(function (event) { - // enter is already handled in keypress - if (event.keyCode === 13) { - return; - } - if (allowEmptyValue || that.val() !== '') { - cb(event); - } - }, 1000)); - - this.keypress(function (event) { - if (event.keyCode === 13 && (allowEmptyValue || that.val() !== '')) { - event.preventDefault(); - cb(event); - } - }); -}; - -function updateAvatar (hidedefault) { - var $headerdiv = $('#header .avatardiv'); - var $displaydiv = $('#displayavatar .avatardiv'); - - //Bump avatar avatarversion - oc_userconfig.avatar.version = -(Math.floor(Math.random() * 1000)); - - if (hidedefault) { - $headerdiv.hide(); - $('#header .avatardiv').removeClass('avatardiv-shown'); - } else { - $headerdiv.css({'background-color': ''}); - $headerdiv.avatar(OC.currentUser, 32, true); - $('#header .avatardiv').addClass('avatardiv-shown'); - } - $displaydiv.css({'background-color': ''}); - $displaydiv.avatar(OC.currentUser, 145, true, null, function() { - $displaydiv.removeClass('loading'); - $('#displayavatar img').show(); - if($('#displayavatar img').length === 0) { - $('#removeavatar').removeClass('inlineblock').addClass('hidden'); - } else { - $('#removeavatar').removeClass('hidden').addClass('inlineblock'); - } - }); -} - -function showAvatarCropper () { - var $cropper = $('#cropper'); - var $cropperImage = $(''); - $cropperImage.css('opacity', 0); // prevent showing the unresized image - $cropper.children('.inner-container').prepend($cropperImage); - - $cropperImage.attr('src', - OC.generateUrl('/avatar/tmp') + '?requesttoken=' + encodeURIComponent(oc_requesttoken) + '#' + Math.floor(Math.random() * 1000)); - - $cropperImage.load(function () { - var img = $cropperImage.get()[0]; - var selectSize = Math.min(img.width, img.height); - var offsetX = (img.width - selectSize) / 2; - var offsetY = (img.height - selectSize) / 2; - $cropperImage.Jcrop({ - onChange: saveCoords, - onSelect: saveCoords, - aspectRatio: 1, - boxHeight: Math.min(500, $('#app-content').height() -100), - boxWidth: Math.min(500, $('#app-content').width()), - setSelect: [offsetX, offsetY, selectSize, selectSize] - }, function() { - $cropper.show(); - }); - }); -} - -function sendCropData () { - cleanCropper(); - - var cropperData = $('#cropper').data(); - var data = { - x: cropperData.x, - y: cropperData.y, - w: cropperData.w, - h: cropperData.h - }; - $.post(OC.generateUrl('/avatar/cropped'), {crop: data}, avatarResponseHandler); -} - -function saveCoords (c) { - $('#cropper').data(c); -} - -function cleanCropper () { - var $cropper = $('#cropper'); - $('#displayavatar').show(); - $cropper.hide(); - $('.jcrop-holder').remove(); - $('#cropper img').removeData('Jcrop').removeAttr('style').removeAttr('src'); - $('#cropper img').remove(); -} - -function avatarResponseHandler (data) { - if (typeof data === 'string') { - data = JSON.parse(data); - } - var $warning = $('#avatarform .warning'); - $warning.hide(); - if (data.status === "success") { - updateAvatar(); - } else if (data.data === "notsquare") { - showAvatarCropper(); - } else { - $warning.show(); - $warning.text(data.data.message); - } -} - -$(document).ready(function () { - if($('#pass2').length) { - $('#pass2').showPassword().keyup(); - } - - var removeloader = function () { - setTimeout(function(){ - if ($('.password-state').length > 0) { - $('.password-state').remove(); - } - }, 5000) - }; - - $("#passwordbutton").click(function () { - var isIE8or9 = $('html').hasClass('lte9'); - // FIXME - TODO - once support for IE8 and IE9 is dropped - // for IE8 and IE9 this will check additionally if the typed in password - // is different from the placeholder, because in IE8/9 the placeholder - // is simply set as the value to look like a placeholder - if ($('#pass1').val() !== '' && $('#pass2').val() !== '' - && !(isIE8or9 && $('#pass2').val() === $('#pass2').attr('placeholder'))) { - // Serialize the data - var post = $("#passwordform").serialize(); - $('#passwordchanged').hide(); - $('#passworderror').hide(); - $("#passwordbutton").attr('disabled', 'disabled'); - $("#passwordbutton").after(""); - $(".personal-show-label").hide(); - // Ajax foo - $.post(OC.generateUrl('/settings/personal/changepassword'), post, function (data) { - if (data.status === "success") { - $("#passwordbutton").after(""); - removeloader(); - $(".personal-show-label").show(); - $('#pass1').val(''); - $('#pass2').val('').change(); - } - if (typeof(data.data) !== "undefined") { - OC.msg.finishedSaving('#password-error-msg', data); - } else { - OC.msg.finishedSaving('#password-error-msg', - { - 'status' : 'error', - 'data' : { - 'message' : t('core', 'Unable to change password') - } - } - ); - } - $(".password-loading").remove(); - $("#passwordbutton").removeAttr('disabled'); - }); - return false; - } else { - OC.msg.finishedSaving('#password-error-msg', - { - 'status' : 'error', - 'data' : { - 'message' : t('core', 'Unable to change password') - } - } - ); - return false; - } - }); - - var showVerifyDialog = function(dialog, howToVerify, verificationCode) { - var dialogContent = dialog.children('.verification-dialog-content'); - dialogContent.children(".explainVerification").text(howToVerify); - dialogContent.children(".verificationCode").text(verificationCode); - dialog.css('display', 'block'); - }; - - $(".verify").click(function (event) { - - event.stopPropagation(); - - var verify = $(this); - var indicator = $(this).children('img'); - var accountId = indicator.attr('id'); - var status = indicator.data('status'); - - var onlyVerificationCode = false; - if (parseInt(status) === 1) { - onlyVerificationCode = true; - } - - if (indicator.hasClass('verify-action')) { - $.ajax( - OC.generateUrl('/settings/users/{account}/verify', {account: accountId}), - { - method: 'GET', - data: {onlyVerificationCode: onlyVerificationCode} - } - ).done(function (data) { - var dialog = verify.children('.verification-dialog'); - showVerifyDialog($(dialog), data.msg, data.code); - indicator.attr('data-origin-title', t('core', 'Verifying …')); - indicator.attr('src', OC.imagePath('core', 'actions/verifying.svg')); - indicator.data('status', '1'); - }); - } - - }); - - // When the user clicks anywhere outside of the verification dialog we close it - $(document).click(function(event){ - var element = event.target; - var isDialog = $(element).hasClass('verificationCode') - || $(element).hasClass('explainVerification') - || $(element).hasClass('verification-dialog-content') - || $(element).hasClass('verification-dialog'); - if (!isDialog) { - $(document).find('.verification-dialog').css('display', 'none'); - } - }); - - - var federationSettingsView = new OC.Settings.FederationSettingsView({ - el: '#personal-settings' - }); - federationSettingsView.render(); - - var updateLanguage = function () { - if (OC.PasswordConfirmation.requiresPasswordConfirmation()) { - OC.PasswordConfirmation.requirePasswordConfirmation(updateLanguage); - return; - } - - var selectedLang = $("#languageinput").val(), - user = OC.getCurrentUser(); - - $.ajax({ - url: OC.linkToOCS('cloud/users', 2) + user['uid'], - method: 'PUT', - data: { - key: 'language', - value: selectedLang - }, - success: function() { - location.reload(); - }, - fail: function() { - OC.Notification.showTemporary(t('settings', 'An error occured while changing your language. Please reload the page and try again.')); - } - }); - }; - $("#languageinput").change(updateLanguage); - - var uploadparms = { - pasteZone: null, - done: function (e, data) { - var response = data; - if (typeof data.result === 'string') { - response = JSON.parse(data.result); - } else if (data.result && data.result.length) { - // fetch response from iframe - response = JSON.parse(data.result[0].body.innerText); - } else { - response = data.result; - } - avatarResponseHandler(response); - }, - submit: function(e, data) { - $('#displayavatar img').hide(); - $('#displayavatar .avatardiv').addClass('loading'); - data.formData = _.extend(data.formData || {}, { - requesttoken: OC.requestToken - }); - }, - fail: function (e, data){ - var msg = data.jqXHR.statusText + ' (' + data.jqXHR.status + ')'; - if (!_.isUndefined(data.jqXHR.responseJSON) && - !_.isUndefined(data.jqXHR.responseJSON.data) && - !_.isUndefined(data.jqXHR.responseJSON.data.message) - ) { - msg = data.jqXHR.responseJSON.data.message; - } - avatarResponseHandler({ - data: { - message: msg - } - }); - } - }; - - $('#uploadavatar').fileupload(uploadparms); - - $('#selectavatar').click(function () { - OC.dialogs.filepicker( - t('settings', "Select a profile picture"), - function (path) { - $('#displayavatar img').hide(); - $('#displayavatar .avatardiv').addClass('loading'); - $.ajax({ - type: "POST", - url: OC.generateUrl('/avatar/'), - data: { path: path } - }).done(avatarResponseHandler) - .fail(function(jqXHR) { - var msg = jqXHR.statusText + ' (' + jqXHR.status + ')'; - if (!_.isUndefined(jqXHR.responseJSON) && - !_.isUndefined(jqXHR.responseJSON.data) && - !_.isUndefined(jqXHR.responseJSON.data.message) - ) { - msg = jqXHR.responseJSON.data.message; - } - avatarResponseHandler({ - data: { - message: msg - } - }); - }); - }, - false, - ["image/png", "image/jpeg"] - ); - }); - - $('#removeavatar').click(function () { - $.ajax({ - type: 'DELETE', - url: OC.generateUrl('/avatar/'), - success: function () { - updateAvatar(true); - } - }); - }); - - $('#abortcropperbutton').click(function () { - $('#displayavatar .avatardiv').removeClass('loading'); - $('#displayavatar img').show(); - cleanCropper(); - }); - - $('#sendcropperbutton').click(function () { - sendCropData(); - }); - - $('#pass2').strengthify({ - zxcvbn: OC.linkTo('core','vendor/zxcvbn/dist/zxcvbn.js'), - titles: [ - t('core', 'Very weak password'), - t('core', 'Weak password'), - t('core', 'So-so password'), - t('core', 'Good password'), - t('core', 'Strong password') - ], - drawTitles: true, - }); - - // Load the big avatar - $('#avatarform .avatardiv').avatar(OC.currentUser, 145, true, null, function() { - if($('#displayavatar img').length === 0) { - $('#removeavatar').removeClass('inlineblock').addClass('hidden'); - } else { - $('#removeavatar').removeClass('hidden').addClass('inlineblock'); - } - }); - - - // Show token views - var collection = new OC.Settings.AuthTokenCollection(); - var view = new OC.Settings.AuthTokenView({ - collection: collection - }); - view.reload(); - - // 'redirect' to anchor sections - // anchors are lost on redirects (e.g. while solving the 2fa challenge) otherwise - // example: /settings/person?section=devices will result in /settings/person?#devices - if (!window.location.hash) { - var query = OC.parseQueryString(location.search); - if (query && query.section) { - OC.Util.History.replaceState({}); - window.location.hash = query.section; - } - } -}); - -if (!OC.Encryption) { - OC.Encryption = {}; -} - -OC.Encryption.msg = { - start: function (selector, msg) { - var spinner = ''; - $(selector) - .html(msg + ' ' + spinner) - .removeClass('success') - .removeClass('error') - .stop(true, true) - .show(); - }, - finished: function (selector, data) { - if (data.status === "success") { - $(selector).html(data.data.message) - .addClass('success') - .stop(true, true) - .delay(3000); - } else { - $(selector).html(data.data.message).addClass('error'); - } - } -}; - -OC.Settings.updateAvatar = updateAvatar; diff --git a/settings/personal.php b/settings/personal.php deleted file mode 100644 index fcccbc5055..0000000000 --- a/settings/personal.php +++ /dev/null @@ -1,281 +0,0 @@ - - * @author Bart Visscher - * @author Björn Schießle - * @author Christopher Schäpers - * @author Christoph Wurst - * @author Georg Ehrke - * @author Jakob Sack - * @author Jan-Christoph Borchardt - * @author Joas Schilling - * @author Lukas Reschke - * @author Marvin Thomas Rabe - * @author Morris Jobke - * @author Robin Appelman - * @author Roeland Jago Douma - * @author Thomas Müller - * @author Vincent Petry - * @author Volkan Gezer - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * 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, version 3, - * along with this program. If not, see - * - */ - -OC_Util::checkLoggedIn(); - -$defaults = \OC::$server->getThemingDefaults(); -$certificateManager = \OC::$server->getCertificateManager(); -$accountManager = new \OC\Accounts\AccountManager( - \OC::$server->getDatabaseConnection(), - \OC::$server->getEventDispatcher(), - \OC::$server->getJobList() -); -$config = \OC::$server->getConfig(); -$urlGenerator = \OC::$server->getURLGenerator(); - -// Highlight navigation entry -OC_Util::addScript('settings', 'authtoken'); -OC_Util::addScript('settings', 'authtoken_collection'); -OC_Util::addScript('settings', 'authtoken_view'); -OC_Util::addScript('settings', 'usersettings'); -OC_Util::addScript('settings', 'federationsettingsview'); -OC_Util::addScript('settings', 'federationscopemenu'); -OC_Util::addScript('settings', 'personal'); -OC_Util::addScript('settings', 'certificates'); -OC_Util::addStyle( 'settings', 'settings' ); -\OC_Util::addVendorScript('strengthify/jquery.strengthify'); -\OC_Util::addVendorStyle('strengthify/strengthify'); -\OC_Util::addScript('files', 'jquery.fileupload'); -\OC_Util::addVendorScript('jcrop/js/jquery.Jcrop'); -\OC_Util::addVendorStyle('jcrop/css/jquery.Jcrop'); - -\OC::$server->getEventDispatcher()->dispatch('OC\Settings\Personal::loadAdditionalScripts'); - -// Highlight navigation entry -OC::$server->getNavigationManager()->setActiveEntry('personal'); - -$storageInfo=OC_Helper::getStorageInfo('/'); - -$user = OC::$server->getUserManager()->get(OC_User::getUser()); - -$forceLanguage = $config->getSystemValue('force_language', false); -if ($forceLanguage === false) { - $userLang=$config->getUserValue( OC_User::getUser(), 'core', 'lang', \OC::$server->getL10NFactory()->findLanguage() ); - $languageCodes = \OC::$server->getL10NFactory()->findAvailableLanguages(); - - // array of common languages - $commonLangCodes = array( - 'en', 'es', 'fr', 'de', 'de_DE', 'ja', 'ar', 'ru', 'nl', 'it', 'pt_BR', 'pt_PT', 'da', 'fi_FI', 'nb_NO', 'sv', 'tr', 'zh_CN', 'ko' - ); - - $languages=array(); - $commonLanguages = array(); - foreach($languageCodes as $lang) { - $l = \OC::$server->getL10N('settings', $lang); - // TRANSLATORS this is the language name for the language switcher in the personal settings and should be the localized version - $potentialName = (string) $l->t('__language_name__'); - if($l->getLanguageCode() === $lang && substr($potentialName, 0, 1) !== '_') {//first check if the language name is in the translation file - $ln = array('code' => $lang, 'name' => $potentialName); - } elseif ($lang === 'en') { - $ln = ['code' => $lang, 'name' => 'English (US)']; - }else{//fallback to language code - $ln=array('code'=>$lang, 'name'=>$lang); - } - - // put appropriate languages into appropriate arrays, to print them sorted - // used language -> common languages -> divider -> other languages - if ($lang === $userLang) { - $userLang = $ln; - } elseif (in_array($lang, $commonLangCodes)) { - $commonLanguages[array_search($lang, $commonLangCodes)]=$ln; - } else { - $languages[]=$ln; - } - } - - // if user language is not available but set somehow: show the actual code as name - if (!is_array($userLang)) { - $userLang = [ - 'code' => $userLang, - 'name' => $userLang, - ]; - } - - ksort($commonLanguages); - - // sort now by displayed language not the iso-code - usort( $languages, function ($a, $b) { - if ($a['code'] === $a['name'] && $b['code'] !== $b['name']) { - // If a doesn't have a name, but b does, list b before a - return 1; - } - if ($a['code'] !== $a['name'] && $b['code'] === $b['name']) { - // If a does have a name, but b doesn't, list a before b - return -1; - } - // Otherwise compare the names - return strcmp($a['name'], $b['name']); - }); -} - -//links to clients -$clients = array( - 'desktop' => $config->getSystemValue('customclient_desktop', $defaults->getSyncClientUrl()), - 'android' => $config->getSystemValue('customclient_android', $defaults->getAndroidClientUrl()), - 'ios' => $config->getSystemValue('customclient_ios', $defaults->getiOSClientUrl()) -); - -// only show root certificate import if external storages are enabled -$enableCertImport = false; -$externalStorageEnabled = \OC::$server->getAppManager()->isEnabledForUser('files_external'); -if ($externalStorageEnabled) { - /** @var \OCA\Files_External\Service\BackendService $backendService */ - $backendService = \OC_Mount_Config::$app->getContainer()->query('\OCA\Files_External\Service\BackendService'); - $enableCertImport = $backendService->isUserMountingAllowed(); -} - - -// Return template -$l = \OC::$server->getL10N('settings'); -$tmpl = new OC_Template( 'settings', 'personal', 'user'); -$tmpl->assign('usage', OC_Helper::humanFileSize($storageInfo['used'])); -if ($storageInfo['quota'] === \OCP\Files\FileInfo::SPACE_UNLIMITED) { - $totalSpace = $l->t('Unlimited'); -} else { - $totalSpace = OC_Helper::humanFileSize($storageInfo['total']); -} - -$uid = $user->getUID(); -$userData = $accountManager->getUser($user); - -$tmpl->assign('total_space', $totalSpace); -$tmpl->assign('usage_relative', $storageInfo['relative']); -$tmpl->assign('quota', $storageInfo['quota']); -$tmpl->assign('clients', $clients); -$tmpl->assign('email', $userData[\OC\Accounts\AccountManager::PROPERTY_EMAIL]['value']); -if ($forceLanguage === false) { - $tmpl->assign('languages', $languages); - $tmpl->assign('commonlanguages', $commonLanguages); - $tmpl->assign('activelanguage', $userLang); -} -$tmpl->assign('passwordChangeSupported', OC_User::canUserChangePassword(OC_User::getUser())); -$tmpl->assign('displayNameChangeSupported', OC_User::canUserChangeDisplayName(OC_User::getUser())); -$tmpl->assign('displayName', $userData[\OC\Accounts\AccountManager::PROPERTY_DISPLAYNAME]['value']); - -$tmpl->assign('phone', $userData[\OC\Accounts\AccountManager::PROPERTY_PHONE]['value']); -$tmpl->assign('website', $userData[\OC\Accounts\AccountManager::PROPERTY_WEBSITE]['value']); -$tmpl->assign('twitter', $userData[\OC\Accounts\AccountManager::PROPERTY_TWITTER]['value']); -$tmpl->assign('address', $userData[\OC\Accounts\AccountManager::PROPERTY_ADDRESS]['value']); - -$tmpl->assign('avatarScope', $userData[\OC\Accounts\AccountManager::PROPERTY_AVATAR]['scope']); -$tmpl->assign('displayNameScope', $userData[\OC\Accounts\AccountManager::PROPERTY_DISPLAYNAME]['scope']); -$tmpl->assign('phoneScope', $userData[\OC\Accounts\AccountManager::PROPERTY_PHONE]['scope']); -$tmpl->assign('emailScope', $userData[\OC\Accounts\AccountManager::PROPERTY_EMAIL]['scope']); -$tmpl->assign('websiteScope', $userData[\OC\Accounts\AccountManager::PROPERTY_WEBSITE]['scope']); -$tmpl->assign('twitterScope', $userData[\OC\Accounts\AccountManager::PROPERTY_TWITTER]['scope']); -$tmpl->assign('addressScope', $userData[\OC\Accounts\AccountManager::PROPERTY_ADDRESS]['scope']); - -$tmpl->assign('websiteVerification', $userData[\OC\Accounts\AccountManager::PROPERTY_WEBSITE]['verified']); -$tmpl->assign('twitterVerification', $userData[\OC\Accounts\AccountManager::PROPERTY_TWITTER]['verified']); -$tmpl->assign('emailVerification', $userData[\OC\Accounts\AccountManager::PROPERTY_EMAIL]['verified']); - -$needVerifyMessage = [\OC\Accounts\AccountManager::PROPERTY_EMAIL, \OC\Accounts\AccountManager::PROPERTY_WEBSITE, \OC\Accounts\AccountManager::PROPERTY_TWITTER]; - -foreach ($needVerifyMessage as $property) { - - switch ($userData[$property]['verified']) { - case \OC\Accounts\AccountManager::VERIFIED: - $message = $l->t('Verifying'); - break; - case \OC\Accounts\AccountManager::VERIFICATION_IN_PROGRESS: - $message = $l->t('Verifying …'); - break; - default: - $message = $l->t('Verify'); - } - - $tmpl->assign($property . 'Message', $message); -} - -$tmpl->assign('avatarChangeSupported', OC_User::canUserChangeAvatar(OC_User::getUser())); -$tmpl->assign('certs', $certificateManager->listCertificates()); -$tmpl->assign('showCertificates', $enableCertImport); -$tmpl->assign('urlGenerator', $urlGenerator); - -$federatedFileSharingEnabled = \OC::$server->getAppManager()->isEnabledForUser('federatedfilesharing'); -$lookupServerUploadEnabled = false; -if ($federatedFileSharingEnabled) { - $federatedFileSharing = new \OCA\FederatedFileSharing\AppInfo\Application(); - $shareProvider = $federatedFileSharing->getFederatedShareProvider(); - $lookupServerUploadEnabled = $shareProvider->isLookupServerUploadEnabled(); -} - -$tmpl->assign('lookupServerUploadEnabled', $lookupServerUploadEnabled); - -// Get array of group ids for this user -$groups = \OC::$server->getGroupManager()->getUserIdGroups(OC_User::getUser()); -$groups2 = array_map(function($group) { return $group->getGID(); }, $groups); -sort($groups2); -$tmpl->assign('groups', $groups2); - -// add hardcoded forms from the template -$formsAndMore = []; -$formsAndMore[]= ['anchor' => 'personal-settings', 'section-name' => $l->t('Personal info')]; -$formsAndMore[]= ['anchor' => 'security', 'section-name' => $l->t('Security')]; -$formsAndMore[]= ['anchor' => 'clientsbox', 'section-name' => $l->t('Sync clients')]; - -$forms=OC_App::getForms('personal'); - - -// add bottom hardcoded forms from the template -if ($enableCertImport) { - $certificatesTemplate = new OC_Template('settings', 'certificates'); - $certificatesTemplate->assign('type', 'personal'); - $certificatesTemplate->assign('uploadRoute', 'settings.Certificate.addPersonalRootCertificate'); - $certificatesTemplate->assign('certs', $certificateManager->listCertificates()); - $certificatesTemplate->assign('urlGenerator', $urlGenerator); - $forms[] = $certificatesTemplate->fetchPage(); -} - -$formsMap = array_map(function($form){ - if (preg_match('%([^>]*)>.*?)%i', $form, $regs)) { - $sectionName = str_replace('', '', $regs[0]); - $sectionName = str_replace('', '', $sectionName); - if (strpos($regs['class'], 'data-anchor-name') !== false) { - preg_match('%.*data-anchor-name="(?P[^"]*)"%i', $regs['class'], $matches); - $anchor = $matches['anchor']; - } else { - $anchor = strtolower($sectionName); - $anchor = str_replace(' ', '-', $anchor); - } - - return array( - 'anchor' => $anchor, - 'section-name' => $sectionName, - 'form' => $form - ); - } - return array( - 'form' => $form - ); -}, $forms); - -$formsAndMore = array_merge($formsAndMore, $formsMap); - -$tmpl->assign('forms', $formsAndMore); -$tmpl->printPage(); diff --git a/settings/templates/settings/personal/personal.info.php b/settings/templates/settings/personal/personal.info.php index 9fe0e546db..8cb9aec8af 100644 --- a/settings/templates/settings/personal/personal.info.php +++ b/settings/templates/settings/personal/personal.info.php @@ -35,9 +35,6 @@ vendor_style('strengthify/strengthify'); vendor_script('jcrop/js/jquery.Jcrop'); vendor_style('jcrop/css/jquery.Jcrop'); -//TODO: delete js/personal.js once the Encryption and AuthToken things are, -// where they belong - ?>
    From 28fd18de43ee4371c614782a2a4b9cf0eb497faa Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Fri, 19 May 2017 17:34:57 +0200 Subject: [PATCH 14/42] add missing pieces to Settings Manager and fix and extend its unit tests Signed-off-by: Arthur Schiwon --- lib/private/Settings/Manager.php | 30 +++++++ lib/private/Settings/Mapper.php | 32 ++++++- tests/lib/Settings/ManagerTest.php | 130 ++++++++++++++++++++++++++--- 3 files changed, 180 insertions(+), 12 deletions(-) diff --git a/lib/private/Settings/Manager.php b/lib/private/Settings/Manager.php index 62a74b706f..7da8bfe65d 100644 --- a/lib/private/Settings/Manager.php +++ b/lib/private/Settings/Manager.php @@ -464,6 +464,22 @@ class Manager implements IManager { 15 => [new Section('sync-clients', $this->l->t('Sync clients'), 0, $this->url->imagePath('settings', 'change.svg'))], 98 => [new Section('additional', $this->l->t('Additional settings'), 0, $this->url->imagePath('core', 'actions/settings-dark.svg'))], ]; + + $rows = $this->mapper->getPersonalSectionsFromDB(); + + foreach ($rows as $row) { + if (!isset($sections[$row['priority']])) { + $sections[$row['priority']] = []; + } + try { + $sections[$row['priority']][] = $this->query($row['class']); + } catch (QueryException $e) { + // skip + } + } + + ksort($sections); + return $sections; } @@ -472,6 +488,20 @@ class Manager implements IManager { */ public function getPersonalSettings($section) { $settings = $this->getBuiltInPersonalSettings($section); + $dbRows = $this->mapper->getPersonalSettingsFromDB($section); + + foreach ($dbRows as $row) { + if (!isset($settings[$row['priority']])) { + $settings[$row['priority']] = []; + } + try { + $settings[$row['priority']][] = $this->query($row['class']); + } catch (QueryException $e) { + // skip + } + } + + ksort($settings); return $settings; } } diff --git a/lib/private/Settings/Mapper.php b/lib/private/Settings/Mapper.php index 44ba7dd9cb..999efb0d87 100644 --- a/lib/private/Settings/Mapper.php +++ b/lib/private/Settings/Mapper.php @@ -85,11 +85,39 @@ class Mapper { * @return array[] [['class' => string, 'priority' => int], ...] */ public function getAdminSectionsFromDB() { + return $this->getSectionsFromDB('admin'); + } + + /** + * Get the configured admin sections from the database + * + * @return array[] [['class' => string, 'priority' => int], ...] + */ + public function getPersonalSectionsFromDB() { + return $this->getSectionsFromDB('personal'); + } + + /** + * Get the configured sections from the database by table + * + * @param string $type either 'personal' or 'admin' + * @return array[] [['class' => string, 'priority' => int], ...] + */ + public function getSectionsFromDB($type) { + if($type === 'personal') { + $sectionsTable = self::TABLE_ADMIN_SECTIONS; + $settingsTable = self::TABLE_ADMIN_SETTINGS; + } else if($type === 'admin') { + $sectionsTable = self::TABLE_PERSONAL_SECTIONS; + $settingsTable = self::TABLE_PERSONAL_SETTINGS; + } else { + throw new \InvalidArgumentException('"admin" or "personal" expected'); + } $query = $this->dbc->getQueryBuilder(); $query->selectDistinct('s.class') ->addSelect('s.priority') - ->from(self::TABLE_ADMIN_SECTIONS, 's') - ->from(self::TABLE_ADMIN_SETTINGS, 'f') + ->from($sectionsTable, 's') + ->from($settingsTable, 'f') ->where($query->expr()->eq('s.id', 'f.section')); $result = $query->execute(); return array_map(function ($row) { diff --git a/tests/lib/Settings/ManagerTest.php b/tests/lib/Settings/ManagerTest.php index 07f7e71fec..b9f03ea4d0 100644 --- a/tests/lib/Settings/ManagerTest.php +++ b/tests/lib/Settings/ManagerTest.php @@ -23,18 +23,22 @@ namespace Tests\Settings; +use OC\Accounts\AccountManager; use OC\Settings\Admin\Sharing; use OC\Settings\Manager; use OC\Settings\Mapper; +use OC\Settings\Personal\AppPasswords; use OC\Settings\Section; use OCP\Encryption\IManager; use OCP\IConfig; use OCP\IDBConnection; +use OCP\IGroupManager; use OCP\IL10N; use OCP\ILogger; use OCP\IRequest; use OCP\IURLGenerator; use OCP\IUserManager; +use OCP\L10N\IFactory; use OCP\Lock\ILockingProvider; use Test\TestCase; @@ -61,6 +65,14 @@ class ManagerTest extends TestCase { private $mapper; /** @var IURLGenerator|\PHPUnit_Framework_MockObject_MockObject */ private $url; + /** @var AccountManager|\PHPUnit_Framework_MockObject_MockObject */ + private $accountManager; + /** @var IGroupManager|\PHPUnit_Framework_MockObject_MockObject */ + private $groupManager; + /** @var IFactory|\PHPUnit_Framework_MockObject_MockObject */ + private $l10nFactory; + /** @var \OC_Defaults|\PHPUnit_Framework_MockObject_MockObject */ + private $defaults; public function setUp() { parent::setUp(); @@ -75,6 +87,10 @@ class ManagerTest extends TestCase { $this->request = $this->createMock(IRequest::class); $this->mapper = $this->createMock(Mapper::class); $this->url = $this->createMock(IURLGenerator::class); + $this->accountManager = $this->createMock(AccountManager::class); + $this->groupManager = $this->createMock(IGroupManager::class); + $this->l10nFactory = $this->createMock(IFactory::class); + $this->defaults = $this->createMock(\OC_Defaults::class); $this->manager = new Manager( $this->logger, @@ -86,21 +102,39 @@ class ManagerTest extends TestCase { $this->lockingProvider, $this->request, $this->mapper, - $this->url + $this->url, + $this->accountManager, + $this->groupManager, + $this->l10nFactory, + $this->defaults ); } - public function testSetupSettingsUpdate() { + public function settingsTypeProvider() { + return [ + ['admin', 'admin_settings'], + ['personal', 'personal_settings'], + ]; + } + + /** + * @dataProvider settingsTypeProvider + * @param string $type + * @param string $table + */ + public function testSetupSettingsUpdate($type, $table) { + $className = 'OCA\Files\Settings\Admin'; + $this->mapper->expects($this->any()) ->method('has') - ->with('admin_settings', 'OCA\Files\Settings\Admin') + ->with($table, $className) ->will($this->returnValue(true)); $this->mapper->expects($this->once()) ->method('update') - ->with('admin_settings', + ->with($table, 'class', - 'OCA\Files\Settings\Admin', [ + $className, [ 'section' => 'additional', 'priority' => 5 ]); @@ -108,19 +142,24 @@ class ManagerTest extends TestCase { ->method('add'); $this->manager->setupSettings([ - 'admin' => 'OCA\Files\Settings\Admin', + $type => $className, ]); } - public function testSetupSettingsAdd() { + /** + * @dataProvider settingsTypeProvider + * @param string $type + * @param string $table + */ + public function testSetupSettingsAdd($type, $table) { $this->mapper->expects($this->any()) ->method('has') - ->with('admin_settings', 'OCA\Files\Settings\Admin') + ->with($table, 'OCA\Files\Settings\Admin') ->will($this->returnValue(false)); $this->mapper->expects($this->once()) ->method('add') - ->with('admin_settings', [ + ->with($table, [ 'class' => 'OCA\Files\Settings\Admin', 'section' => 'additional', 'priority' => 5 @@ -130,7 +169,7 @@ class ManagerTest extends TestCase { ->method('update'); $this->manager->setupSettings([ - 'admin' => 'OCA\Files\Settings\Admin', + $type => 'OCA\Files\Settings\Admin', ]); } @@ -167,6 +206,38 @@ class ManagerTest extends TestCase { ], $this->manager->getAdminSections()); } + public function testGetPersonalSections() { + $this->l10n + ->expects($this->any()) + ->method('t') + ->will($this->returnArgument(0)); + + $this->mapper->expects($this->once()) + ->method('getPersonalSectionsFromDB') + ->will($this->returnValue([ + ['class' => \OCA\WorkflowEngine\Settings\Section::class, 'priority' => 90] + ])); + + $this->url->expects($this->exactly(5)) + ->method('imagePath') + ->willReturnMap([ + ['core', 'actions/info.svg', '1'], + ['settings', 'admin.svg', '2'], + ['settings', 'password.svg', '3'], + ['settings', 'change.svg', '4'], + ['core', 'actions/settings-dark.svg', '5'], + ]); + + $this->assertEquals([ + 0 => [new Section('personal-info', 'Personal info', 0, '1')], + 5 => [new Section('sessions', 'Sessions', 0, '2')], + 10 => [new Section('app-passwords', 'App passwords', 0, '3')], + 15 => [new Section('sync-clients', 'Sync clients', 0, '4')], + 90 => [\OC::$server->query(\OCA\WorkflowEngine\Settings\Section::class)], + 98 => [new Section('additional', 'Additional settings', 0, '5')], + ], $this->manager->getPersonalSections()); + } + public function testGetAdminSectionsEmptySection() { $this->l10n ->expects($this->any()) @@ -198,6 +269,35 @@ class ManagerTest extends TestCase { ], $this->manager->getAdminSections()); } + public function testGetPersonalSectionsEmptySection() { + $this->l10n + ->expects($this->any()) + ->method('t') + ->will($this->returnArgument(0)); + + $this->mapper->expects($this->once()) + ->method('getPersonalSectionsFromDB') + ->will($this->returnValue([])); + + $this->url->expects($this->exactly(5)) + ->method('imagePath') + ->willReturnMap([ + ['core', 'actions/info.svg', '1'], + ['settings', 'admin.svg', '2'], + ['settings', 'password.svg', '3'], + ['settings', 'change.svg', '4'], + ['core', 'actions/settings-dark.svg', '5'], + ]); + + $this->assertEquals([ + 0 => [new Section('personal-info', 'Personal info', 0, '1')], + 5 => [new Section('sessions', 'Sessions', 0, '2')], + 10 => [new Section('app-passwords', 'App passwords', 0, '3')], + 15 => [new Section('sync-clients', 'Sync clients', 0, '4')], + 98 => [new Section('additional', 'Additional settings', 0, '5')], + ], $this->manager->getPersonalSections()); + } + public function testGetAdminSettings() { $this->mapper->expects($this->any()) ->method('getAdminSettingsFromDB') @@ -207,4 +307,14 @@ class ManagerTest extends TestCase { 0 => [new Sharing($this->config)], ], $this->manager->getAdminSettings('sharing')); } + + public function testGetPersonalSettings() { + $this->mapper->expects($this->any()) + ->method('getPersonalSettingsFromDB') + ->will($this->returnValue([])); + + $this->assertEquals([ + 5 => [new AppPasswords()], + ], $this->manager->getPersonalSettings('app-passwords')); + } } From e8f5c21db9bc16d7263cbfec74480d5835278b85 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 31 May 2017 12:44:52 +0200 Subject: [PATCH 15/42] Fix trait usage Signed-off-by: Robin Appelman --- settings/Controller/AdminSettingsController.php | 3 +-- settings/Controller/CommonSettingsTrait.php | 2 +- settings/Controller/PersonalSettingsController.php | 7 ++----- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/settings/Controller/AdminSettingsController.php b/settings/Controller/AdminSettingsController.php index 087700ee55..804b7c217c 100644 --- a/settings/Controller/AdminSettingsController.php +++ b/settings/Controller/AdminSettingsController.php @@ -74,8 +74,7 @@ class AdminSettingsController extends Controller { * @param string $section * @return array */ - private function getSettings($section) { - // PhpStorm shows this as unused, but is required by CommonSettingsTrait + protected function getSettings($section) { $settings = $this->settingsManager->getAdminSettings($section); $formatted = $this->formatSettings($settings); if($section === 'additional') { diff --git a/settings/Controller/CommonSettingsTrait.php b/settings/Controller/CommonSettingsTrait.php index 66ffabd84d..4854f40586 100644 --- a/settings/Controller/CommonSettingsTrait.php +++ b/settings/Controller/CommonSettingsTrait.php @@ -119,5 +119,5 @@ trait CommonSettingsTrait { return new TemplateResponse('settings', 'settings/frame', $templateParams); } - abstract public function getSettings($section); + abstract protected function getSettings($section); } diff --git a/settings/Controller/PersonalSettingsController.php b/settings/Controller/PersonalSettingsController.php index 11bd9a9d94..3ccef025a7 100644 --- a/settings/Controller/PersonalSettingsController.php +++ b/settings/Controller/PersonalSettingsController.php @@ -31,9 +31,7 @@ use OCP\Settings\IManager as ISettingsManager; use OCP\Template; class PersonalSettingsController extends Controller { - use CommonSettingsTrait { - getSettings as private; - } + use CommonSettingsTrait; /** @var INavigationManager */ private $navigationManager; @@ -66,8 +64,7 @@ class PersonalSettingsController extends Controller { * @param string $section * @return array */ - private function getSettings($section) { - // PhpStorm shows this as unused, but is required by CommonSettingsTrait + protected function getSettings($section) { $settings = $this->settingsManager->getPersonalSettings($section); $formatted = $this->formatSettings($settings); if($section === 'additional') { From 6e314ddabe0bd9f1d9bcfecf451c6a82f2de648b Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 31 May 2017 12:55:49 +0200 Subject: [PATCH 16/42] fix getting sections Signed-off-by: Robin Appelman --- lib/private/Settings/Mapper.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/private/Settings/Mapper.php b/lib/private/Settings/Mapper.php index 999efb0d87..3219a812cd 100644 --- a/lib/private/Settings/Mapper.php +++ b/lib/private/Settings/Mapper.php @@ -104,10 +104,10 @@ class Mapper { * @return array[] [['class' => string, 'priority' => int], ...] */ public function getSectionsFromDB($type) { - if($type === 'personal') { + if($type === 'admin') { $sectionsTable = self::TABLE_ADMIN_SECTIONS; $settingsTable = self::TABLE_ADMIN_SETTINGS; - } else if($type === 'admin') { + } else if($type === 'personal') { $sectionsTable = self::TABLE_PERSONAL_SECTIONS; $settingsTable = self::TABLE_PERSONAL_SETTINGS; } else { From 0dcce5a83568ecf40f59e7efcc1308ace89d15d5 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Thu, 1 Jun 2017 15:37:23 +0200 Subject: [PATCH 17/42] move personal external storage settings to it's own section Signed-off-by: Robin Appelman --- apps/files_external/appinfo/app.php | 2 - apps/files_external/appinfo/info.xml | 4 +- .../lib/AppInfo/Application.php | 18 --- apps/files_external/lib/Settings/Personal.php | 103 ++++++++++++++++++ .../lib/Settings/PersonalSection.php | 67 ++++++++++++ 5 files changed, 173 insertions(+), 21 deletions(-) create mode 100644 apps/files_external/lib/Settings/Personal.php create mode 100644 apps/files_external/lib/Settings/PersonalSection.php diff --git a/apps/files_external/appinfo/app.php b/apps/files_external/appinfo/app.php index ddf609129f..250cbbd00d 100644 --- a/apps/files_external/appinfo/app.php +++ b/apps/files_external/appinfo/app.php @@ -35,8 +35,6 @@ require_once __DIR__ . '/../3rdparty/autoload.php'; \OC_Mount_Config::$app = new \OCA\Files_External\AppInfo\Application(); $appContainer = \OC_Mount_Config::$app->getContainer(); -\OC_Mount_Config::$app->registerSettings(); - \OCA\Files\App::getNavigationManager()->add(function () { $l = \OC::$server->getL10N('files_external'); return [ diff --git a/apps/files_external/appinfo/info.xml b/apps/files_external/appinfo/info.xml index 5772b89ba9..74cb3e64e4 100644 --- a/apps/files_external/appinfo/info.xml +++ b/apps/files_external/appinfo/info.xml @@ -14,7 +14,7 @@ External storage can be configured using the GUI or at the command line. This se admin-external-storage - 1.4.0 + 1.4.1 @@ -29,6 +29,8 @@ External storage can be configured using the GUI or at the command line. This se OCA\Files_External\Settings\Admin OCA\Files_External\Settings\Section + OCA\Files_External\Settings\Personal + OCA\Files_External\Settings\PersonalSection diff --git a/apps/files_external/lib/AppInfo/Application.php b/apps/files_external/lib/AppInfo/Application.php index fcf10adb37..0bbb81dfea 100644 --- a/apps/files_external/lib/AppInfo/Application.php +++ b/apps/files_external/lib/AppInfo/Application.php @@ -64,24 +64,6 @@ class Application extends App implements IBackendProvider, IAuthMechanismProvide ); } - /** - * Register settings templates - */ - public function registerSettings() { - $container = $this->getContainer(); - $userSession = $container->getServer()->getUserSession(); - if (!$userSession->isLoggedIn()) { - return; - } - $backendService = $container->query('OCA\\Files_External\\Service\\BackendService'); - - /** @var \OCA\Files_External\Service\UserGlobalStoragesService $userGlobalStoragesService */ - $userGlobalStoragesService = $container->query('OCA\Files_External\Service\UserGlobalStoragesService'); - if (count($userGlobalStoragesService->getStorages()) > 0 || $backendService->isUserMountingAllowed()) { - \OCP\App::registerPersonal('files_external', 'personal'); - } - } - /** * @{inheritdoc} */ diff --git a/apps/files_external/lib/Settings/Personal.php b/apps/files_external/lib/Settings/Personal.php new file mode 100644 index 0000000000..946ba9f694 --- /dev/null +++ b/apps/files_external/lib/Settings/Personal.php @@ -0,0 +1,103 @@ + + * + * @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\Files_External\Settings; + +use OCA\Files_External\Lib\Auth\Password\GlobalAuth; +use OCA\Files_External\Service\BackendService; +use OCA\Files_External\Service\GlobalStoragesService; +use OCA\Files_External\Service\UserGlobalStoragesService; +use OCP\AppFramework\Http\TemplateResponse; +use OCP\Encryption\IManager; +use OCP\IUserSession; +use OCP\Settings\ISettings; + +class Personal implements ISettings { + + /** @var IManager */ + private $encryptionManager; + + /** @var UserGlobalStoragesService */ + private $userGlobalStoragesService; + + /** @var BackendService */ + private $backendService; + + /** @var GlobalAuth */ + private $globalAuth; + + /** @var IUserSession */ + private $userSession; + + public function __construct( + IManager $encryptionManager, + UserGlobalStoragesService $userGlobalStoragesService, + BackendService $backendService, + GlobalAuth $globalAuth, + IUserSession $userSession + ) { + $this->encryptionManager = $encryptionManager; + $this->userGlobalStoragesService = $userGlobalStoragesService; + $this->backendService = $backendService; + $this->globalAuth = $globalAuth; + $this->userSession = $userSession; + } + + /** + * @return TemplateResponse + */ + public function getForm() { + $uid = $this->userSession->getUser()->getUID(); + + $parameters = [ + 'encryptionEnabled' => $this->encryptionManager->isEnabled(), + 'visibilityType' => BackendService::VISIBILITY_PERSONAL, + 'storages' => $this->userGlobalStoragesService->getStorages(), + 'backends' => $this->backendService->getAvailableBackends(), + 'authMechanisms' => $this->backendService->getAuthMechanisms(), + 'dependencies' => \OC_Mount_Config::dependencyMessage($this->backendService->getBackends()), + 'allowUserMounting' => $this->backendService->isUserMountingAllowed(), + 'globalCredentials' => $this->globalAuth->getAuth($uid), + 'globalCredentialsUid' => $uid, + ]; + + return new TemplateResponse('files_external', 'settings', $parameters, ''); + } + + /** + * @return string the section ID, e.g. 'sharing' + */ + public function getSection() { + return 'externalstorages'; + } + + /** + * @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. + * + * E.g.: 70 + */ + public function getPriority() { + return 40; + } + +} diff --git a/apps/files_external/lib/Settings/PersonalSection.php b/apps/files_external/lib/Settings/PersonalSection.php new file mode 100644 index 0000000000..32a841c420 --- /dev/null +++ b/apps/files_external/lib/Settings/PersonalSection.php @@ -0,0 +1,67 @@ + + * + * @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\Files_External\Settings; + + +use OCA\Files_External\Service\BackendService; +use OCA\Files_External\Service\UserGlobalStoragesService; +use OCP\IL10N; +use OCP\IURLGenerator; +use OCP\IUserSession; + +class PersonalSection extends Section { + /** @var IUserSession */ + private $userSession; + + /** @var UserGlobalStoragesService */ + private $userGlobalStoragesService; + + /** @var BackendService */ + private $backendService; + + public function __construct( + IURLGenerator $url, + IL10N $l, + IUserSession $userSession, + UserGlobalStoragesService $userGlobalStoragesService, + BackendService $backendService + ) { + parent::__construct($url, $l); + $this->userSession = $userSession; + $this->userGlobalStoragesService = $userGlobalStoragesService; + $this->backendService = $backendService; + } + + public function getID() { + if (!$this->userSession->isLoggedIn()) { + // we need to return the proper id while installing/upgrading the app + return parent::getID(); + } + + if (count($this->userGlobalStoragesService->getStorages()) > 0 || $this->backendService->isUserMountingAllowed()) { + return parent::getID(); + } else { + // by returning a different id, no matching settings will be found and the item will be hidden + return null; + } + } +} \ No newline at end of file From d7a2290ce15c70b219ecae8f0076e38a2471070d Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Fri, 16 Jun 2017 15:00:15 +0200 Subject: [PATCH 18/42] take over changes from #5084 Signed-off-by: Arthur Schiwon --- lib/private/Server.php | 3 +- lib/private/Settings/Manager.php | 17 ++++++- .../Settings/Personal/PersonalInfo.php | 49 ++++++++++++++++--- 3 files changed, 59 insertions(+), 10 deletions(-) diff --git a/lib/private/Server.php b/lib/private/Server.php index 262f9f00a7..d10da38d29 100644 --- a/lib/private/Server.php +++ b/lib/private/Server.php @@ -975,7 +975,8 @@ class Server extends ServerContainer implements IServerContainer { $c->query(AccountManager::class), $c->getGroupManager(), $c->getL10NFactory(), - $c->getThemingDefaults() + $c->getThemingDefaults(), + $c->getAppManager() ); return $manager; }); diff --git a/lib/private/Settings/Manager.php b/lib/private/Settings/Manager.php index 7da8bfe65d..d04f4abdcd 100644 --- a/lib/private/Settings/Manager.php +++ b/lib/private/Settings/Manager.php @@ -24,6 +24,7 @@ namespace OC\Settings; use OC\Accounts\AccountManager; +use OCP\App\IAppManager; use OCP\AppFramework\QueryException; use OCP\Encryption\IManager as EncryptionManager; use OCP\IConfig; @@ -69,6 +70,8 @@ class Manager implements IManager { private $l10nFactory; /** @var \OC_Defaults */ private $defaults; + /** @var IAppManager */ + private $appManager; /** * @param ILogger $log @@ -100,7 +103,8 @@ class Manager implements IManager { AccountManager $accountManager, IGroupManager $groupManager, IFactory $l10nFactory, - \OC_Defaults $defaults + \OC_Defaults $defaults, + IAppManager $appManager ) { $this->log = $log; $this->dbc = $dbc; @@ -116,6 +120,7 @@ class Manager implements IManager { $this->groupManager = $groupManager; $this->l10nFactory = $l10nFactory; $this->defaults = $defaults; + $this->appManager = $appManager; } /** @@ -402,7 +407,15 @@ class Manager implements IManager { try { if ($section === 'personal-info') { /** @var ISettings $form */ - $form = new Personal\PersonalInfo($this->config, $this->userManager, $this->groupManager, $this->accountManager, $this->l10nFactory, $this->l); + $form = new Personal\PersonalInfo( + $this->config, + $this->userManager, + $this->groupManager, + $this->accountManager, + $this->appManager, + $this->l10nFactory, + $this->l + ); $forms[$form->getPriority()] = [$form]; } if($section === 'sessions') { diff --git a/lib/private/Settings/Personal/PersonalInfo.php b/lib/private/Settings/Personal/PersonalInfo.php index ea7cecaa79..eb0ff253db 100644 --- a/lib/private/Settings/Personal/PersonalInfo.php +++ b/lib/private/Settings/Personal/PersonalInfo.php @@ -25,6 +25,8 @@ namespace OC\Settings\Personal; use OC\Accounts\AccountManager; +use OCA\FederatedFileSharing\AppInfo\Application; +use OCP\App\IAppManager; use OCP\AppFramework\Http\TemplateResponse; use OCP\Files\FileInfo; use OCP\IConfig; @@ -45,6 +47,8 @@ class PersonalInfo implements ISettings { private $accountManager; /** @var IGroupManager */ private $groupManager; + /** @var IAppManager */ + private $appManager; /** @var IFactory */ private $l10nFactory; @@ -69,6 +73,7 @@ class PersonalInfo implements ISettings { IUserManager $userManager, IGroupManager $groupManager, AccountManager $accountManager, + IAppManager $appManager, IFactory $l10nFactory, IL10N $l ) { @@ -76,6 +81,7 @@ class PersonalInfo implements ISettings { $this->userManager = $userManager; $this->accountManager = $accountManager; $this->groupManager = $groupManager; + $this->appManager = $appManager; $this->l10nFactory = $l10nFactory; $this->l = $l; } @@ -85,8 +91,13 @@ class PersonalInfo implements ISettings { * @since 9.1 */ public function getForm() { - $lookupServerUploadEnabled = $this->config->getAppValue('files_sharing', 'lookupServerUploadEnabled', 'yes'); - $lookupServerUploadEnabled = $lookupServerUploadEnabled === 'yes'; + $federatedFileSharingEnabled = $this->appManager->isEnabledForUser('federatedfilesharing'); + $lookupServerUploadEnabled = false; + if($federatedFileSharingEnabled) { + $federatedFileSharing = new Application(); + $shareProvider = $federatedFileSharing->getFederatedShareProvider(); + $lookupServerUploadEnabled = $shareProvider->isLookupServerUploadEnabled(); + } $uid = \OC_User::getUser(); $user = $this->userManager->get($uid); @@ -100,6 +111,7 @@ class PersonalInfo implements ISettings { } list($activeLanguage, $commonLanguages, $languages) = $this->getLanguages($user); + $messageParameters = $this->getMessageParameters($userData); $parameters = [ 'total_space' => $totalSpace, @@ -108,17 +120,17 @@ class PersonalInfo implements ISettings { 'quota' => $storageInfo['quota'], 'avatarChangeSupported' => \OC_User::canUserChangeAvatar($uid), 'lookupServerUploadEnabled' => $lookupServerUploadEnabled, - 'avatar_scope' => $userData[AccountManager::PROPERTY_AVATAR]['scope'], + 'avatarScope' => $userData[AccountManager::PROPERTY_AVATAR]['scope'], 'displayNameChangeSupported' => \OC_User::canUserChangeDisplayName($uid), 'displayName' => $userData[AccountManager::PROPERTY_DISPLAYNAME]['value'], + 'displayNameScope' => $userData[AccountManager::PROPERTY_DISPLAYNAME]['scope'], 'email' => $userData[AccountManager::PROPERTY_EMAIL]['value'], 'emailScope' => $userData[AccountManager::PROPERTY_EMAIL]['scope'], - 'emailMesage' => '', 'emailVerification' => $userData[AccountManager::PROPERTY_EMAIL]['verified'], 'phone' => $userData[AccountManager::PROPERTY_PHONE]['value'], 'phoneScope' => $userData[AccountManager::PROPERTY_PHONE]['scope'], - 'address', $userData[AccountManager::PROPERTY_ADDRESS]['value'], - 'addressScope', $userData[AccountManager::PROPERTY_ADDRESS]['scope'], + 'address' => $userData[AccountManager::PROPERTY_ADDRESS]['value'], + 'addressScope' => $userData[AccountManager::PROPERTY_ADDRESS]['scope'], 'website' => $userData[AccountManager::PROPERTY_WEBSITE]['value'], 'websiteScope' => $userData[AccountManager::PROPERTY_WEBSITE]['scope'], 'websiteVerification' => $userData[AccountManager::PROPERTY_WEBSITE]['verified'], @@ -130,7 +142,7 @@ class PersonalInfo implements ISettings { 'activelanguage' => $activeLanguage, 'commonlanguages' => $commonLanguages, 'languages' => $languages, - ]; + ] + $messageParameters; return new TemplateResponse('settings', 'settings/personal/personal.info', $parameters, ''); @@ -237,4 +249,27 @@ class PersonalInfo implements ISettings { return [$userLang, $commonLanguages, $languages]; } + /** + * @param array $userData + * @return array + */ + private function getMessageParameters(array $userData) { + $needVerifyMessage = [AccountManager::PROPERTY_EMAIL, AccountManager::PROPERTY_WEBSITE, AccountManager::PROPERTY_TWITTER]; + $messageParameters = []; + foreach ($needVerifyMessage as $property) { + switch ($userData[$property]['verified']) { + case AccountManager::VERIFIED: + $message = $this->l->t('Verifying'); + break; + case AccountManager::VERIFICATION_IN_PROGRESS: + $message = $this->l->t('Verifying …'); + break; + default: + $message = $this->l->t('Verify'); + } + $messageParameters[$property . 'Message'] = $message; + } + return $messageParameters; + } + } From 07cf046216fc420965191fdd3003cdf6029dbbac Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Fri, 16 Jun 2017 15:34:16 +0200 Subject: [PATCH 19/42] take over changes from #5166 and follow #5267 Signed-off-by: Arthur Schiwon --- lib/private/Settings/Manager.php | 12 +--- .../Settings/Personal/AppPasswords.php | 59 ------------------- .../Personal/{Sessions.php => Security.php} | 6 +- .../{app-passwords.php => security.php} | 20 ++++--- .../templates/settings/personal/sessions.php | 48 --------------- 5 files changed, 17 insertions(+), 128 deletions(-) delete mode 100644 lib/private/Settings/Personal/AppPasswords.php rename lib/private/Settings/Personal/{Sessions.php => Security.php} (92%) rename settings/templates/settings/personal/{app-passwords.php => security.php} (83%) delete mode 100644 settings/templates/settings/personal/sessions.php diff --git a/lib/private/Settings/Manager.php b/lib/private/Settings/Manager.php index d04f4abdcd..fe2932d976 100644 --- a/lib/private/Settings/Manager.php +++ b/lib/private/Settings/Manager.php @@ -418,14 +418,9 @@ class Manager implements IManager { ); $forms[$form->getPriority()] = [$form]; } - if($section === 'sessions') { + if($section === 'security') { /** @var ISettings $form */ - $form = new Personal\Sessions(); - $forms[$form->getPriority()] = [$form]; - } - if($section === 'app-passwords') { - /** @var ISettings $form */ - $form = new Personal\AppPasswords(); + $form = new Personal\Security(); $forms[$form->getPriority()] = [$form]; } if($section === 'sync-clients') { @@ -472,8 +467,7 @@ class Manager implements IManager { public function getPersonalSections() { $sections = [ 0 => [new Section('personal-info', $this->l->t('Personal info'), 0, $this->url->imagePath('core', 'actions/info.svg'))], - 5 => [new Section('sessions', $this->l->t('Sessions'), 0, $this->url->imagePath('settings', 'admin.svg'))], - 10 => [new Section('app-passwords', $this->l->t('App passwords'), 0, $this->url->imagePath('settings', 'password.svg'))], + 5 => [new Section('security', $this->l->t('Security'), 0, $this->url->imagePath('settings', 'password.svg'))], 15 => [new Section('sync-clients', $this->l->t('Sync clients'), 0, $this->url->imagePath('settings', 'change.svg'))], 98 => [new Section('additional', $this->l->t('Additional settings'), 0, $this->url->imagePath('core', 'actions/settings-dark.svg'))], ]; diff --git a/lib/private/Settings/Personal/AppPasswords.php b/lib/private/Settings/Personal/AppPasswords.php deleted file mode 100644 index 3f2886326d..0000000000 --- a/lib/private/Settings/Personal/AppPasswords.php +++ /dev/null @@ -1,59 +0,0 @@ - - * - * @author Arthur Schiwon - * - * @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 OC\Settings\Personal; - - -use OCP\AppFramework\Http\TemplateResponse; -use OCP\Settings\ISettings; - -class AppPasswords implements ISettings { - - /** - * @return TemplateResponse returns the instance with all parameters set, ready to be rendered - * @since 9.1 - */ - public function getForm() { - return new TemplateResponse('settings', 'settings/personal/app-passwords'); - } - - /** - * @return string the section ID, e.g. 'sharing' - * @since 9.1 - */ - public function getSection() { - return 'app-passwords'; - } - - /** - * @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. - * - * E.g.: 70 - * @since 9.1 - */ - public function getPriority() { - return 5; - } -} diff --git a/lib/private/Settings/Personal/Sessions.php b/lib/private/Settings/Personal/Security.php similarity index 92% rename from lib/private/Settings/Personal/Sessions.php rename to lib/private/Settings/Personal/Security.php index 22f8a44b17..ecbd1199d1 100644 --- a/lib/private/Settings/Personal/Sessions.php +++ b/lib/private/Settings/Personal/Security.php @@ -27,14 +27,14 @@ namespace OC\Settings\Personal; use OCP\AppFramework\Http\TemplateResponse; use OCP\Settings\ISettings; -class Sessions implements ISettings { +class Security implements ISettings { /** * @return TemplateResponse returns the instance with all parameters set, ready to be rendered * @since 9.1 */ public function getForm() { - return new TemplateResponse('settings', 'settings/personal/sessions'); + return new TemplateResponse('settings', 'settings/personal/security'); } /** @@ -42,7 +42,7 @@ class Sessions implements ISettings { * @since 9.1 */ public function getSection() { - return 'sessions'; + return 'security'; } /** diff --git a/settings/templates/settings/personal/app-passwords.php b/settings/templates/settings/personal/security.php similarity index 83% rename from settings/templates/settings/personal/app-passwords.php rename to settings/templates/settings/personal/security.php index b9f8c4867e..3a324bf8d2 100644 --- a/settings/templates/settings/personal/app-passwords.php +++ b/settings/templates/settings/personal/security.php @@ -20,6 +20,7 @@ * along with this program. If not, see . * */ + script('settings', [ 'authtoken', 'authtoken_collection', @@ -29,16 +30,17 @@ script('settings', [ ?> -
    -

    t('App passwords'));?>

    -

    t('Here you can generate individual passwords for apps so you don’t have to give out your password. You can revoke them individually too.'));?>

    + +
    +

    t('Security'));?>

    +

    t('Web, desktop and mobile clients currently logged in to your account.'));?>

    - - - - - - + + + + + + diff --git a/settings/templates/settings/personal/sessions.php b/settings/templates/settings/personal/sessions.php deleted file mode 100644 index 60b38d6648..0000000000 --- a/settings/templates/settings/personal/sessions.php +++ /dev/null @@ -1,48 +0,0 @@ - - * - * @author Arthur Schiwon - * - * @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 . - * - */ - -script('settings', [ - 'authtoken', - 'authtoken_collection', - 'authtoken_view', - 'settings/authtoken-init' -]); - -?> - - -
    -

    t('Sessions'));?>

    -

    t('Web, desktop and mobile clients currently logged in to your account.'));?>

    -
    t('Name'));?>t('Last activity'));?>
    t('Device'));?>t('Last activity'));?>
    - - - - - - - - - -
    t('Device'));?>t('Last activity'));?>
    -
    From 0762d3dd3e4153455c70e175ae67690d57b9a5d1 Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Fri, 16 Jun 2017 15:40:05 +0200 Subject: [PATCH 20/42] =?UTF-8?q?=E2=80=A6and=20adjust=20tests?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Arthur Schiwon --- tests/lib/Settings/ManagerTest.php | 45 +++++++++++++++--------------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/tests/lib/Settings/ManagerTest.php b/tests/lib/Settings/ManagerTest.php index b9f03ea4d0..83dbbe5c2a 100644 --- a/tests/lib/Settings/ManagerTest.php +++ b/tests/lib/Settings/ManagerTest.php @@ -27,8 +27,9 @@ use OC\Accounts\AccountManager; use OC\Settings\Admin\Sharing; use OC\Settings\Manager; use OC\Settings\Mapper; -use OC\Settings\Personal\AppPasswords; +use OC\Settings\Personal\Security; use OC\Settings\Section; +use OCP\App\IAppManager; use OCP\Encryption\IManager; use OCP\IConfig; use OCP\IDBConnection; @@ -73,6 +74,8 @@ class ManagerTest extends TestCase { private $l10nFactory; /** @var \OC_Defaults|\PHPUnit_Framework_MockObject_MockObject */ private $defaults; + /** @var IAppManager */ + private $appManager; public function setUp() { parent::setUp(); @@ -91,6 +94,7 @@ class ManagerTest extends TestCase { $this->groupManager = $this->createMock(IGroupManager::class); $this->l10nFactory = $this->createMock(IFactory::class); $this->defaults = $this->createMock(\OC_Defaults::class); + $this->appManager = $this->createMock(IAppManager::class); $this->manager = new Manager( $this->logger, @@ -106,7 +110,8 @@ class ManagerTest extends TestCase { $this->accountManager, $this->groupManager, $this->l10nFactory, - $this->defaults + $this->defaults, + $this->appManager ); } @@ -218,23 +223,21 @@ class ManagerTest extends TestCase { ['class' => \OCA\WorkflowEngine\Settings\Section::class, 'priority' => 90] ])); - $this->url->expects($this->exactly(5)) + $this->url->expects($this->exactly(4)) ->method('imagePath') ->willReturnMap([ ['core', 'actions/info.svg', '1'], - ['settings', 'admin.svg', '2'], - ['settings', 'password.svg', '3'], - ['settings', 'change.svg', '4'], - ['core', 'actions/settings-dark.svg', '5'], + ['settings', 'password.svg', '2'], + ['settings', 'change.svg', '3'], + ['core', 'actions/settings-dark.svg', '4'], ]); $this->assertEquals([ 0 => [new Section('personal-info', 'Personal info', 0, '1')], - 5 => [new Section('sessions', 'Sessions', 0, '2')], - 10 => [new Section('app-passwords', 'App passwords', 0, '3')], - 15 => [new Section('sync-clients', 'Sync clients', 0, '4')], + 5 => [new Section('security', 'Security', 0, '2')], + 15 => [new Section('sync-clients', 'Sync clients', 0, '3')], 90 => [\OC::$server->query(\OCA\WorkflowEngine\Settings\Section::class)], - 98 => [new Section('additional', 'Additional settings', 0, '5')], + 98 => [new Section('additional', 'Additional settings', 0, '4')], ], $this->manager->getPersonalSections()); } @@ -279,22 +282,20 @@ class ManagerTest extends TestCase { ->method('getPersonalSectionsFromDB') ->will($this->returnValue([])); - $this->url->expects($this->exactly(5)) + $this->url->expects($this->exactly(4)) ->method('imagePath') ->willReturnMap([ ['core', 'actions/info.svg', '1'], - ['settings', 'admin.svg', '2'], - ['settings', 'password.svg', '3'], - ['settings', 'change.svg', '4'], - ['core', 'actions/settings-dark.svg', '5'], + ['settings', 'password.svg', '2'], + ['settings', 'change.svg', '3'], + ['core', 'actions/settings-dark.svg', '4'], ]); $this->assertEquals([ 0 => [new Section('personal-info', 'Personal info', 0, '1')], - 5 => [new Section('sessions', 'Sessions', 0, '2')], - 10 => [new Section('app-passwords', 'App passwords', 0, '3')], - 15 => [new Section('sync-clients', 'Sync clients', 0, '4')], - 98 => [new Section('additional', 'Additional settings', 0, '5')], + 5 => [new Section('security', 'Security', 0, '2')], + 15 => [new Section('sync-clients', 'Sync clients', 0, '3')], + 98 => [new Section('additional', 'Additional settings', 0, '4')], ], $this->manager->getPersonalSections()); } @@ -314,7 +315,7 @@ class ManagerTest extends TestCase { ->will($this->returnValue([])); $this->assertEquals([ - 5 => [new AppPasswords()], - ], $this->manager->getPersonalSettings('app-passwords')); + 10 => [new Security()], + ], $this->manager->getPersonalSettings('security')); } } From 1cdb49d6dbfe071f7d612dd4364cbc0c71abacde Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Fri, 16 Jun 2017 16:50:13 +0200 Subject: [PATCH 21/42] adjust another test Signed-off-by: Arthur Schiwon --- .../AdminSettingsControllerTest.php | 22 ++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/tests/Settings/Controller/AdminSettingsControllerTest.php b/tests/Settings/Controller/AdminSettingsControllerTest.php index 6c93bca0d6..1d4d6eb9db 100644 --- a/tests/Settings/Controller/AdminSettingsControllerTest.php +++ b/tests/Settings/Controller/AdminSettingsControllerTest.php @@ -22,7 +22,6 @@ */ namespace Tests\Settings\Controller; - use OC\Settings\Admin\TipsTricks; use OC\Settings\Controller\AdminSettingsController; use OCP\AppFramework\Http\TemplateResponse; @@ -31,6 +30,13 @@ use OCP\IRequest; use OCP\Settings\IManager; use Test\TestCase; +/** + * Class AdminSettingsControllerTest + * + * @group DB + * + * @package Tests\Settings\Controller + */ class AdminSettingsControllerTest extends TestCase { /** @var AdminSettingsController */ private $adminSettingsController; @@ -38,7 +44,7 @@ class AdminSettingsControllerTest extends TestCase { private $request; /** @var INavigationManager */ private $navigationManager; - /** @var IManager */ + /** @var IManager|\PHPUnit_Framework_MockObject_MockObject */ private $settingsManager; public function setUp() { @@ -61,12 +67,22 @@ class AdminSettingsControllerTest extends TestCase { ->expects($this->once()) ->method('getAdminSections') ->willReturn([]); + $this->settingsManager + ->expects($this->once()) + ->method('getPersonalSections') + ->willReturn([]); $this->settingsManager ->expects($this->once()) ->method('getAdminSettings') ->with('test') ->willReturn([5 => new TipsTricks($this->getMockBuilder('\OCP\IConfig')->getMock())]); - $expected = new TemplateResponse('settings', 'admin/frame', ['forms' => [], 'content' => '']); + + // so unity… + $user = \OC::$server->getUserManager()->createUser('lolo', 'olo'); + \OC_User::setUserId($user->getUID()); + \OC::$server->getGroupManager()->get('admin')->addUser($user); + + $expected = new TemplateResponse('settings', 'settings/frame', ['forms' => ['personal' => [], 'admin' => []], 'content' => '']); $this->assertEquals($expected, $this->adminSettingsController->index('test')); } } From ab814e77861d3cba7089e073483ae4e11c67096c Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Fri, 16 Jun 2017 17:18:06 +0200 Subject: [PATCH 22/42] drone wasn't satisfied yet Signed-off-by: Arthur Schiwon --- .../Controller/AdminSettingsControllerTest.php | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/tests/Settings/Controller/AdminSettingsControllerTest.php b/tests/Settings/Controller/AdminSettingsControllerTest.php index 1d4d6eb9db..51357f67a2 100644 --- a/tests/Settings/Controller/AdminSettingsControllerTest.php +++ b/tests/Settings/Controller/AdminSettingsControllerTest.php @@ -46,6 +46,8 @@ class AdminSettingsControllerTest extends TestCase { private $navigationManager; /** @var IManager|\PHPUnit_Framework_MockObject_MockObject */ private $settingsManager; + /** @var string */ + private $adminUid = 'lololo'; public function setUp() { parent::setUp(); @@ -60,6 +62,16 @@ class AdminSettingsControllerTest extends TestCase { $this->navigationManager, $this->settingsManager ); + + $user = \OC::$server->getUserManager()->createUser($this->adminUid, 'olo'); + \OC_User::setUserId($user->getUID()); + \OC::$server->getGroupManager()->createGroup('admin')->addUser($user); + } + + public function tearDown() { + \OC::$server->getUserManager()->get($this->adminUid)->delete(); + + parent::tearDown(); } public function testIndex() { @@ -77,11 +89,6 @@ class AdminSettingsControllerTest extends TestCase { ->with('test') ->willReturn([5 => new TipsTricks($this->getMockBuilder('\OCP\IConfig')->getMock())]); - // so unity… - $user = \OC::$server->getUserManager()->createUser('lolo', 'olo'); - \OC_User::setUserId($user->getUID()); - \OC::$server->getGroupManager()->get('admin')->addUser($user); - $expected = new TemplateResponse('settings', 'settings/frame', ['forms' => ['personal' => [], 'admin' => []], 'content' => '']); $this->assertEquals($expected, $this->adminSettingsController->index('test')); } From 2b128ca576b88a43ab71196613c74edaeaae5af4 Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Tue, 20 Jun 2017 00:23:34 +0200 Subject: [PATCH 23/42] update autoloader Signed-off-by: Arthur Schiwon --- lib/composer/composer/autoload_classmap.php | 6 ++++++ lib/composer/composer/autoload_static.php | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/lib/composer/composer/autoload_classmap.php b/lib/composer/composer/autoload_classmap.php index 33b96d29ac..db03e49009 100644 --- a/lib/composer/composer/autoload_classmap.php +++ b/lib/composer/composer/autoload_classmap.php @@ -806,10 +806,12 @@ return array( 'OC\\Settings\\Controller\\CertificateController' => $baseDir . '/settings/Controller/CertificateController.php', 'OC\\Settings\\Controller\\ChangePasswordController' => $baseDir . '/settings/Controller/ChangePasswordController.php', 'OC\\Settings\\Controller\\CheckSetupController' => $baseDir . '/settings/Controller/CheckSetupController.php', + 'OC\\Settings\\Controller\\CommonSettingsTrait' => $baseDir . '/settings/Controller/CommonSettingsTrait.php', 'OC\\Settings\\Controller\\EncryptionController' => $baseDir . '/settings/Controller/EncryptionController.php', 'OC\\Settings\\Controller\\GroupsController' => $baseDir . '/settings/Controller/GroupsController.php', '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\\SecuritySettingsController' => $baseDir . '/settings/Controller/SecuritySettingsController.php', 'OC\\Settings\\Controller\\UsersController' => $baseDir . '/settings/Controller/UsersController.php', 'OC\\Settings\\Hooks' => $baseDir . '/settings/Hooks.php', @@ -817,6 +819,10 @@ return array( 'OC\\Settings\\Manager' => $baseDir . '/lib/private/Settings/Manager.php', 'OC\\Settings\\Mapper' => $baseDir . '/lib/private/Settings/Mapper.php', 'OC\\Settings\\Middleware\\SubadminMiddleware' => $baseDir . '/settings/Middleware/SubadminMiddleware.php', + 'OC\\Settings\\Personal\\Additional' => $baseDir . '/lib/private/Settings/Personal/Additional.php', + 'OC\\Settings\\Personal\\PersonalInfo' => $baseDir . '/lib/private/Settings/Personal/PersonalInfo.php', + 'OC\\Settings\\Personal\\Security' => $baseDir . '/lib/private/Settings/Personal/Security.php', + 'OC\\Settings\\Personal\\SyncClients' => $baseDir . '/lib/private/Settings/Personal/SyncClients.php', 'OC\\Settings\\RemoveOrphaned' => $baseDir . '/lib/private/Settings/RemoveOrphaned.php', 'OC\\Settings\\Section' => $baseDir . '/lib/private/Settings/Section.php', 'OC\\Setup' => $baseDir . '/lib/private/Setup.php', diff --git a/lib/composer/composer/autoload_static.php b/lib/composer/composer/autoload_static.php index 6f93d83c31..65b3b9a3cf 100644 --- a/lib/composer/composer/autoload_static.php +++ b/lib/composer/composer/autoload_static.php @@ -836,10 +836,12 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c 'OC\\Settings\\Controller\\CertificateController' => __DIR__ . '/../../..' . '/settings/Controller/CertificateController.php', 'OC\\Settings\\Controller\\ChangePasswordController' => __DIR__ . '/../../..' . '/settings/Controller/ChangePasswordController.php', 'OC\\Settings\\Controller\\CheckSetupController' => __DIR__ . '/../../..' . '/settings/Controller/CheckSetupController.php', + 'OC\\Settings\\Controller\\CommonSettingsTrait' => __DIR__ . '/../../..' . '/settings/Controller/CommonSettingsTrait.php', 'OC\\Settings\\Controller\\EncryptionController' => __DIR__ . '/../../..' . '/settings/Controller/EncryptionController.php', 'OC\\Settings\\Controller\\GroupsController' => __DIR__ . '/../../..' . '/settings/Controller/GroupsController.php', '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\\SecuritySettingsController' => __DIR__ . '/../../..' . '/settings/Controller/SecuritySettingsController.php', 'OC\\Settings\\Controller\\UsersController' => __DIR__ . '/../../..' . '/settings/Controller/UsersController.php', 'OC\\Settings\\Hooks' => __DIR__ . '/../../..' . '/settings/Hooks.php', @@ -847,6 +849,10 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c 'OC\\Settings\\Manager' => __DIR__ . '/../../..' . '/lib/private/Settings/Manager.php', 'OC\\Settings\\Mapper' => __DIR__ . '/../../..' . '/lib/private/Settings/Mapper.php', 'OC\\Settings\\Middleware\\SubadminMiddleware' => __DIR__ . '/../../..' . '/settings/Middleware/SubadminMiddleware.php', + 'OC\\Settings\\Personal\\Additional' => __DIR__ . '/../../..' . '/lib/private/Settings/Personal/Additional.php', + 'OC\\Settings\\Personal\\PersonalInfo' => __DIR__ . '/../../..' . '/lib/private/Settings/Personal/PersonalInfo.php', + 'OC\\Settings\\Personal\\Security' => __DIR__ . '/../../..' . '/lib/private/Settings/Personal/Security.php', + 'OC\\Settings\\Personal\\SyncClients' => __DIR__ . '/../../..' . '/lib/private/Settings/Personal/SyncClients.php', 'OC\\Settings\\RemoveOrphaned' => __DIR__ . '/../../..' . '/lib/private/Settings/RemoveOrphaned.php', 'OC\\Settings\\Section' => __DIR__ . '/../../..' . '/lib/private/Settings/Section.php', 'OC\\Setup' => __DIR__ . '/../../..' . '/lib/private/Setup.php', From 8a8e78d439a18fa643b64e49a372a64b7d450fb4 Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Tue, 20 Jun 2017 12:01:50 +0200 Subject: [PATCH 24/42] already declared in Trait Signed-off-by: Arthur Schiwon --- settings/Controller/AdminSettingsController.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/settings/Controller/AdminSettingsController.php b/settings/Controller/AdminSettingsController.php index 804b7c217c..834534f95a 100644 --- a/settings/Controller/AdminSettingsController.php +++ b/settings/Controller/AdminSettingsController.php @@ -39,8 +39,6 @@ class AdminSettingsController extends Controller { /** @var INavigationManager */ private $navigationManager; - /** @var ISettingsManager */ - private $settingsManager; /** * @param string $appName From 26ca5635451b50b49c68bda995678d09516a41eb Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Tue, 20 Jun 2017 16:24:07 +0200 Subject: [PATCH 25/42] Fix and extend acceptance tests Signed-off-by: Arthur Schiwon --- .../acceptance/features/access-levels.feature | 20 +++++++--- .../bootstrap/SettingsMenuContext.php | 39 +++++++++++++++++++ .../features/core/ElementWrapper.php | 2 +- 3 files changed, 55 insertions(+), 6 deletions(-) diff --git a/tests/acceptance/features/access-levels.feature b/tests/acceptance/features/access-levels.feature index 57998899a5..91d6ba48e4 100644 --- a/tests/acceptance/features/access-levels.feature +++ b/tests/acceptance/features/access-levels.feature @@ -1,11 +1,10 @@ Feature: access-levels - Scenario: regular users can not see admin-level items in the Settings menu + Scenario: regular users cannot see admin-level items in the Settings menu Given I am logged in When I open the Settings menu Then I see that the Settings menu is shown - And I see that the "Personal" item in the Settings menu is shown - And I see that the "Admin" item in the Settings menu is not shown + And I see that the "Settings" item in the Settings menu is shown And I see that the "Users" item in the Settings menu is not shown And I see that the "Help" item in the Settings menu is shown And I see that the "Log out" item in the Settings menu is shown @@ -14,8 +13,19 @@ Feature: access-levels Given I am logged in as the admin When I open the Settings menu Then I see that the Settings menu is shown - And I see that the "Personal" item in the Settings menu is shown - And I see that the "Admin" item in the Settings menu is shown + And I see that the "Settings" item in the Settings menu is shown And I see that the "Users" item in the Settings menu is shown And I see that the "Help" item in the Settings menu is shown And I see that the "Log out" item in the Settings menu is shown + + Scenario: regular users cannot see amdin-level items on the Settings page + Given I am logged in + When I visit the settings page + Then I see that the "Personal" settings panel is shown + And I see that the "Administration" settings panel is not shown + + Scenario: admin users can see amdin-level items on the Settings page + Given I am logged in as the admin + When I visit the settings page + Then I see that the "Personal" settings panel is shown + And I see that the "Administration" settings panel is shown diff --git a/tests/acceptance/features/bootstrap/SettingsMenuContext.php b/tests/acceptance/features/bootstrap/SettingsMenuContext.php index 1ff5d94e98..29b959fa92 100644 --- a/tests/acceptance/features/bootstrap/SettingsMenuContext.php +++ b/tests/acceptance/features/bootstrap/SettingsMenuContext.php @@ -66,6 +66,15 @@ class SettingsMenuContext implements Context, ActorAwareInterface { describedAs($itemText . " item in Settings menu"); } + /** + * @param string $itemText + * @return Locator + */ + private static function settingsPanelFor($itemText) { + return Locator::forThe()->xpath("//div[@id = 'app-navigation']//ul//li[@class = 'settings-caption' and normalize-space() = '$itemText']")-> + describedAs($itemText . " item in Settings panel"); + } + /** * @When I open the Settings menu */ @@ -73,6 +82,7 @@ class SettingsMenuContext implements Context, ActorAwareInterface { $this->actor->find(self::settingsMenuButton(), 10)->click(); } + /** * @When I open the User settings */ @@ -82,6 +92,14 @@ class SettingsMenuContext implements Context, ActorAwareInterface { $this->actor->find(self::usersMenuItem(), 2)->click(); } + /** + * @When I visit the settings page + */ + public function iVisitTheSettingsPage() { + $this->iOpenTheSettingsMenu(); + $this->actor->find(self::menuItemFor('Settings'), 20)->click(); + } + /** * @When I log out */ @@ -120,4 +138,25 @@ class SettingsMenuContext implements Context, ActorAwareInterface { } } + /** + * @Then I see that the :itemText settings panel is shown + */ + public function iSeeThatTheItemSettingsPanelIsShown($itemText) { + PHPUnit_Framework_Assert::assertTrue( + $this->actor->find(self::settingsPanelFor($itemText), 10)->isVisible() + ); + } + + /** + * @Then I see that the :itemText settings panel is not shown + */ + public function iSeeThatTheItemSettingsPanelIsNotShown($itemText) { + try { + PHPUnit_Framework_Assert::assertFalse( + $this->actor->find(self::settingsPanelFor($itemText), 10)->isVisible() + ); + } catch (NoSuchElementException $exception) { + } + } + } diff --git a/tests/acceptance/features/core/ElementWrapper.php b/tests/acceptance/features/core/ElementWrapper.php index 6b730903f6..f6ce176817 100644 --- a/tests/acceptance/features/core/ElementWrapper.php +++ b/tests/acceptance/features/core/ElementWrapper.php @@ -119,7 +119,7 @@ class ElementWrapper { /** * Returns whether the wrapped element is visible or not. * - * @return boolbean true if the wrapped element is visible, false otherwise. + * @return bool true if the wrapped element is visible, false otherwise. */ public function isVisible() { $commandCallback = function() { From 9c85f552022656d17b55a9d265b0b977011468ba Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Thu, 22 Jun 2017 13:36:24 +0200 Subject: [PATCH 26/42] remove obsolete file Signed-off-by: Arthur Schiwon --- apps/files_external/personal.php | 47 -------------------------------- 1 file changed, 47 deletions(-) delete mode 100644 apps/files_external/personal.php diff --git a/apps/files_external/personal.php b/apps/files_external/personal.php deleted file mode 100644 index e213125238..0000000000 --- a/apps/files_external/personal.php +++ /dev/null @@ -1,47 +0,0 @@ - - * @author Michael Gapczynski - * @author Morris Jobke - * @author Robin Appelman - * @author Robin McCorkell - * @author Vincent Petry - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * 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, version 3, - * along with this program. If not, see - * - */ - -use \OCA\Files_External\Service\BackendService; - -// we must use the same container -$appContainer = \OC_Mount_Config::$app->getContainer(); -$backendService = $appContainer->query('OCA\Files_External\Service\BackendService'); -$userStoragesService = $appContainer->query('OCA\Files_External\Service\UserStoragesService'); -$globalAuth = $appContainer->query('OCA\Files_External\Lib\Auth\Password\GlobalAuth'); - -$tmpl = new OCP\Template('files_external', 'settings'); -$tmpl->assign('encryptionEnabled', \OC::$server->getEncryptionManager()->isEnabled()); -$tmpl->assign('visibilityType', BackendService::VISIBILITY_PERSONAL); -$tmpl->assign('storages', $userStoragesService->getStorages()); -$tmpl->assign('dependencies', OC_Mount_Config::dependencyMessage($backendService->getBackends())); -$tmpl->assign('backends', $backendService->getAvailableBackends()); -$tmpl->assign('authMechanisms', $backendService->getAuthMechanisms()); -$uid = \OC::$server->getUserSession()->getUser()->getUID(); -$tmpl->assign('globalCredentials', $globalAuth->getAuth($uid)); -$tmpl->assign('globalCredentialsUid', $uid); -$tmpl->assign('allowUserMounting', $backendService->isUserMountingAllowed()); -return $tmpl->fetchPage(); From 1ace1657b68687caa8cae48749eb1a98788eb244 Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Thu, 22 Jun 2017 15:05:39 +0200 Subject: [PATCH 27/42] adapt federatedfilesharing also drops IE8 switch Signed-off-by: Arthur Schiwon --- apps/federatedfilesharing/appinfo/app.php | 2 - apps/federatedfilesharing/appinfo/info.xml | 4 +- .../lib/AppInfo/Application.php | 7 -- .../lib/Settings/Personal.php | 101 ++++++++++++++++++ .../lib/Settings/PersonalSection.php | 86 +++++++++++++++ .../settings-personal.php | 72 ------------- .../templates/settings-personal.php | 2 - 7 files changed, 190 insertions(+), 84 deletions(-) create mode 100644 apps/federatedfilesharing/lib/Settings/Personal.php create mode 100644 apps/federatedfilesharing/lib/Settings/PersonalSection.php delete mode 100644 apps/federatedfilesharing/settings-personal.php diff --git a/apps/federatedfilesharing/appinfo/app.php b/apps/federatedfilesharing/appinfo/app.php index b6a145bcc2..62265ff064 100644 --- a/apps/federatedfilesharing/appinfo/app.php +++ b/apps/federatedfilesharing/appinfo/app.php @@ -26,8 +26,6 @@ use OCA\FederatedFileSharing\Notifier; $app = new \OCA\FederatedFileSharing\AppInfo\Application(); $eventDispatcher = \OC::$server->getEventDispatcher(); -$app->registerSettings(); - $manager = \OC::$server->getNotificationManager(); $manager->registerNotifier(function() { return \OC::$server->query(Notifier::class); diff --git a/apps/federatedfilesharing/appinfo/info.xml b/apps/federatedfilesharing/appinfo/info.xml index aaacf3ec80..ce2e2286be 100644 --- a/apps/federatedfilesharing/appinfo/info.xml +++ b/apps/federatedfilesharing/appinfo/info.xml @@ -6,7 +6,7 @@ AGPL Bjoern Schiessle Roeland Jago Douma - 1.3.0 + 1.3.1 FederatedFileSharing other @@ -14,5 +14,7 @@ OCA\FederatedFileSharing\Settings\Admin + OCA\FederatedFileSharing\Settings\Personal + OCA\FederatedFileSharing\Settings\PersonalSection diff --git a/apps/federatedfilesharing/lib/AppInfo/Application.php b/apps/federatedfilesharing/lib/AppInfo/Application.php index 346d3c4e29..a2e2f76186 100644 --- a/apps/federatedfilesharing/lib/AppInfo/Application.php +++ b/apps/federatedfilesharing/lib/AppInfo/Application.php @@ -69,13 +69,6 @@ class Application extends App { }); } - /** - * register personal and admin settings page - */ - public function registerSettings() { - \OCP\App::registerPersonal('federatedfilesharing', 'settings-personal'); - } - /** * get instance of federated share provider * diff --git a/apps/federatedfilesharing/lib/Settings/Personal.php b/apps/federatedfilesharing/lib/Settings/Personal.php new file mode 100644 index 0000000000..854f5f13ab --- /dev/null +++ b/apps/federatedfilesharing/lib/Settings/Personal.php @@ -0,0 +1,101 @@ + + * + * @author Arthur Schiwon + * + * @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\FederatedFileSharing\Settings; + + +use OCA\FederatedFileSharing\FederatedShareProvider; +use OCP\AppFramework\Http\TemplateResponse; +use OCP\IL10N; +use OCP\IURLGenerator; +use OCP\IUserSession; +use OCP\Settings\ISettings; + +class Personal implements ISettings { + + /** @var FederatedShareProvider */ + private $federatedShareProvider; + /** @var IUserSession */ + private $userSession; + /** @var IL10N */ + private $l; + /** @var IURLGenerator */ + private $urlGenerator; + /** @var \OC_Defaults */ + private $defaults; + + public function __construct( + FederatedShareProvider $federatedShareProvider, # + IUserSession $userSession, + IL10N $l, + IURLGenerator $urlGenerator, + \OC_Defaults $defaults + ) { + $this->federatedShareProvider = $federatedShareProvider; + $this->userSession = $userSession; + $this->l = $l; + $this->urlGenerator = $urlGenerator; + $this->defaults = $defaults; + } + + /** + * @return TemplateResponse returns the instance with all parameters set, ready to be rendered + * @since 9.1 + */ + public function getForm() { + $cloudID = $this->userSession->getUser()->getCloudId(); + $url = 'https://nextcloud.com/federation#' . $cloudID; + + $parameters = [ + 'outgoingServer2serverShareEnabled' => $this->federatedShareProvider->isOutgoingServer2serverShareEnabled(), + 'message_with_URL' => $this->l->t('Share with me through my #Nextcloud Federated Cloud ID, see %s', [$url]), + 'message_without_URL' => $this->l->t('Share with me through my #Nextcloud Federated Cloud ID', [$cloudID]), + 'logoPath' => $this->urlGenerator->imagePath('core', 'logo-icon.svg'), + 'reference' => $url, + 'cloudId' => $cloudID, + 'color' => $this->defaults->getColorPrimary(), + 'textColor' => "#ffffff", + ]; + return new TemplateResponse('federatedfilesharing', 'settings-personal', $parameters, ''); + } + + /** + * @return string the section ID, e.g. 'sharing' + * @since 9.1 + */ + public function getSection() { + return 'sharing'; + } + + /** + * @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. + * + * E.g.: 70 + * @since 9.1 + */ + public function getPriority() { + return 40; + } +} diff --git a/apps/federatedfilesharing/lib/Settings/PersonalSection.php b/apps/federatedfilesharing/lib/Settings/PersonalSection.php new file mode 100644 index 0000000000..e4e1bad721 --- /dev/null +++ b/apps/federatedfilesharing/lib/Settings/PersonalSection.php @@ -0,0 +1,86 @@ + + * + * @author Arthur Schiwon + * + * @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\FederatedFileSharing\Settings; + + +use OCP\IL10N; +use OCP\IURLGenerator; +use OCP\Settings\IIconSection; + +class PersonalSection implements IIconSection { + /** @var IURLGenerator */ + private $urlGenerator; + /** @var IL10N */ + private $l; + + public function __construct(IURLGenerator $urlGenerator, IL10N $l) { + $this->urlGenerator = $urlGenerator; + $this->l = $l; + } + + /** + * returns the relative path to an 16*16 icon describing the section. + * e.g. '/core/img/places/files.svg' + * + * @returns string + * @since 12 + */ + public function getIcon() { + return $this->urlGenerator->imagePath('core', 'actions/share.svg'); + } + + /** + * returns the ID of the section. It is supposed to be a lower case string, + * e.g. 'ldap' + * + * @returns string + * @since 9.1 + */ + public function getID() { + return 'sharing'; + } + + /** + * returns the translated name as it should be displayed, e.g. 'LDAP / AD + * integration'. Use the L10N service to translate it. + * + * @return string + * @since 9.1 + */ + public function getName() { + return $this->l->t('Sharing'); + } + + /** + * @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 + * @since 9.1 + */ + public function getPriority() { + return 15; + } +} diff --git a/apps/federatedfilesharing/settings-personal.php b/apps/federatedfilesharing/settings-personal.php deleted file mode 100644 index cd22cc1708..0000000000 --- a/apps/federatedfilesharing/settings-personal.php +++ /dev/null @@ -1,72 +0,0 @@ - - * @author Björn Schießle - * @author Jan-Christoph Borchardt - * @author Thomas Müller - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * 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, version 3, - * along with this program. If not, see - * - */ - -use OCA\FederatedFileSharing\AppInfo\Application; - -\OC_Util::checkLoggedIn(); - -$l = \OC::$server->getL10N('federatedfilesharing'); - -$app = new Application(); -$federatedShareProvider = $app->getFederatedShareProvider(); - -$isIE8 = false; -preg_match('/MSIE (.*?);/', $_SERVER['HTTP_USER_AGENT'], $matches); -if (count($matches) > 0 && $matches[1] <= 9) { - $isIE8 = true; -} - -$cloudID = \OC::$server->getUserSession()->getUser()->getCloudId(); -$url = 'https://nextcloud.com/federation#' . $cloudID; -$logoPath = \OC::$server->getURLGenerator()->imagePath('core', 'logo-icon.svg'); -/** @var \OCP\Defaults $theme */ -$theme = \OC::$server->query(\OCP\Defaults::class); -$color = $theme->getColorPrimary(); -$textColor = "#ffffff"; -if(\OC::$server->getAppManager()->isEnabledForUser("theming")) { - $logoPath = $theme->getLogo(); - try { - $util = \OC::$server->query("\OCA\Theming\Util"); - if($util->invertTextColor($color)) { - $textColor = "#000000"; - } - } catch (OCP\AppFramework\QueryException $e) { - - } -} - - -$tmpl = new OCP\Template('federatedfilesharing', 'settings-personal'); -$tmpl->assign('outgoingServer2serverShareEnabled', $federatedShareProvider->isOutgoingServer2serverShareEnabled()); -$tmpl->assign('message_with_URL', $l->t('Share with me through my #Nextcloud Federated Cloud ID, see %s', [$url])); -$tmpl->assign('message_without_URL', $l->t('Share with me through my #Nextcloud Federated Cloud ID', [$cloudID])); -$tmpl->assign('logoPath', $logoPath); -$tmpl->assign('reference', $url); -$tmpl->assign('cloudId', $cloudID); -$tmpl->assign('showShareIT', !$isIE8); -$tmpl->assign('color', $color); -$tmpl->assign('textColor', $textColor); - -return $tmpl->fetchPage(); diff --git a/apps/federatedfilesharing/templates/settings-personal.php b/apps/federatedfilesharing/templates/settings-personal.php index 126daae27d..c6be2a45f1 100644 --- a/apps/federatedfilesharing/templates/settings-personal.php +++ b/apps/federatedfilesharing/templates/settings-personal.php @@ -18,7 +18,6 @@ style('federatedfilesharing', 'settings-personal');
    -

    t('Share it so your friends can share files with you:')); ?>

    -
    From 7817811d13931886199c23c78b7d2df93800bf0d Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Thu, 22 Jun 2017 15:19:01 +0200 Subject: [PATCH 28/42] do not offer additional settings when there is no content Signed-off-by: Arthur Schiwon --- lib/private/Settings/Manager.php | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/lib/private/Settings/Manager.php b/lib/private/Settings/Manager.php index fe2932d976..db147e05eb 100644 --- a/lib/private/Settings/Manager.php +++ b/lib/private/Settings/Manager.php @@ -469,9 +469,13 @@ class Manager implements IManager { 0 => [new Section('personal-info', $this->l->t('Personal info'), 0, $this->url->imagePath('core', 'actions/info.svg'))], 5 => [new Section('security', $this->l->t('Security'), 0, $this->url->imagePath('settings', 'password.svg'))], 15 => [new Section('sync-clients', $this->l->t('Sync clients'), 0, $this->url->imagePath('settings', 'change.svg'))], - 98 => [new Section('additional', $this->l->t('Additional settings'), 0, $this->url->imagePath('core', 'actions/settings-dark.svg'))], ]; + $legacyForms = \OC_App::getForms('personal'); + if(count($legacyForms) > 0 && $this->hasLegacyPersonalSettingsToRender($legacyForms)) { + $sections[98] = [new Section('additional', $this->l->t('Additional settings'), 0, $this->url->imagePath('core', 'actions/settings-dark.svg'))]; + } + $rows = $this->mapper->getPersonalSectionsFromDB(); foreach ($rows as $row) { @@ -490,6 +494,19 @@ class Manager implements IManager { return $sections; } + /** + * @param $forms + * @return bool + */ + private function hasLegacyPersonalSettingsToRender($forms) { + foreach ($forms as $form) { + if(trim($form) !== '') { + return true; + } + } + return false; + } + /** * @inheritdoc */ From f6ecc46cfa6dcb5423497167fc19ffc2f3439938 Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Thu, 22 Jun 2017 17:33:45 +0200 Subject: [PATCH 29/42] adapt twofactore_backupcodes Signed-off-by: Arthur Schiwon --- apps/twofactor_backupcodes/appinfo/info.xml | 7 +- .../lib/AppInfo/Application.php | 8 -- .../lib/Settings/Personal.php | 82 ++++++++++++++++ .../lib/Settings/PersonalSection.php | 98 +++++++++++++++++++ .../settings/personal.php | 19 ---- settings/templates/settings/empty.php | 3 +- 6 files changed, 187 insertions(+), 30 deletions(-) create mode 100644 apps/twofactor_backupcodes/lib/Settings/Personal.php create mode 100644 apps/twofactor_backupcodes/lib/Settings/PersonalSection.php delete mode 100644 apps/twofactor_backupcodes/settings/personal.php diff --git a/apps/twofactor_backupcodes/appinfo/info.xml b/apps/twofactor_backupcodes/appinfo/info.xml index 92300320e1..b5399fbd77 100644 --- a/apps/twofactor_backupcodes/appinfo/info.xml +++ b/apps/twofactor_backupcodes/appinfo/info.xml @@ -5,7 +5,7 @@ A two-factor auth backup codes provider agpl Christoph Wurst - 1.2.0 + 1.2.1 TwoFactorBackupCodes other @@ -28,4 +28,9 @@ OCA\TwoFactorBackupCodes\Migration\CopyEntriesFromOldTable + + + OCA\TwoFactorBackupCodes\Settings\Personal + OCA\TwoFactorBackupCodes\Settings\PersonalSection + diff --git a/apps/twofactor_backupcodes/lib/AppInfo/Application.php b/apps/twofactor_backupcodes/lib/AppInfo/Application.php index ad92c0b147..050473f7ef 100644 --- a/apps/twofactor_backupcodes/lib/AppInfo/Application.php +++ b/apps/twofactor_backupcodes/lib/AppInfo/Application.php @@ -37,7 +37,6 @@ class Application extends App { */ public function register() { $this->registerHooksAndEvents(); - $this->registerPersonalPage(); } /** @@ -52,11 +51,4 @@ class Application extends App { $mapper = $this->getContainer()->query(BackupCodeMapper::class); $mapper->deleteCodesByUserId($params['uid']); } - - /** - * Register personal settings for notifications and emails - */ - public function registerPersonalPage() { - \OCP\App::registerPersonal($this->getContainer()->getAppName(), 'settings/personal'); - } } diff --git a/apps/twofactor_backupcodes/lib/Settings/Personal.php b/apps/twofactor_backupcodes/lib/Settings/Personal.php new file mode 100644 index 0000000000..0edd86fb14 --- /dev/null +++ b/apps/twofactor_backupcodes/lib/Settings/Personal.php @@ -0,0 +1,82 @@ + + * + * @author Arthur Schiwon + * + * @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\TwoFactorBackupCodes\Settings; + + +use OCA\TwoFactorBackupCodes\AppInfo\Application; +use OCA\TwoFactorBackupCodes\Provider\BackupCodesProvider; +use OCP\AppFramework\Http\TemplateResponse; +use OCP\IUserSession; +use OCP\Settings\ISettings; + +class Personal implements ISettings { + + /** @var Application */ + private $app; + /** @var BackupCodesProvider */ + private $provider; + /** @var IUserSession */ + private $userSession; + + public function __construct(Application $app, BackupCodesProvider $provider, IUserSession $userSession) { + $this->app = $app; + $this->provider = $provider; + $this->userSession = $userSession; + } + + /** + * @return TemplateResponse returns the instance with all parameters set, ready to be rendered + * @since 9.1 + */ + public function getForm() { + $templateOwner = 'settings'; + $templateName = 'settings/empty'; + if ($this->provider->isActive($this->userSession->getUser())) { + $templateOwner = $this->app->getContainer()->getAppName(); + $templateName = 'personal'; + } + + return new TemplateResponse($templateOwner, $templateName, [], ''); + } + + /** + * @return string the section ID, e.g. 'sharing' + * @since 9.1 + */ + public function getSection() { + return 'twofactor'; + } + + /** + * @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. + * + * E.g.: 70 + * @since 9.1 + */ + public function getPriority() { + return 85; + } +} diff --git a/apps/twofactor_backupcodes/lib/Settings/PersonalSection.php b/apps/twofactor_backupcodes/lib/Settings/PersonalSection.php new file mode 100644 index 0000000000..eb023306c3 --- /dev/null +++ b/apps/twofactor_backupcodes/lib/Settings/PersonalSection.php @@ -0,0 +1,98 @@ + + * + * @author Arthur Schiwon + * + * @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\TwoFactorBackupCodes\Settings; + + +use OCA\TwoFactorBackupCodes\Provider\BackupCodesProvider; +use OCP\IL10N; +use OCP\IURLGenerator; +use OCP\IUserSession; +use OCP\Settings\IIconSection; + +class PersonalSection implements IIconSection { + + /** @var IURLGenerator */ + private $urlGenerator; + /** @var IL10N */ + private $l; + /** @var BackupCodesProvider */ + private $provider; + /** @var IUserSession */ + private $userSession; + + public function __construct(IURLGenerator $urlGenerator, IL10N $l, BackupCodesProvider $provider, IUserSession $userSession) { + $this->urlGenerator = $urlGenerator; + $this->l = $l; + $this->provider = $provider; + $this->userSession = $userSession; + } + + /** + * returns the relative path to an 16*16 icon describing the section. + * e.g. '/core/img/places/files.svg' + * + * @returns string + * @since 12 + */ + public function getIcon() { + return $this->urlGenerator->imagePath('settings', 'password.svg'); + } + + /** + * returns the ID of the section. It is supposed to be a lower case string, + * e.g. 'ldap' + * + * @returns string + * @since 9.1 + */ + public function getID() { + if (!$this->provider->isActive($this->userSession->getUser())) { + return null; + } + return 'twofactor'; + } + + /** + * returns the translated name as it should be displayed, e.g. 'LDAP / AD + * integration'. Use the L10N service to translate it. + * + * @return string + * @since 9.1 + */ + public function getName() { + return $this->l->t('Second factor auth'); + } + + /** + * @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 + * @since 9.1 + */ + public function getPriority() { + return 8; + } +} diff --git a/apps/twofactor_backupcodes/settings/personal.php b/apps/twofactor_backupcodes/settings/personal.php deleted file mode 100644 index 48c84a3355..0000000000 --- a/apps/twofactor_backupcodes/settings/personal.php +++ /dev/null @@ -1,19 +0,0 @@ -query(BackupCodesProvider::class); -$user = OC::$server->getUserSession()->getUser(); - -if ($provider->isActive($user)) { - $tmpl = new Template('twofactor_backupcodes', 'personal'); - return $tmpl->fetchPage(); -} else { - return ""; -} - -// @codeCoverageIgnoreEnd diff --git a/settings/templates/settings/empty.php b/settings/templates/settings/empty.php index e7e728f87b..0ed8a873d3 100644 --- a/settings/templates/settings/empty.php +++ b/settings/templates/settings/empty.php @@ -21,6 +21,5 @@ * */ + # used for Personal/Additional settings as fallback for legacy settings ?> - - From b7ce492c59364faacd55fc90eebf4ed0a1c26115 Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Thu, 22 Jun 2017 18:06:32 +0200 Subject: [PATCH 30/42] adapt encryption Signed-off-by: Arthur Schiwon --- apps/encryption/appinfo/app.php | 1 - apps/encryption/appinfo/info.xml | 4 +- apps/encryption/lib/AppInfo/Application.php | 5 - apps/encryption/lib/Settings/Personal.php | 95 ++++++++++++++++ .../lib/Settings/PersonalSection.php | 105 ++++++++++++++++++ 5 files changed, 203 insertions(+), 7 deletions(-) create mode 100644 apps/encryption/lib/Settings/Personal.php create mode 100644 apps/encryption/lib/Settings/PersonalSection.php diff --git a/apps/encryption/appinfo/app.php b/apps/encryption/appinfo/app.php index 22c35f8791..950166dca2 100644 --- a/apps/encryption/appinfo/app.php +++ b/apps/encryption/appinfo/app.php @@ -31,5 +31,4 @@ $app = new Application([], $encryptionSystemReady); if ($encryptionSystemReady) { $app->registerEncryptionModule(); $app->registerHooks(); - $app->registerSettings(); } diff --git a/apps/encryption/appinfo/info.xml b/apps/encryption/appinfo/info.xml index 36b6774c6e..01e42ae370 100644 --- a/apps/encryption/appinfo/info.xml +++ b/apps/encryption/appinfo/info.xml @@ -19,7 +19,7 @@ user-encryption admin-encryption - 1.7.0 + 1.7.1 @@ -29,6 +29,8 @@ OCA\Encryption\Settings\Admin + OCA\Encryption\Settings\Personal + OCA\Encryption\Settings\PersonalSection OCA\Encryption\Command\EnableMasterKey diff --git a/apps/encryption/lib/AppInfo/Application.php b/apps/encryption/lib/AppInfo/Application.php index a43646d86d..56c2dafdab 100644 --- a/apps/encryption/lib/AppInfo/Application.php +++ b/apps/encryption/lib/AppInfo/Application.php @@ -266,9 +266,4 @@ class Application extends \OCP\AppFramework\App { ); } - - public function registerSettings() { - // Register settings scripts - App::registerPersonal('encryption', 'settings/settings-personal'); - } } diff --git a/apps/encryption/lib/Settings/Personal.php b/apps/encryption/lib/Settings/Personal.php new file mode 100644 index 0000000000..3d399e4fe1 --- /dev/null +++ b/apps/encryption/lib/Settings/Personal.php @@ -0,0 +1,95 @@ + + * + * @author Arthur Schiwon + * + * @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\Encryption\Settings; + + +use OCA\Encryption\Session; +use OCA\Encryption\Util; +use OCP\AppFramework\Http\TemplateResponse; +use OCP\IConfig; +use OCP\IUserSession; +use OCP\Settings\ISettings; + +class Personal implements ISettings { + + /** @var IConfig */ + private $config; + /** @var Session */ + private $session; + /** @var Util */ + private $util; + /** @var IUserSession */ + private $userSession; + + public function __construct(IConfig $config, Session $session, Util $util, IUserSession $userSession) { + $this->config = $config; + $this->session = $session; + $this->util = $util; + $this->userSession = $userSession; + } + + /** + * @return TemplateResponse returns the instance with all parameters set, ready to be rendered + * @since 9.1 + */ + public function getForm() { + $recoveryAdminEnabled = $this->config->getAppValue('encryption', 'recoveryAdminEnabled'); + $privateKeySet = $this->session->isPrivateKeySet(); + + if (!$recoveryAdminEnabled && $privateKeySet) { + return new TemplateResponse('settings', 'settings/empty', [], ''); + } + + $userId = $this->userSession->getUser()->getUID(); + $recoveryEnabledForUser = $this->util->isRecoveryEnabledForUser($userId); + + $parameters = [ + 'recoveryEnabled' => $recoveryAdminEnabled, + 'recoveryEnabledForUser' => $recoveryEnabledForUser, + 'privateKeySet' => $privateKeySet, + 'initialized' => $this->session->getStatus(), + ]; + return new TemplateResponse('encryption', 'settings-personal', $parameters, ''); + } + + /** + * @return string the section ID, e.g. 'sharing' + * @since 9.1 + */ + public function getSection() { + return 'encryption'; + } + + /** + * @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. + * + * E.g.: 70 + * @since 9.1 + */ + public function getPriority() { + return 10; + } +} diff --git a/apps/encryption/lib/Settings/PersonalSection.php b/apps/encryption/lib/Settings/PersonalSection.php new file mode 100644 index 0000000000..70e826a6ea --- /dev/null +++ b/apps/encryption/lib/Settings/PersonalSection.php @@ -0,0 +1,105 @@ + + * + * @author Arthur Schiwon + * + * @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\Encryption\Settings; + + +use OCA\Encryption\AppInfo\Application; +use OCA\Encryption\Session; +use OCP\IConfig; +use OCP\IL10N; +use OCP\IURLGenerator; +use OCP\Settings\IIconSection; + +class PersonalSection implements IIconSection { + + /** @var IURLGenerator */ + private $urlGenerator; + /** @var IL10N */ + private $l; + /** @var Application */ + private $app; + /** @var IConfig */ + private $config; + /** @var Session */ + private $session; + + public function __construct(IURLGenerator $urlGenerator, IL10N $l, Application $app, IConfig $config, Session $session) { + $this->urlGenerator = $urlGenerator; + $this->l = $l; + $this->app = $app; + $this->config = $config; + $this->session = $session; + } + + /** + * returns the relative path to an 16*16 icon describing the section. + * e.g. '/core/img/places/files.svg' + * + * @returns string + * @since 12 + */ + public function getIcon() { + return $this->urlGenerator->imagePath('settings', 'password.svg'); + } + + /** + * returns the ID of the section. It is supposed to be a lower case string, + * e.g. 'ldap' + * + * @returns string + * @since 9.1 + */ + public function getID() { + $recoveryAdminEnabled = $this->config->getAppValue('encryption', 'recoveryAdminEnabled'); + $privateKeySet = $this->session->isPrivateKeySet(); + + if (!$recoveryAdminEnabled && $privateKeySet) { + return null; + } + return 'encryption'; + } + + /** + * returns the translated name as it should be displayed, e.g. 'LDAP / AD + * integration'. Use the L10N service to translate it. + * + * @return string + * @since 9.1 + */ + public function getName() { + return $this->l->t('Encryption'); + } + + /** + * @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 + * @since 9.1 + */ + public function getPriority() { + return 10; + } +} From a596251d6b8b27ad5ea626d1939adab6866dfe61 Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Thu, 22 Jun 2017 18:15:33 +0200 Subject: [PATCH 31/42] avoid marking two sections as active when they have the same name MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit … in both personal and admin. --- .../Controller/AdminSettingsController.php | 2 +- settings/Controller/CommonSettingsTrait.php | 25 +++++++++++-------- .../Controller/PersonalSettingsController.php | 3 ++- 3 files changed, 17 insertions(+), 13 deletions(-) diff --git a/settings/Controller/AdminSettingsController.php b/settings/Controller/AdminSettingsController.php index 834534f95a..33d9cb2c2a 100644 --- a/settings/Controller/AdminSettingsController.php +++ b/settings/Controller/AdminSettingsController.php @@ -65,7 +65,7 @@ class AdminSettingsController extends Controller { */ public function index($section) { $this->navigationManager->setActiveEntry('admin'); - return $this->getIndexResponse($section); + return $this->getIndexResponse('admin', $section); } /** diff --git a/settings/Controller/CommonSettingsTrait.php b/settings/Controller/CommonSettingsTrait.php index 4854f40586..ac316aa7f4 100644 --- a/settings/Controller/CommonSettingsTrait.php +++ b/settings/Controller/CommonSettingsTrait.php @@ -36,14 +36,14 @@ trait CommonSettingsTrait { * @param string $currentSection * @return array */ - private function getNavigationParameters($currentSection) { + private function getNavigationParameters($currentType, $currentSection) { $templateParameters = [ - 'personal' => $this->formatPersonalSections($currentSection), + 'personal' => $this->formatPersonalSections($currentType, $currentSection), 'admin' => [] ]; if(\OC_User::isAdminUser(\OC_User::getUser())) { - $templateParameters['admin'] = $this->formatAdminSections($currentSection); + $templateParameters['admin'] = $this->formatAdminSections($currentType, $currentSection); } return [ @@ -51,7 +51,7 @@ trait CommonSettingsTrait { ]; } - protected function formatSections($sections, $currentSection, $type) { + protected function formatSections($sections, $currentSection, $type, $currentType) { $templateParameters = []; /** @var \OCP\Settings\ISection[] $prioritizedSections */ foreach($sections as $prioritizedSections) { @@ -70,10 +70,13 @@ trait CommonSettingsTrait { $icon = $section->getIcon(); } + $active = $section->getID() === $currentSection + && $type === $currentType; + $templateParameters[] = [ 'anchor' => $section->getID(), 'section-name' => $section->getName(), - 'active' => $section->getID() === $currentSection, + 'active' => $active, 'icon' => $icon, ]; } @@ -81,16 +84,16 @@ trait CommonSettingsTrait { return $templateParameters; } - protected function formatPersonalSections($currentSections) { + protected function formatPersonalSections($currentType, $currentSections) { $sections = $this->settingsManager->getPersonalSections(); - $templateParameters = $this->formatSections($sections, $currentSections, 'personal'); + $templateParameters = $this->formatSections($sections, $currentSections, 'personal', $currentType); return $templateParameters; } - protected function formatAdminSections($currentSections) { + protected function formatAdminSections($currentType, $currentSections) { $sections = $this->settingsManager->getAdminSections(); - $templateParameters = $this->formatSections($sections, $currentSections, 'admin'); + $templateParameters = $this->formatSections($sections, $currentSections, 'admin', $currentType); return $templateParameters; } @@ -111,9 +114,9 @@ trait CommonSettingsTrait { return ['content' => $html]; } - private function getIndexResponse($section) { + private function getIndexResponse($type, $section) { $templateParams = []; - $templateParams = array_merge($templateParams, $this->getNavigationParameters($section)); + $templateParams = array_merge($templateParams, $this->getNavigationParameters($type, $section)); $templateParams = array_merge($templateParams, $this->getSettings($section)); return new TemplateResponse('settings', 'settings/frame', $templateParams); diff --git a/settings/Controller/PersonalSettingsController.php b/settings/Controller/PersonalSettingsController.php index 3ccef025a7..7e2d62961b 100644 --- a/settings/Controller/PersonalSettingsController.php +++ b/settings/Controller/PersonalSettingsController.php @@ -57,7 +57,8 @@ class PersonalSettingsController extends Controller { */ public function index($section) { $this->navigationManager->setActiveEntry('personal'); - return $this->getIndexResponse($section); + return $this->getIndexResponse('personal', $section); + } /** From d881a3c37b627fa5b5de282df93be3af93ff829c Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Fri, 23 Jun 2017 13:15:08 +0200 Subject: [PATCH 32/42] adapt to force language changes Signed-off-by: Arthur Schiwon --- .../Settings/Personal/PersonalInfo.php | 23 +++++++---- settings/js/settings/personalInfo.js | 38 +++++++++++-------- .../settings/personal/personal.info.php | 2 + 3 files changed, 41 insertions(+), 22 deletions(-) diff --git a/lib/private/Settings/Personal/PersonalInfo.php b/lib/private/Settings/Personal/PersonalInfo.php index eb0ff253db..fb1f388c59 100644 --- a/lib/private/Settings/Personal/PersonalInfo.php +++ b/lib/private/Settings/Personal/PersonalInfo.php @@ -110,7 +110,7 @@ class PersonalInfo implements ISettings { $totalSpace = \OC_Helper::humanFileSize($storageInfo['total']); } - list($activeLanguage, $commonLanguages, $languages) = $this->getLanguages($user); + $languageParameters = $this->getLanguages($user); $messageParameters = $this->getMessageParameters($userData); $parameters = [ @@ -139,10 +139,7 @@ class PersonalInfo implements ISettings { 'twitterVerification' => $userData[AccountManager::PROPERTY_TWITTER]['verified'], 'groups' => $this->getGroups($user), 'passwordChangeSupported' => \OC_User::canUserChangePassword($uid), - 'activelanguage' => $activeLanguage, - 'commonlanguages' => $commonLanguages, - 'languages' => $languages, - ] + $messageParameters; + ] + $messageParameters + $languageParameters; return new TemplateResponse('settings', 'settings/personal/personal.info', $parameters, ''); @@ -194,11 +191,19 @@ class PersonalInfo implements ISettings { * @return array */ private function getLanguages(IUser $user) { + $forceLanguage = $this->config->getSystemValue('force_language', false); + if($forceLanguage !== false) { + return []; + } + $uid = $user->getUID(); - $commonLanguages = []; $userLang = $this->config->getUserValue($uid, 'core', 'lang', $this->l10nFactory->findLanguage()); $languageCodes = $this->l10nFactory->findAvailableLanguages(); + + $commonLanguages = []; + $languages = []; + foreach($languageCodes as $lang) { $l = \OC::$server->getL10N('settings', $lang); // TRANSLATORS this is the language name for the language switcher in the personal settings and should be the localized version @@ -246,7 +251,11 @@ class PersonalInfo implements ISettings { return strcmp($a['name'], $b['name']); }); - return [$userLang, $commonLanguages, $languages]; + return [ + 'activelanguage' => $userLang, + 'commonlanguages' => $commonLanguages, + 'languages' => $languages + ]; } /** diff --git a/settings/js/settings/personalInfo.js b/settings/js/settings/personalInfo.js index 9496f65a8f..306994a709 100644 --- a/settings/js/settings/personalInfo.js +++ b/settings/js/settings/personalInfo.js @@ -259,23 +259,31 @@ $(document).ready(function () { }); federationSettingsView.render(); - $("#languageinput").change(function () { - // Serialize the data - var post = $("#languageinput").serialize(); - // Ajax foo - $.ajax( - 'ajax/setlanguage.php', - { - method: 'POST', - data: post + var updateLanguage = function () { + if (OC.PasswordConfirmation.requiresPasswordConfirmation()) { + OC.PasswordConfirmation.requirePasswordConfirmation(updateLanguage); + return; + } + + var selectedLang = $("#languageinput").val(), + user = OC.getCurrentUser(); + + $.ajax({ + url: OC.linkToOCS('cloud/users', 2) + user['uid'], + method: 'PUT', + data: { + key: 'language', + value: selectedLang + }, + success: function() { + location.reload(); + }, + fail: function() { + OC.Notification.showTemporary(t('settings', 'An error occured while changing your language. Please reload the page and try again.')); } - ).done(function() { - location.reload(); - }).fail(function(jqXHR) { - $('#passworderror').text(jqXHR.responseJSON.message); }); - return false; - }); + }; + $("#languageinput").change(updateLanguage); var uploadparms = { pasteZone: null, diff --git a/settings/templates/settings/personal/personal.info.php b/settings/templates/settings/personal/personal.info.php index 8cb9aec8af..db14a4de98 100644 --- a/settings/templates/settings/personal/personal.info.php +++ b/settings/templates/settings/personal/personal.info.php @@ -287,6 +287,7 @@ if($_['passwordChangeSupported']) { } ?> +

    @@ -312,3 +313,4 @@ if($_['passwordChangeSupported']) { t('Help translate'));?> + From c5df6db6318a7cd2dacc85a895b35cd571ad3ac9 Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Fri, 23 Jun 2017 13:18:08 +0200 Subject: [PATCH 33/42] move twofactor_* into security Signed-off-by: Arthur Schiwon --- apps/twofactor_backupcodes/appinfo/info.xml | 3 +- .../lib/Settings/Personal.php | 2 +- .../lib/Settings/PersonalSection.php | 98 ------------------- 3 files changed, 2 insertions(+), 101 deletions(-) delete mode 100644 apps/twofactor_backupcodes/lib/Settings/PersonalSection.php diff --git a/apps/twofactor_backupcodes/appinfo/info.xml b/apps/twofactor_backupcodes/appinfo/info.xml index b5399fbd77..7faf2825be 100644 --- a/apps/twofactor_backupcodes/appinfo/info.xml +++ b/apps/twofactor_backupcodes/appinfo/info.xml @@ -5,7 +5,7 @@ A two-factor auth backup codes provider agpl Christoph Wurst - 1.2.1 + 1.2.0 TwoFactorBackupCodes other @@ -31,6 +31,5 @@ OCA\TwoFactorBackupCodes\Settings\Personal - OCA\TwoFactorBackupCodes\Settings\PersonalSection diff --git a/apps/twofactor_backupcodes/lib/Settings/Personal.php b/apps/twofactor_backupcodes/lib/Settings/Personal.php index 0edd86fb14..56eead1639 100644 --- a/apps/twofactor_backupcodes/lib/Settings/Personal.php +++ b/apps/twofactor_backupcodes/lib/Settings/Personal.php @@ -65,7 +65,7 @@ class Personal implements ISettings { * @since 9.1 */ public function getSection() { - return 'twofactor'; + return 'security'; } /** diff --git a/apps/twofactor_backupcodes/lib/Settings/PersonalSection.php b/apps/twofactor_backupcodes/lib/Settings/PersonalSection.php deleted file mode 100644 index eb023306c3..0000000000 --- a/apps/twofactor_backupcodes/lib/Settings/PersonalSection.php +++ /dev/null @@ -1,98 +0,0 @@ - - * - * @author Arthur Schiwon - * - * @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\TwoFactorBackupCodes\Settings; - - -use OCA\TwoFactorBackupCodes\Provider\BackupCodesProvider; -use OCP\IL10N; -use OCP\IURLGenerator; -use OCP\IUserSession; -use OCP\Settings\IIconSection; - -class PersonalSection implements IIconSection { - - /** @var IURLGenerator */ - private $urlGenerator; - /** @var IL10N */ - private $l; - /** @var BackupCodesProvider */ - private $provider; - /** @var IUserSession */ - private $userSession; - - public function __construct(IURLGenerator $urlGenerator, IL10N $l, BackupCodesProvider $provider, IUserSession $userSession) { - $this->urlGenerator = $urlGenerator; - $this->l = $l; - $this->provider = $provider; - $this->userSession = $userSession; - } - - /** - * returns the relative path to an 16*16 icon describing the section. - * e.g. '/core/img/places/files.svg' - * - * @returns string - * @since 12 - */ - public function getIcon() { - return $this->urlGenerator->imagePath('settings', 'password.svg'); - } - - /** - * returns the ID of the section. It is supposed to be a lower case string, - * e.g. 'ldap' - * - * @returns string - * @since 9.1 - */ - public function getID() { - if (!$this->provider->isActive($this->userSession->getUser())) { - return null; - } - return 'twofactor'; - } - - /** - * returns the translated name as it should be displayed, e.g. 'LDAP / AD - * integration'. Use the L10N service to translate it. - * - * @return string - * @since 9.1 - */ - public function getName() { - return $this->l->t('Second factor auth'); - } - - /** - * @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 - * @since 9.1 - */ - public function getPriority() { - return 8; - } -} From 39ca06e6b9bfc85efc6c2f15090b0719b1e4f0ef Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Fri, 23 Jun 2017 13:38:33 +0200 Subject: [PATCH 34/42] fix setting up encryption section Signed-off-by: Arthur Schiwon --- .../lib/Settings/PersonalSection.php | 18 ++++- .../encryption/settings/settings-personal.php | 76 ------------------- 2 files changed, 16 insertions(+), 78 deletions(-) delete mode 100644 apps/encryption/settings/settings-personal.php diff --git a/apps/encryption/lib/Settings/PersonalSection.php b/apps/encryption/lib/Settings/PersonalSection.php index 70e826a6ea..fd25d25ef8 100644 --- a/apps/encryption/lib/Settings/PersonalSection.php +++ b/apps/encryption/lib/Settings/PersonalSection.php @@ -29,6 +29,7 @@ use OCA\Encryption\Session; use OCP\IConfig; use OCP\IL10N; use OCP\IURLGenerator; +use OCP\IUserSession; use OCP\Settings\IIconSection; class PersonalSection implements IIconSection { @@ -43,13 +44,23 @@ class PersonalSection implements IIconSection { private $config; /** @var Session */ private $session; + /** @var IUserSession */ + private $userSession; - public function __construct(IURLGenerator $urlGenerator, IL10N $l, Application $app, IConfig $config, Session $session) { + public function __construct( + IURLGenerator $urlGenerator, + IL10N $l, + Application $app, + IConfig $config, + Session $session, + IUserSession $userSession + ) { $this->urlGenerator = $urlGenerator; $this->l = $l; $this->app = $app; $this->config = $config; $this->session = $session; + $this->userSession = $userSession; } /** @@ -71,10 +82,13 @@ class PersonalSection implements IIconSection { * @since 9.1 */ public function getID() { + // we need to return the proper id while installing/upgrading the app + $loggedIn = $this->userSession->isLoggedIn(); + $recoveryAdminEnabled = $this->config->getAppValue('encryption', 'recoveryAdminEnabled'); $privateKeySet = $this->session->isPrivateKeySet(); - if (!$recoveryAdminEnabled && $privateKeySet) { + if ($loggedIn && !$recoveryAdminEnabled && $privateKeySet) { return null; } return 'encryption'; diff --git a/apps/encryption/settings/settings-personal.php b/apps/encryption/settings/settings-personal.php deleted file mode 100644 index 6608340888..0000000000 --- a/apps/encryption/settings/settings-personal.php +++ /dev/null @@ -1,76 +0,0 @@ - - * @author Clark Tomlinson - * @author Thomas Müller - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * 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, version 3, - * along with this program. If not, see - * - */ - -$session = new \OCA\Encryption\Session(\OC::$server->getSession()); -$userSession = \OC::$server->getUserSession(); - -$template = new OCP\Template('encryption', 'settings-personal'); -$crypt = new \OCA\Encryption\Crypto\Crypt( - \OC::$server->getLogger(), - $userSession, - \OC::$server->getConfig(), - \OC::$server->getL10N('encryption')); - -$util = new \OCA\Encryption\Util( - new \OC\Files\View(), - $crypt, - \OC::$server->getLogger(), - $userSession, - \OC::$server->getConfig(), - \OC::$server->getUserManager()); - -$keyManager = new \OCA\Encryption\KeyManager( - \OC::$server->getEncryptionKeyStorage(), - $crypt, - \OC::$server->getConfig(), - $userSession, - $session, - \OC::$server->getLogger(), $util); - -$user = $userSession->getUser()->getUID(); - -$view = new \OC\Files\View('/'); - - - -$privateKeySet = $session->isPrivateKeySet(); -// did we tried to initialize the keys for this session? -$initialized = $session->getStatus(); - -$recoveryAdminEnabled = \OC::$server->getConfig()->getAppValue('encryption', 'recoveryAdminEnabled'); -$recoveryEnabledForUser = $util->isRecoveryEnabledForUser($user); - -$result = false; - -if ($recoveryAdminEnabled || !$privateKeySet) { - $template->assign('recoveryEnabled', $recoveryAdminEnabled); - $template->assign('recoveryEnabledForUser', $recoveryEnabledForUser); - $template->assign('privateKeySet', $privateKeySet); - $template->assign('initialized', $initialized); - - $result = $template->fetchPage(); -} - -return $result; - From 8750d5b80225d3a7e341db8594b0f54db2f7b5eb Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Fri, 23 Jun 2017 14:34:55 +0200 Subject: [PATCH 35/42] take out additional (legacy) settings section from tests because it is dependent whether anything else registers into it and \OC_App is static Signed-off-by: Arthur Schiwon --- tests/lib/Settings/ManagerTest.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/lib/Settings/ManagerTest.php b/tests/lib/Settings/ManagerTest.php index 83dbbe5c2a..0c66bf19e8 100644 --- a/tests/lib/Settings/ManagerTest.php +++ b/tests/lib/Settings/ManagerTest.php @@ -232,12 +232,11 @@ class ManagerTest extends TestCase { ['core', 'actions/settings-dark.svg', '4'], ]); - $this->assertEquals([ + $this->assertArraySubset([ 0 => [new Section('personal-info', 'Personal info', 0, '1')], 5 => [new Section('security', 'Security', 0, '2')], 15 => [new Section('sync-clients', 'Sync clients', 0, '3')], 90 => [\OC::$server->query(\OCA\WorkflowEngine\Settings\Section::class)], - 98 => [new Section('additional', 'Additional settings', 0, '4')], ], $this->manager->getPersonalSections()); } From b6b19346b4c5583677545b4b9a6c83ac3fce1b56 Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Fri, 23 Jun 2017 22:19:18 +0200 Subject: [PATCH 36/42] forgotten test adjustments Signed-off-by: Arthur Schiwon --- tests/lib/Settings/ManagerTest.php | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/tests/lib/Settings/ManagerTest.php b/tests/lib/Settings/ManagerTest.php index 0c66bf19e8..6a13b737c8 100644 --- a/tests/lib/Settings/ManagerTest.php +++ b/tests/lib/Settings/ManagerTest.php @@ -223,13 +223,12 @@ class ManagerTest extends TestCase { ['class' => \OCA\WorkflowEngine\Settings\Section::class, 'priority' => 90] ])); - $this->url->expects($this->exactly(4)) + $this->url->expects($this->exactly(3)) ->method('imagePath') ->willReturnMap([ ['core', 'actions/info.svg', '1'], ['settings', 'password.svg', '2'], ['settings', 'change.svg', '3'], - ['core', 'actions/settings-dark.svg', '4'], ]); $this->assertArraySubset([ @@ -281,20 +280,18 @@ class ManagerTest extends TestCase { ->method('getPersonalSectionsFromDB') ->will($this->returnValue([])); - $this->url->expects($this->exactly(4)) + $this->url->expects($this->exactly(3)) ->method('imagePath') ->willReturnMap([ ['core', 'actions/info.svg', '1'], ['settings', 'password.svg', '2'], ['settings', 'change.svg', '3'], - ['core', 'actions/settings-dark.svg', '4'], ]); - $this->assertEquals([ + $this->assertArraySubset([ 0 => [new Section('personal-info', 'Personal info', 0, '1')], 5 => [new Section('security', 'Security', 0, '2')], 15 => [new Section('sync-clients', 'Sync clients', 0, '3')], - 98 => [new Section('additional', 'Additional settings', 0, '4')], ], $this->manager->getPersonalSections()); } From cfa5eea902afe138ec7c1115d90ff5ad543d9c9a Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Mon, 26 Jun 2017 10:30:42 +0200 Subject: [PATCH 37/42] fix typos and unnecessary white spaces Signed-off-by: Arthur Schiwon --- tests/acceptance/features/access-levels.feature | 8 ++++---- .../acceptance/features/bootstrap/SettingsMenuContext.php | 1 - 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/tests/acceptance/features/access-levels.feature b/tests/acceptance/features/access-levels.feature index 91d6ba48e4..8017029667 100644 --- a/tests/acceptance/features/access-levels.feature +++ b/tests/acceptance/features/access-levels.feature @@ -18,14 +18,14 @@ Feature: access-levels And I see that the "Help" item in the Settings menu is shown And I see that the "Log out" item in the Settings menu is shown - Scenario: regular users cannot see amdin-level items on the Settings page - Given I am logged in + Scenario: regular users cannot see admin-level items on the Settings page + Given I am logged in When I visit the settings page Then I see that the "Personal" settings panel is shown And I see that the "Administration" settings panel is not shown - Scenario: admin users can see amdin-level items on the Settings page - Given I am logged in as the admin + Scenario: admin users can see admin-level items on the Settings page + Given I am logged in as the admin When I visit the settings page Then I see that the "Personal" settings panel is shown And I see that the "Administration" settings panel is shown diff --git a/tests/acceptance/features/bootstrap/SettingsMenuContext.php b/tests/acceptance/features/bootstrap/SettingsMenuContext.php index 29b959fa92..712036d560 100644 --- a/tests/acceptance/features/bootstrap/SettingsMenuContext.php +++ b/tests/acceptance/features/bootstrap/SettingsMenuContext.php @@ -82,7 +82,6 @@ class SettingsMenuContext implements Context, ActorAwareInterface { $this->actor->find(self::settingsMenuButton(), 10)->click(); } - /** * @When I open the User settings */ From da5316265684561b9308d5cb190d4ad0352b7825 Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Mon, 26 Jun 2017 11:03:41 +0200 Subject: [PATCH 38/42] =?UTF-8?q?We're=20on=2013=20now=E2=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Arthur Schiwon --- apps/encryption/lib/Settings/PersonalSection.php | 2 +- .../federatedfilesharing/lib/Settings/PersonalSection.php | 2 +- lib/public/Settings/IManager.php | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/encryption/lib/Settings/PersonalSection.php b/apps/encryption/lib/Settings/PersonalSection.php index fd25d25ef8..1af4229bcd 100644 --- a/apps/encryption/lib/Settings/PersonalSection.php +++ b/apps/encryption/lib/Settings/PersonalSection.php @@ -68,7 +68,7 @@ class PersonalSection implements IIconSection { * e.g. '/core/img/places/files.svg' * * @returns string - * @since 12 + * @since 13.0.0 */ public function getIcon() { return $this->urlGenerator->imagePath('settings', 'password.svg'); diff --git a/apps/federatedfilesharing/lib/Settings/PersonalSection.php b/apps/federatedfilesharing/lib/Settings/PersonalSection.php index e4e1bad721..330a4efd7f 100644 --- a/apps/federatedfilesharing/lib/Settings/PersonalSection.php +++ b/apps/federatedfilesharing/lib/Settings/PersonalSection.php @@ -44,7 +44,7 @@ class PersonalSection implements IIconSection { * e.g. '/core/img/places/files.svg' * * @returns string - * @since 12 + * @since 13.0.0 */ public function getIcon() { return $this->urlGenerator->imagePath('core', 'actions/share.svg'); diff --git a/lib/public/Settings/IManager.php b/lib/public/Settings/IManager.php index 1242f83515..7a24eab389 100644 --- a/lib/public/Settings/IManager.php +++ b/lib/public/Settings/IManager.php @@ -38,12 +38,12 @@ interface IManager { const KEY_ADMIN_SECTION = 'admin-section'; /** - * @since 12.0.0 + * @since 13.0.0 */ const KEY_PERSONAL_SETTINGS = 'personal'; /** - * @since 12.0.0 + * @since 13.0.0 */ const KEY_PERSONAL_SECTION = 'personal-section'; @@ -101,7 +101,7 @@ interface IManager { * returns a list of the personal sections * * @return array array of ISection[] where key is the priority - * @since 12.0.0 + * @since 13.0.0 */ public function getPersonalSections(); @@ -119,7 +119,7 @@ interface IManager { * * @param string $section the section id for which to load the settings * @return array array of IPersonal[] where key is the priority - * @since 12.0.0 + * @since 13.0.0 */ public function getPersonalSettings($section); } From 6b5bbe18807c9b247a3b4f7d9d0739b8b791d9dd Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Mon, 26 Jun 2017 14:42:07 +0200 Subject: [PATCH 39/42] try to lower the timeout in an acceptance test Signed-off-by: Arthur Schiwon --- tests/acceptance/features/bootstrap/SettingsMenuContext.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/acceptance/features/bootstrap/SettingsMenuContext.php b/tests/acceptance/features/bootstrap/SettingsMenuContext.php index 712036d560..401575c78f 100644 --- a/tests/acceptance/features/bootstrap/SettingsMenuContext.php +++ b/tests/acceptance/features/bootstrap/SettingsMenuContext.php @@ -96,7 +96,7 @@ class SettingsMenuContext implements Context, ActorAwareInterface { */ public function iVisitTheSettingsPage() { $this->iOpenTheSettingsMenu(); - $this->actor->find(self::menuItemFor('Settings'), 20)->click(); + $this->actor->find(self::menuItemFor('Settings'), 2)->click(); } /** From 793de6a8d0906ec2f01cc3ee293493e5ae1a0d7a Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Tue, 27 Jun 2017 12:21:18 +0200 Subject: [PATCH 40/42] move encryption to security (and behind two factor things) Signed-off-by: Arthur Schiwon --- apps/encryption/appinfo/info.xml | 1 - apps/encryption/lib/Settings/Personal.php | 4 +- .../lib/Settings/PersonalSection.php | 119 ------------------ .../lib/Settings/Personal.php | 2 +- 4 files changed, 3 insertions(+), 123 deletions(-) delete mode 100644 apps/encryption/lib/Settings/PersonalSection.php diff --git a/apps/encryption/appinfo/info.xml b/apps/encryption/appinfo/info.xml index 01e42ae370..7cfdc93438 100644 --- a/apps/encryption/appinfo/info.xml +++ b/apps/encryption/appinfo/info.xml @@ -30,7 +30,6 @@ OCA\Encryption\Settings\Admin OCA\Encryption\Settings\Personal - OCA\Encryption\Settings\PersonalSection OCA\Encryption\Command\EnableMasterKey diff --git a/apps/encryption/lib/Settings/Personal.php b/apps/encryption/lib/Settings/Personal.php index 3d399e4fe1..5b01c22453 100644 --- a/apps/encryption/lib/Settings/Personal.php +++ b/apps/encryption/lib/Settings/Personal.php @@ -78,7 +78,7 @@ class Personal implements ISettings { * @since 9.1 */ public function getSection() { - return 'encryption'; + return 'security'; } /** @@ -90,6 +90,6 @@ class Personal implements ISettings { * @since 9.1 */ public function getPriority() { - return 10; + return 80; } } diff --git a/apps/encryption/lib/Settings/PersonalSection.php b/apps/encryption/lib/Settings/PersonalSection.php deleted file mode 100644 index 1af4229bcd..0000000000 --- a/apps/encryption/lib/Settings/PersonalSection.php +++ /dev/null @@ -1,119 +0,0 @@ - - * - * @author Arthur Schiwon - * - * @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\Encryption\Settings; - - -use OCA\Encryption\AppInfo\Application; -use OCA\Encryption\Session; -use OCP\IConfig; -use OCP\IL10N; -use OCP\IURLGenerator; -use OCP\IUserSession; -use OCP\Settings\IIconSection; - -class PersonalSection implements IIconSection { - - /** @var IURLGenerator */ - private $urlGenerator; - /** @var IL10N */ - private $l; - /** @var Application */ - private $app; - /** @var IConfig */ - private $config; - /** @var Session */ - private $session; - /** @var IUserSession */ - private $userSession; - - public function __construct( - IURLGenerator $urlGenerator, - IL10N $l, - Application $app, - IConfig $config, - Session $session, - IUserSession $userSession - ) { - $this->urlGenerator = $urlGenerator; - $this->l = $l; - $this->app = $app; - $this->config = $config; - $this->session = $session; - $this->userSession = $userSession; - } - - /** - * returns the relative path to an 16*16 icon describing the section. - * e.g. '/core/img/places/files.svg' - * - * @returns string - * @since 13.0.0 - */ - public function getIcon() { - return $this->urlGenerator->imagePath('settings', 'password.svg'); - } - - /** - * returns the ID of the section. It is supposed to be a lower case string, - * e.g. 'ldap' - * - * @returns string - * @since 9.1 - */ - public function getID() { - // we need to return the proper id while installing/upgrading the app - $loggedIn = $this->userSession->isLoggedIn(); - - $recoveryAdminEnabled = $this->config->getAppValue('encryption', 'recoveryAdminEnabled'); - $privateKeySet = $this->session->isPrivateKeySet(); - - if ($loggedIn && !$recoveryAdminEnabled && $privateKeySet) { - return null; - } - return 'encryption'; - } - - /** - * returns the translated name as it should be displayed, e.g. 'LDAP / AD - * integration'. Use the L10N service to translate it. - * - * @return string - * @since 9.1 - */ - public function getName() { - return $this->l->t('Encryption'); - } - - /** - * @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 - * @since 9.1 - */ - public function getPriority() { - return 10; - } -} diff --git a/apps/twofactor_backupcodes/lib/Settings/Personal.php b/apps/twofactor_backupcodes/lib/Settings/Personal.php index 56eead1639..eb28dacb42 100644 --- a/apps/twofactor_backupcodes/lib/Settings/Personal.php +++ b/apps/twofactor_backupcodes/lib/Settings/Personal.php @@ -77,6 +77,6 @@ class Personal implements ISettings { * @since 9.1 */ public function getPriority() { - return 85; + return 40; } } From 005ef115fbffecb22a7ac9e65425419aca90c1aa Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Tue, 27 Jun 2017 12:25:37 +0200 Subject: [PATCH 41/42] move admin templates to the right place Signed-off-by: Arthur Schiwon --- lib/private/Settings/Admin/Additional.php | 2 +- lib/private/Settings/Admin/Encryption.php | 2 +- lib/private/Settings/Admin/Server.php | 2 +- lib/private/Settings/Admin/ServerDevNotice.php | 2 +- lib/private/Settings/Admin/Sharing.php | 2 +- lib/private/Settings/Admin/TipsTricks.php | 2 +- settings/templates/{ => settings}/admin/additional-mail.php | 0 settings/templates/{ => settings}/admin/encryption.php | 0 .../{ => settings}/admin/server.development.notice.php | 0 settings/templates/{ => settings}/admin/server.php | 0 settings/templates/{ => settings}/admin/sharing.php | 0 settings/templates/{ => settings}/admin/tipstricks.php | 0 12 files changed, 6 insertions(+), 6 deletions(-) rename settings/templates/{ => settings}/admin/additional-mail.php (100%) rename settings/templates/{ => settings}/admin/encryption.php (100%) rename settings/templates/{ => settings}/admin/server.development.notice.php (100%) rename settings/templates/{ => settings}/admin/server.php (100%) rename settings/templates/{ => settings}/admin/sharing.php (100%) rename settings/templates/{ => settings}/admin/tipstricks.php (100%) diff --git a/lib/private/Settings/Admin/Additional.php b/lib/private/Settings/Admin/Additional.php index ffa0de6848..57bb382c1f 100644 --- a/lib/private/Settings/Admin/Additional.php +++ b/lib/private/Settings/Admin/Additional.php @@ -61,7 +61,7 @@ class Additional implements ISettings { $parameters['mail_smtppassword'] = '********'; } - return new TemplateResponse('settings', 'admin/additional-mail', $parameters, ''); + return new TemplateResponse('settings', 'settings/admin/additional-mail', $parameters, ''); } /** diff --git a/lib/private/Settings/Admin/Encryption.php b/lib/private/Settings/Admin/Encryption.php index 63020c6bce..7ee4bafbfe 100644 --- a/lib/private/Settings/Admin/Encryption.php +++ b/lib/private/Settings/Admin/Encryption.php @@ -68,7 +68,7 @@ class Encryption implements ISettings { 'encryptionModules' => $encryptionModuleList, ]; - return new TemplateResponse('settings', 'admin/encryption', $parameters, ''); + return new TemplateResponse('settings', 'settings/admin/encryption', $parameters, ''); } /** diff --git a/lib/private/Settings/Admin/Server.php b/lib/private/Settings/Admin/Server.php index 5443336669..994d927aff 100644 --- a/lib/private/Settings/Admin/Server.php +++ b/lib/private/Settings/Admin/Server.php @@ -137,7 +137,7 @@ class Server implements ISettings { 'cli_based_cron_user' => function_exists('posix_getpwuid') ? posix_getpwuid(fileowner(\OC::$configDir . 'config.php'))['name'] : '', ]; - return new TemplateResponse('settings', 'admin/server', $parameters, ''); + return new TemplateResponse('settings', 'settings/admin/server', $parameters, ''); } /** diff --git a/lib/private/Settings/Admin/ServerDevNotice.php b/lib/private/Settings/Admin/ServerDevNotice.php index 39897d5c61..017113fd9c 100644 --- a/lib/private/Settings/Admin/ServerDevNotice.php +++ b/lib/private/Settings/Admin/ServerDevNotice.php @@ -30,7 +30,7 @@ class ServerDevNotice implements ISettings { * @return TemplateResponse */ public function getForm() { - return new TemplateResponse('settings', 'admin/server.development.notice'); + return new TemplateResponse('settings', 'settings/admin/server.development.notice'); } /** diff --git a/lib/private/Settings/Admin/Sharing.php b/lib/private/Settings/Admin/Sharing.php index 8f57f77b20..997a4d6658 100644 --- a/lib/private/Settings/Admin/Sharing.php +++ b/lib/private/Settings/Admin/Sharing.php @@ -67,7 +67,7 @@ class Sharing implements ISettings { 'enableLinkPasswordByDefault' => $this->config->getAppValue('core', 'shareapi_enable_link_password_by_default', 'no'), ]; - return new TemplateResponse('settings', 'admin/sharing', $parameters, ''); + return new TemplateResponse('settings', 'settings/admin/sharing', $parameters, ''); } /** diff --git a/lib/private/Settings/Admin/TipsTricks.php b/lib/private/Settings/Admin/TipsTricks.php index fd0fd59584..0df690dbbe 100644 --- a/lib/private/Settings/Admin/TipsTricks.php +++ b/lib/private/Settings/Admin/TipsTricks.php @@ -48,7 +48,7 @@ class TipsTricks implements ISettings { 'databaseOverload' => $databaseOverload, ]; - return new TemplateResponse('settings', 'admin/tipstricks', $parameters, ''); + return new TemplateResponse('settings', 'settings/admin/tipstricks', $parameters, ''); } /** diff --git a/settings/templates/admin/additional-mail.php b/settings/templates/settings/admin/additional-mail.php similarity index 100% rename from settings/templates/admin/additional-mail.php rename to settings/templates/settings/admin/additional-mail.php diff --git a/settings/templates/admin/encryption.php b/settings/templates/settings/admin/encryption.php similarity index 100% rename from settings/templates/admin/encryption.php rename to settings/templates/settings/admin/encryption.php diff --git a/settings/templates/admin/server.development.notice.php b/settings/templates/settings/admin/server.development.notice.php similarity index 100% rename from settings/templates/admin/server.development.notice.php rename to settings/templates/settings/admin/server.development.notice.php diff --git a/settings/templates/admin/server.php b/settings/templates/settings/admin/server.php similarity index 100% rename from settings/templates/admin/server.php rename to settings/templates/settings/admin/server.php diff --git a/settings/templates/admin/sharing.php b/settings/templates/settings/admin/sharing.php similarity index 100% rename from settings/templates/admin/sharing.php rename to settings/templates/settings/admin/sharing.php diff --git a/settings/templates/admin/tipstricks.php b/settings/templates/settings/admin/tipstricks.php similarity index 100% rename from settings/templates/admin/tipstricks.php rename to settings/templates/settings/admin/tipstricks.php From 010a3c09f2c589f15dc885694fdb0f7febdb25d8 Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Thu, 29 Jun 2017 14:38:22 +0200 Subject: [PATCH 42/42] =?UTF-8?q?=E2=80=A6=20and=20their=20tests=20needed?= =?UTF-8?q?=20adjustments,=20too?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Arthur Schiwon --- tests/lib/Settings/Admin/AdditionalTest.php | 2 +- tests/lib/Settings/Admin/EncryptionTest.php | 4 ++-- tests/lib/Settings/Admin/ServerTest.php | 2 +- tests/lib/Settings/Admin/SharingTest.php | 4 ++-- tests/lib/Settings/Admin/TipsTricksTest.php | 4 ++-- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/lib/Settings/Admin/AdditionalTest.php b/tests/lib/Settings/Admin/AdditionalTest.php index 420a7110c1..84c63f3aeb 100644 --- a/tests/lib/Settings/Admin/AdditionalTest.php +++ b/tests/lib/Settings/Admin/AdditionalTest.php @@ -97,7 +97,7 @@ class AdditionalTest extends TestCase { $expected = new TemplateResponse( 'settings', - 'admin/additional-mail', + 'settings/admin/additional-mail', [ 'sendmail_is_available' => (bool) \OC_Helper::findBinaryPath('sendmail'), 'mail_domain' => 'mx.nextcloud.com', diff --git a/tests/lib/Settings/Admin/EncryptionTest.php b/tests/lib/Settings/Admin/EncryptionTest.php index a282b059c9..a5f483863e 100644 --- a/tests/lib/Settings/Admin/EncryptionTest.php +++ b/tests/lib/Settings/Admin/EncryptionTest.php @@ -81,7 +81,7 @@ class EncryptionTest extends TestCase { ->willReturn(['entry']); $expected = new TemplateResponse( 'settings', - 'admin/encryption', + 'settings/admin/encryption', [ 'encryptionEnabled' => $enabled, 'encryptionReady' => $enabled, @@ -116,7 +116,7 @@ class EncryptionTest extends TestCase { ->willReturn(['entry', 'entry']); $expected = new TemplateResponse( 'settings', - 'admin/encryption', + 'settings/admin/encryption', [ 'encryptionEnabled' => $enabled, 'encryptionReady' => $enabled, diff --git a/tests/lib/Settings/Admin/ServerTest.php b/tests/lib/Settings/Admin/ServerTest.php index f876ae8513..a71aef0178 100644 --- a/tests/lib/Settings/Admin/ServerTest.php +++ b/tests/lib/Settings/Admin/ServerTest.php @@ -123,7 +123,7 @@ class ServerTest extends TestCase { $envPath = getenv('PATH'); $expected = new TemplateResponse( 'settings', - 'admin/server', + 'settings/admin/server', [ // Diagnosis 'readOnlyConfigEnabled' => \OC_Helper::isReadOnlyConfigEnabled(), diff --git a/tests/lib/Settings/Admin/SharingTest.php b/tests/lib/Settings/Admin/SharingTest.php index 0bf0355968..d9aa14fece 100644 --- a/tests/lib/Settings/Admin/SharingTest.php +++ b/tests/lib/Settings/Admin/SharingTest.php @@ -112,7 +112,7 @@ class SharingTest extends TestCase { $expected = new TemplateResponse( 'settings', - 'admin/sharing', + 'settings/admin/sharing', [ 'allowGroupSharing' => 'yes', 'allowLinks' => 'yes', @@ -205,7 +205,7 @@ class SharingTest extends TestCase { $expected = new TemplateResponse( 'settings', - 'admin/sharing', + 'settings/admin/sharing', [ 'allowGroupSharing' => 'yes', 'allowLinks' => 'yes', diff --git a/tests/lib/Settings/Admin/TipsTricksTest.php b/tests/lib/Settings/Admin/TipsTricksTest.php index 0e8857b56d..cbecd51ed5 100644 --- a/tests/lib/Settings/Admin/TipsTricksTest.php +++ b/tests/lib/Settings/Admin/TipsTricksTest.php @@ -52,7 +52,7 @@ class TipsTrickTest extends TestCase { $expected = new TemplateResponse( 'settings', - 'admin/tipstricks', + 'settings/admin/tipstricks', [ 'databaseOverload' => true, ], @@ -71,7 +71,7 @@ class TipsTrickTest extends TestCase { $expected = new TemplateResponse( 'settings', - 'admin/tipstricks', + 'settings/admin/tipstricks', [ 'databaseOverload' => false, ],