|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435 |
- <?php
- /**
- * @copyright Copyright (c) 2016 Arthur Schiwon <blizzz@arthur-schiwon.de>
- *
- * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
- namespace OC\Settings;
-
- use OCP\AppFramework\QueryException;
- use OCP\Encryption\IManager as EncryptionManager;
- use OCP\IConfig;
- use OCP\IDBConnection;
- use OCP\IL10N;
- use OCP\ILogger;
- use OCP\IUserManager;
- use OCP\Lock\ILockingProvider;
- use OCP\Settings\ISettings;
- 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 */
- private $dbc;
- /** @var IL10N */
- private $l;
- /** @var IConfig */
- private $config;
- /** @var EncryptionManager */
- private $encryptionManager;
- /** @var IUserManager */
- private $userManager;
- /** @var ILockingProvider */
- private $lockingProvider;
-
- /**
- * @param ILogger $log
- * @param IDBConnection $dbc
- * @param IL10N $l
- * @param IConfig $config
- * @param EncryptionManager $encryptionManager
- * @param IUserManager $userManager
- * @param ILockingProvider $lockingProvider
- */
- public function __construct(
- ILogger $log,
- IDBConnection $dbc,
- IL10N $l,
- IConfig $config,
- EncryptionManager $encryptionManager,
- IUserManager $userManager,
- ILockingProvider $lockingProvider
- ) {
- $this->log = $log;
- $this->dbc = $dbc;
- $this->l = $l;
- $this->config = $config;
- $this->encryptionManager = $encryptionManager;
- $this->userManager = $userManager;
- $this->lockingProvider = $lockingProvider;
- }
-
- /**
- * @inheritdoc
- */
- public function setupSettings(array $settings) {
- if(isset($settings[IManager::KEY_ADMIN_SECTION])) {
- $this->setupAdminSection($settings[IManager::KEY_ADMIN_SECTION]);
- }
- if(isset($settings[IManager::KEY_ADMIN_SETTINGS])) {
- $this->setupAdminSettings($settings[IManager::KEY_ADMIN_SETTINGS]);
- }
- }
-
- /**
- * attempts to remove an apps section and/or settings entry. A listener is
- * added centrally making sure that this method is called ones an app was
- * disabled.
- *
- * @param string $appId
- * @since 9.1.0
- */
- public function onAppDisabled($appId) {
- $appInfo = \OC_App::getAppInfo($appId); // hello static legacy
-
- if(isset($appInfo['settings'][IManager::KEY_ADMIN_SECTION])) {
- $this->remove(self::TABLE_ADMIN_SECTIONS, trim($appInfo['settings'][IManager::KEY_ADMIN_SECTION], '\\'));
- }
- if(isset($appInfo['settings'][IManager::KEY_ADMIN_SETTINGS])) {
- $this->remove(self::TABLE_ADMIN_SETTINGS, trim($appInfo['settings'][IManager::KEY_ADMIN_SETTINGS], '\\'));
- }
- }
-
- public function checkForOrphanedClassNames() {
- $tables = [ self::TABLE_ADMIN_SECTIONS, self::TABLE_ADMIN_SETTINGS ];
- foreach ($tables as $table) {
- $classes = $this->getClasses($table);
- foreach($classes as $className) {
- try {
- \OC::$server->query($className);
- } catch (QueryException $e) {
- $this->remove($table, $className);
- }
- }
- }
- }
-
- /**
- * returns the registerd classes in the given table
- *
- * @param $table
- * @return string[]
- */
- private function getClasses($table) {
- $q = $this->dbc->getQueryBuilder();
- $resultStatement = $q->select('class')
- ->from($table)
- ->execute();
- $data = $resultStatement->fetchAll();
- $resultStatement->closeCursor();
-
- return array_map(function($row) { return $row['class']; }, $data);
- }
-
- /**
- * @param string $sectionClassName
- */
- private function setupAdminSection($sectionClassName) {
- if(!class_exists($sectionClassName)) {
- $this->log->debug('Could not find admin section class ' . $sectionClassName);
- return;
- }
- try {
- $section = $this->query($sectionClassName);
- } catch (QueryException $e) {
- // cancel
- return;
- }
-
- if(!$section instanceof ISection) {
- $this->log->error(
- 'Admin section instance must implement \OCP\ISection. Invalid class: {class}',
- ['class' => $sectionClassName]
- );
- return;
- }
- if(!$this->hasAdminSection(get_class($section))) {
- $this->addAdminSection($section);
- } else {
- $this->updateAdminSection($section);
- }
- }
-
- private function addAdminSection(ISection $section) {
- $this->add(self::TABLE_ADMIN_SECTIONS, [
- 'id' => $section->getID(),
- 'class' => get_class($section),
- 'priority' => $section->getPriority(),
- ]);
- }
-
- private function addAdminSettings(ISettings $settings) {
- $this->add(self::TABLE_ADMIN_SETTINGS, [
- 'class' => get_class($settings),
- 'section' => $settings->getSection(),
- 'priority' => $settings->getPriority(),
- ]);
- }
-
- /**
- * @param string $table
- * @param array $values
- */
- private function add($table, array $values) {
- $query = $this->dbc->getQueryBuilder();
- $values = array_map(function($value) use ($query) {
- return $query->createNamedParameter($value);
- }, $values);
- $query->insert($table)->values($values);
- $query->execute();
- }
-
- private function updateAdminSettings(ISettings $settings) {
- $this->update(
- self::TABLE_ADMIN_SETTINGS,
- 'class',
- get_class($settings),
- [
- 'section' => $settings->getSection(),
- 'priority' => $settings->getPriority(),
- ]
- );
- }
-
- private function updateAdminSection(ISection $section) {
- $this->update(
- self::TABLE_ADMIN_SECTIONS,
- 'class',
- get_class($section),
- [
- 'id' => $section->getID(),
- 'priority' => $section->getPriority(),
- ]
- );
- }
-
- private function update($table, $idCol, $id, $values) {
- $query = $this->dbc->getQueryBuilder();
- $query->update($table);
- foreach($values as $key => $value) {
- $query->set($key, $query->createNamedParameter($value));
- }
- $query
- ->where($query->expr()->eq($idCol, $query->createParameter($idCol)))
- ->setParameter($idCol, $id)
- ->execute();
- }
-
- /**
- * @param string $className
- * @return bool
- */
- private function hasAdminSection($className) {
- return $this->has(self::TABLE_ADMIN_SECTIONS, $className);
- }
-
- /**
- * @param string $className
- * @return bool
- */
- private function hasAdminSettings($className) {
- return $this->has(self::TABLE_ADMIN_SETTINGS, $className);
- }
-
- /**
- * @param string $table
- * @param string $className
- * @return bool
- */
- private function has($table, $className) {
- $query = $this->dbc->getQueryBuilder();
- $query->select('class')
- ->from($table)
- ->where($query->expr()->eq('class', $query->createNamedParameter($className)))
- ->setMaxResults(1);
-
- $result = $query->execute();
- $row = $result->fetch();
- $result->closeCursor();
-
- return (bool) $row;
- }
-
- /**
- * deletes an settings or admin entry from the given table
- *
- * @param $table
- * @param $className
- */
- private function remove($table, $className) {
- $query = $this->dbc->getQueryBuilder();
- $query->delete($table)
- ->where($query->expr()->eq('class', $query->createNamedParameter($className)));
-
- $query->execute();
- }
-
- private function setupAdminSettings($settingsClassName) {
- if(!class_exists($settingsClassName)) {
- $this->log->debug('Could not find admin section class ' . $settingsClassName);
- return;
- }
-
- try {
- /** @var ISettings $settings */
- $settings = $this->query($settingsClassName);
- } catch (QueryException $e) {
- // cancel
- return;
- }
-
- if(!$settings instanceof ISettings) {
- $this->log->error(
- 'Admin section instance must implement \OCP\Settings\ISection. Invalid class: {class}',
- ['class' => $settingsClassName]
- );
- return;
- }
- if(!$this->hasAdminSettings(get_class($settings))) {
- $this->addAdminSettings($settings);
- } else {
- $this->updateAdminSettings($settings);
- }
- }
-
- private function query($className) {
- try {
- return \OC::$server->query($className);
- } catch (QueryException $e) {
- $this->log->logException($e);
- throw $e;
- }
- }
-
- /**
- * @inheritdoc
- */
- public function getAdminSections() {
- // built-in sections
- $sections = [
- 0 => [new Section('server', $this->l->t('Server settings'), 0)],
- 5 => [new Section('sharing', $this->l->t('Sharing'), 0)],
- 45 => [new Section('encryption', $this->l->t('Encryption'), 0)],
- 90 => [new Section('logging', $this->l->t('Logging'), 0)],
- 98 => [new Section('additional', $this->l->t('Additional settings'), 0)],
- 99 => [new Section('tips-tricks', $this->l->t('Tips & tricks'), 0)],
- ];
-
- $query = $this->dbc->getQueryBuilder();
- $query->selectDistinct('s.class')
- ->addSelect('s.priority')
- ->from(self::TABLE_ADMIN_SECTIONS, 's')
- ->from(self::TABLE_ADMIN_SETTINGS, 'f')
- ->where($query->expr()->eq('s.id', 'f.section'))
- ;
- $result = $query->execute();
-
- while($row = $result->fetch()) {
- if(!isset($sections[$row['priority']])) {
- $sections[$row['priority']] = [];
- }
- try {
- $sections[$row['priority']][] = $this->query($row['class']);
- } catch (QueryException $e) {
- // skip
- }
- }
- $result->closeCursor();
-
- ksort($sections);
- return $sections;
- }
-
- private function getBuiltInAdminSettings($section) {
- $forms = [];
- try {
- if($section === 'server') {
- /** @var ISettings $form */
- $form = new Admin\Server($this->dbc, $this->config, $this->lockingProvider, $this->l);
- $forms[$form->getPriority()] = [$form];
- }
- if($section === 'encryption') {
- /** @var ISettings $form */
- $form = new Admin\Encryption($this->encryptionManager, $this->userManager);
- $forms[$form->getPriority()] = [$form];
- }
- if($section === 'sharing') {
- /** @var ISettings $form */
- $form = new Admin\Sharing($this->config);
- $forms[$form->getPriority()] = [$form];
- }
- if($section === 'logging') {
- /** @var ISettings $form */
- $form = new Admin\Logging($this->config);
- $forms[$form->getPriority()] = [$form];
- }
- if($section === 'additional') {
- /** @var ISettings $form */
- $form = new Admin\Additional($this->config);
- $forms[$form->getPriority()] = [$form];
- }
- if($section === 'tips-tricks') {
- /** @var ISettings $form */
- $form = new Admin\TipsTricks($this->config);
- $forms[$form->getPriority()] = [$form];
- }
- } catch (QueryException $e) {
- // skip
- }
- return $forms;
- }
-
- private function getAdminSettingsFromDB($section, &$settings) {
- $query = $this->dbc->getQueryBuilder();
- $query->select(['class', 'priority'])
- ->from(self::TABLE_ADMIN_SETTINGS)
- ->where($query->expr()->eq('section', $this->dbc->getQueryBuilder()->createParameter('section')))
- ->setParameter('section', $section);
-
- $result = $query->execute();
- while($row = $result->fetch()) {
- if(!isset($settings[$row['priority']])) {
- $settings[$row['priority']] = [];
- }
- try {
- $settings[$row['priority']][] = $this->query($row['class']);
- } catch (QueryException $e) {
- // skip
- }
- }
- $result->closeCursor();
-
- ksort($settings);
- }
-
- /**
- * @inheritdoc
- */
- public function getAdminSettings($section) {
- $settings = $this->getBuiltInAdminSettings($section);
- $this->getAdminSettingsFromDB($section, $settings);
- return $settings;
- }
- }
|