From d312051b3d9554519155c6c4f98b51f404a468e1 Mon Sep 17 00:00:00 2001 From: Roeland Jago Douma Date: Fri, 29 Apr 2016 08:00:31 +0200 Subject: Moved some files in \OC to PSR-4 * \OC\ActivityManager * \OC\AllConfig * \OC\AppConfig * \OC\AppHelper * \OC\Avatar * \OC\AvatarManager * \OC\CapabilitiesManager * \OC\Config * \OC\ContactsManager * \OC\DatabaseException * \OC\DatabaseSetupException --- lib/private/ActivityManager.php | 534 +++++++++++++++++++++++++++++++++ lib/private/AllConfig.php | 424 ++++++++++++++++++++++++++ lib/private/AppConfig.php | 287 ++++++++++++++++++ lib/private/AppHelper.php | 47 +++ lib/private/Avatar.php | 198 ++++++++++++ lib/private/AvatarManager.php | 97 ++++++ lib/private/CapabilitiesManager.php | 64 ++++ lib/private/Config.php | 264 ++++++++++++++++ lib/private/ContactsManager.php | 189 ++++++++++++ lib/private/DatabaseException.php | 37 +++ lib/private/DatabaseSetupException.php | 26 ++ lib/private/activitymanager.php | 534 --------------------------------- lib/private/allconfig.php | 424 -------------------------- lib/private/appconfig.php | 287 ------------------ lib/private/apphelper.php | 47 --- lib/private/avatar.php | 198 ------------ lib/private/avatarmanager.php | 97 ------ lib/private/capabilitiesmanager.php | 64 ---- lib/private/config.php | 264 ---------------- lib/private/contactsmanager.php | 189 ------------ lib/private/databaseexception.php | 37 --- lib/private/databasesetupexception.php | 26 -- 22 files changed, 2167 insertions(+), 2167 deletions(-) create mode 100644 lib/private/ActivityManager.php create mode 100644 lib/private/AllConfig.php create mode 100644 lib/private/AppConfig.php create mode 100644 lib/private/AppHelper.php create mode 100644 lib/private/Avatar.php create mode 100644 lib/private/AvatarManager.php create mode 100644 lib/private/CapabilitiesManager.php create mode 100644 lib/private/Config.php create mode 100644 lib/private/ContactsManager.php create mode 100644 lib/private/DatabaseException.php create mode 100644 lib/private/DatabaseSetupException.php delete mode 100644 lib/private/activitymanager.php delete mode 100644 lib/private/allconfig.php delete mode 100644 lib/private/appconfig.php delete mode 100644 lib/private/apphelper.php delete mode 100644 lib/private/avatar.php delete mode 100644 lib/private/avatarmanager.php delete mode 100644 lib/private/capabilitiesmanager.php delete mode 100644 lib/private/config.php delete mode 100644 lib/private/contactsmanager.php delete mode 100644 lib/private/databaseexception.php delete mode 100644 lib/private/databasesetupexception.php diff --git a/lib/private/ActivityManager.php b/lib/private/ActivityManager.php new file mode 100644 index 00000000000..e522dca9e3b --- /dev/null +++ b/lib/private/ActivityManager.php @@ -0,0 +1,534 @@ + + * @author Joas Schilling + * @author Thomas Müller + * + * @copyright Copyright (c) 2016, ownCloud, Inc. + * @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 + * + */ +namespace OC; + + +use OC\Activity\Event; +use OCP\Activity\IConsumer; +use OCP\Activity\IEvent; +use OCP\Activity\IExtension; +use OCP\Activity\IManager; +use OCP\IConfig; +use OCP\IRequest; +use OCP\IUser; +use OCP\IUserSession; + +class ActivityManager implements IManager { + /** @var IRequest */ + protected $request; + + /** @var IUserSession */ + protected $session; + + /** @var IConfig */ + protected $config; + + /** @var string */ + protected $formattingObjectType; + + /** @var int */ + protected $formattingObjectId; + + /** @var string */ + protected $currentUserId; + + /** + * constructor of the controller + * + * @param IRequest $request + * @param IUserSession $session + * @param IConfig $config + */ + public function __construct(IRequest $request, + IUserSession $session, + IConfig $config) { + $this->request = $request; + $this->session = $session; + $this->config = $config; + } + + /** @var \Closure[] */ + private $consumersClosures = array(); + + /** @var IConsumer[] */ + private $consumers = array(); + + /** @var \Closure[] */ + private $extensionsClosures = array(); + + /** @var IExtension[] */ + private $extensions = array(); + + /** @var array list of filters "name" => "is valid" */ + protected $validFilters = array( + 'all' => true, + 'by' => true, + 'self' => true, + ); + + /** @var array list of type icons "type" => "css class" */ + protected $typeIcons = array(); + + /** @var array list of special parameters "app" => ["text" => ["parameter" => "type"]] */ + protected $specialParameters = array(); + + /** + * @return \OCP\Activity\IConsumer[] + */ + protected function getConsumers() { + if (!empty($this->consumers)) { + return $this->consumers; + } + + $this->consumers = []; + foreach($this->consumersClosures as $consumer) { + $c = $consumer(); + if ($c instanceof IConsumer) { + $this->consumers[] = $c; + } else { + throw new \InvalidArgumentException('The given consumer does not implement the \OCP\Activity\IConsumer interface'); + } + } + + return $this->consumers; + } + + /** + * @return \OCP\Activity\IExtension[] + */ + protected function getExtensions() { + if (!empty($this->extensions)) { + return $this->extensions; + } + + $this->extensions = []; + foreach($this->extensionsClosures as $extension) { + $e = $extension(); + if ($e instanceof IExtension) { + $this->extensions[] = $e; + } else { + throw new \InvalidArgumentException('The given extension does not implement the \OCP\Activity\IExtension interface'); + } + } + + return $this->extensions; + } + + /** + * Generates a new IEvent object + * + * Make sure to call at least the following methods before sending it to the + * app with via the publish() method: + * - setApp() + * - setType() + * - setAffectedUser() + * - setSubject() + * + * @return IEvent + */ + public function generateEvent() { + return new Event(); + } + + /** + * Publish an event to the activity consumers + * + * Make sure to call at least the following methods before sending an Event: + * - setApp() + * - setType() + * - setAffectedUser() + * - setSubject() + * + * @param IEvent $event + * @return null + * @throws \BadMethodCallException if required values have not been set + */ + public function publish(IEvent $event) { + if (!$event->getApp()) { + throw new \BadMethodCallException('App not set', 10); + } + if (!$event->getType()) { + throw new \BadMethodCallException('Type not set', 11); + } + if ($event->getAffectedUser() === null) { + throw new \BadMethodCallException('Affected user not set', 12); + } + if ($event->getSubject() === null || $event->getSubjectParameters() === null) { + throw new \BadMethodCallException('Subject not set', 13); + } + + if ($event->getAuthor() === null) { + if ($this->session->getUser() instanceof IUser) { + $event->setAuthor($this->session->getUser()->getUID()); + } + } + + if (!$event->getTimestamp()) { + $event->setTimestamp(time()); + } + + foreach ($this->getConsumers() as $c) { + $c->receive($event); + } + } + + /** + * @param string $app The app where this event is associated with + * @param string $subject A short description of the event + * @param array $subjectParams Array with parameters that are filled in the subject + * @param string $message A longer description of the event + * @param array $messageParams Array with parameters that are filled in the message + * @param string $file The file including path where this event is associated with + * @param string $link A link where this event is associated with + * @param string $affectedUser Recipient of the activity + * @param string $type Type of the notification + * @param int $priority Priority of the notification + * @return null + */ + public function publishActivity($app, $subject, $subjectParams, $message, $messageParams, $file, $link, $affectedUser, $type, $priority) { + $event = $this->generateEvent(); + $event->setApp($app) + ->setType($type) + ->setAffectedUser($affectedUser) + ->setSubject($subject, $subjectParams) + ->setMessage($message, $messageParams) + ->setObject('', 0, $file) + ->setLink($link); + + $this->publish($event); + } + + /** + * In order to improve lazy loading a closure can be registered which will be called in case + * activity consumers are actually requested + * + * $callable has to return an instance of OCA\Activity\IConsumer + * + * @param \Closure $callable + */ + public function registerConsumer(\Closure $callable) { + array_push($this->consumersClosures, $callable); + $this->consumers = []; + } + + /** + * In order to improve lazy loading a closure can be registered which will be called in case + * activity consumers are actually requested + * + * $callable has to return an instance of OCA\Activity\IConsumer + * + * @param \Closure $callable + * @return void + */ + public function registerExtension(\Closure $callable) { + array_push($this->extensionsClosures, $callable); + $this->extensions = []; + } + + /** + * Will return additional notification types as specified by other apps + * + * @param string $languageCode + * @return array + */ + public function getNotificationTypes($languageCode) { + $filesNotificationTypes = []; + $sharingNotificationTypes = []; + + $notificationTypes = array(); + foreach ($this->getExtensions() as $c) { + $result = $c->getNotificationTypes($languageCode); + if (is_array($result)) { + if (class_exists('\OCA\Files\Activity', false) && $c instanceof \OCA\Files\Activity) { + $filesNotificationTypes = $result; + continue; + } + if (class_exists('\OCA\Files_Sharing\Activity', false) && $c instanceof \OCA\Files_Sharing\Activity) { + $sharingNotificationTypes = $result; + continue; + } + + $notificationTypes = array_merge($notificationTypes, $result); + } + } + + return array_merge($filesNotificationTypes, $sharingNotificationTypes, $notificationTypes); + } + + /** + * @param string $method + * @return array + */ + public function getDefaultTypes($method) { + $defaultTypes = array(); + foreach ($this->getExtensions() as $c) { + $types = $c->getDefaultTypes($method); + if (is_array($types)) { + $defaultTypes = array_merge($types, $defaultTypes); + } + } + return $defaultTypes; + } + + /** + * @param string $type + * @return string + */ + public function getTypeIcon($type) { + if (isset($this->typeIcons[$type])) { + return $this->typeIcons[$type]; + } + + foreach ($this->getExtensions() as $c) { + $icon = $c->getTypeIcon($type); + if (is_string($icon)) { + $this->typeIcons[$type] = $icon; + return $icon; + } + } + + $this->typeIcons[$type] = ''; + return ''; + } + + /** + * @param string $type + * @param string $id + */ + public function setFormattingObject($type, $id) { + $this->formattingObjectType = $type; + $this->formattingObjectId = (string) $id; + } + + /** + * @return bool + */ + public function isFormattingFilteredObject() { + return $this->formattingObjectType !== null && $this->formattingObjectId !== null + && $this->formattingObjectType === $this->request->getParam('object_type') + && $this->formattingObjectId === $this->request->getParam('object_id'); + } + + /** + * @param string $app + * @param string $text + * @param array $params + * @param boolean $stripPath + * @param boolean $highlightParams + * @param string $languageCode + * @return string|false + */ + public function translate($app, $text, $params, $stripPath, $highlightParams, $languageCode) { + foreach ($this->getExtensions() as $c) { + $translation = $c->translate($app, $text, $params, $stripPath, $highlightParams, $languageCode); + if (is_string($translation)) { + return $translation; + } + } + + return false; + } + + /** + * @param string $app + * @param string $text + * @return array|false + */ + public function getSpecialParameterList($app, $text) { + if (isset($this->specialParameters[$app][$text])) { + return $this->specialParameters[$app][$text]; + } + + if (!isset($this->specialParameters[$app])) { + $this->specialParameters[$app] = array(); + } + + foreach ($this->getExtensions() as $c) { + $specialParameter = $c->getSpecialParameterList($app, $text); + if (is_array($specialParameter)) { + $this->specialParameters[$app][$text] = $specialParameter; + return $specialParameter; + } + } + + $this->specialParameters[$app][$text] = false; + return false; + } + + /** + * @param array $activity + * @return integer|false + */ + public function getGroupParameter($activity) { + foreach ($this->getExtensions() as $c) { + $parameter = $c->getGroupParameter($activity); + if ($parameter !== false) { + return $parameter; + } + } + + return false; + } + + /** + * @return array + */ + public function getNavigation() { + $entries = array( + 'apps' => array(), + 'top' => array(), + ); + foreach ($this->getExtensions() as $c) { + $additionalEntries = $c->getNavigation(); + if (is_array($additionalEntries)) { + $entries['apps'] = array_merge($entries['apps'], $additionalEntries['apps']); + $entries['top'] = array_merge($entries['top'], $additionalEntries['top']); + } + } + + return $entries; + } + + /** + * @param string $filterValue + * @return boolean + */ + public function isFilterValid($filterValue) { + if (isset($this->validFilters[$filterValue])) { + return $this->validFilters[$filterValue]; + } + + foreach ($this->getExtensions() as $c) { + if ($c->isFilterValid($filterValue) === true) { + $this->validFilters[$filterValue] = true; + return true; + } + } + + $this->validFilters[$filterValue] = false; + return false; + } + + /** + * @param array $types + * @param string $filter + * @return array + */ + public function filterNotificationTypes($types, $filter) { + if (!$this->isFilterValid($filter)) { + return $types; + } + + foreach ($this->getExtensions() as $c) { + $result = $c->filterNotificationTypes($types, $filter); + if (is_array($result)) { + $types = $result; + } + } + return $types; + } + + /** + * @param string $filter + * @return array + */ + public function getQueryForFilter($filter) { + if (!$this->isFilterValid($filter)) { + return [null, null]; + } + + $conditions = array(); + $parameters = array(); + + foreach ($this->getExtensions() as $c) { + $result = $c->getQueryForFilter($filter); + if (is_array($result)) { + list($condition, $parameter) = $result; + if ($condition && is_array($parameter)) { + $conditions[] = $condition; + $parameters = array_merge($parameters, $parameter); + } + } + } + + if (empty($conditions)) { + return array(null, null); + } + + return array(' and ((' . implode(') or (', $conditions) . '))', $parameters); + } + + /** + * Set the user we need to use + * + * @param string|null $currentUserId + * @throws \UnexpectedValueException If the user is invalid + */ + public function setCurrentUserId($currentUserId) { + if (!is_string($currentUserId) && $currentUserId !== null) { + throw new \UnexpectedValueException('The given current user is invalid'); + } + $this->currentUserId = $currentUserId; + } + + /** + * Get the user we need to use + * + * Either the user is logged in, or we try to get it from the token + * + * @return string + * @throws \UnexpectedValueException If the token is invalid, does not exist or is not unique + */ + public function getCurrentUserId() { + if ($this->currentUserId !== null) { + return $this->currentUserId; + } else if (!$this->session->isLoggedIn()) { + return $this->getUserFromToken(); + } else { + return $this->session->getUser()->getUID(); + } + } + + /** + * Get the user for the token + * + * @return string + * @throws \UnexpectedValueException If the token is invalid, does not exist or is not unique + */ + protected function getUserFromToken() { + $token = (string) $this->request->getParam('token', ''); + if (strlen($token) !== 30) { + throw new \UnexpectedValueException('The token is invalid'); + } + + $users = $this->config->getUsersForUserValue('activity', 'rsstoken', $token); + + if (sizeof($users) !== 1) { + // No unique user found + throw new \UnexpectedValueException('The token is invalid'); + } + + // Token found login as that user + return array_shift($users); + } +} diff --git a/lib/private/AllConfig.php b/lib/private/AllConfig.php new file mode 100644 index 00000000000..b4888fde022 --- /dev/null +++ b/lib/private/AllConfig.php @@ -0,0 +1,424 @@ + + * @author Joas Schilling + * @author Lukas Reschke + * @author Morris Jobke + * @author Robin Appelman + * @author Robin McCorkell + * @author Thomas Müller + * @author Vincent Petry + * + * @copyright Copyright (c) 2016, ownCloud, Inc. + * @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 + * + */ + +namespace OC; +use OCP\IDBConnection; +use OCP\PreConditionNotMetException; + +/** + * Class to combine all the configuration options ownCloud offers + */ +class AllConfig implements \OCP\IConfig { + /** @var SystemConfig */ + private $systemConfig; + + /** @var IDBConnection */ + private $connection; + + /** + * 3 dimensional array with the following structure: + * [ $userId => + * [ $appId => + * [ $key => $value ] + * ] + * ] + * + * database table: preferences + * + * methods that use this: + * - setUserValue + * - getUserValue + * - getUserKeys + * - deleteUserValue + * - deleteAllUserValues + * - deleteAppFromAllUsers + * + * @var array $userCache + */ + private $userCache = array(); + + /** + * @param SystemConfig $systemConfig + */ + function __construct(SystemConfig $systemConfig) { + $this->systemConfig = $systemConfig; + } + + /** + * TODO - FIXME This fixes an issue with base.php that cause cyclic + * dependencies, especially with autoconfig setup + * + * Replace this by properly injected database connection. Currently the + * base.php triggers the getDatabaseConnection too early which causes in + * autoconfig setup case a too early distributed database connection and + * the autoconfig then needs to reinit all already initialized dependencies + * that use the database connection. + * + * otherwise a SQLite database is created in the wrong directory + * because the database connection was created with an uninitialized config + */ + private function fixDIInit() { + if($this->connection === null) { + $this->connection = \OC::$server->getDatabaseConnection(); + } + } + + /** + * Sets and deletes system wide values + * + * @param array $configs Associative array with `key => value` pairs + * If value is null, the config key will be deleted + */ + public function setSystemValues(array $configs) { + $this->systemConfig->setValues($configs); + } + + /** + * Sets a new system wide value + * + * @param string $key the key of the value, under which will be saved + * @param mixed $value the value that should be stored + */ + public function setSystemValue($key, $value) { + $this->systemConfig->setValue($key, $value); + } + + /** + * Looks up a system wide defined value + * + * @param string $key the key of the value, under which it was saved + * @param mixed $default the default value to be returned if the value isn't set + * @return mixed the value or $default + */ + public function getSystemValue($key, $default = '') { + return $this->systemConfig->getValue($key, $default); + } + + /** + * Looks up a system wide defined value and filters out sensitive data + * + * @param string $key the key of the value, under which it was saved + * @param mixed $default the default value to be returned if the value isn't set + * @return mixed the value or $default + */ + public function getFilteredSystemValue($key, $default = '') { + return $this->systemConfig->getFilteredValue($key, $default); + } + + /** + * Delete a system wide defined value + * + * @param string $key the key of the value, under which it was saved + */ + public function deleteSystemValue($key) { + $this->systemConfig->deleteValue($key); + } + + /** + * Get all keys stored for an app + * + * @param string $appName the appName that we stored the value under + * @return string[] the keys stored for the app + */ + public function getAppKeys($appName) { + return \OC::$server->getAppConfig()->getKeys($appName); + } + + /** + * Writes a new app wide value + * + * @param string $appName the appName that we want to store the value under + * @param string $key the key of the value, under which will be saved + * @param string $value the value that should be stored + */ + public function setAppValue($appName, $key, $value) { + \OC::$server->getAppConfig()->setValue($appName, $key, $value); + } + + /** + * Looks up an app wide defined value + * + * @param string $appName the appName that we stored the value under + * @param string $key the key of the value, under which it was saved + * @param string $default the default value to be returned if the value isn't set + * @return string the saved value + */ + public function getAppValue($appName, $key, $default = '') { + return \OC::$server->getAppConfig()->getValue($appName, $key, $default); + } + + /** + * Delete an app wide defined value + * + * @param string $appName the appName that we stored the value under + * @param string $key the key of the value, under which it was saved + */ + public function deleteAppValue($appName, $key) { + \OC::$server->getAppConfig()->deleteKey($appName, $key); + } + + /** + * Removes all keys in appconfig belonging to the app + * + * @param string $appName the appName the configs are stored under + */ + public function deleteAppValues($appName) { + \OC::$server->getAppConfig()->deleteApp($appName); + } + + + /** + * Set a user defined value + * + * @param string $userId the userId of the user that we want to store the value under + * @param string $appName the appName that we want to store the value under + * @param string $key the key under which the value is being stored + * @param string $value the value that you want to store + * @param string $preCondition only update if the config value was previously the value passed as $preCondition + * @throws \OCP\PreConditionNotMetException if a precondition is specified and is not met + */ + public function setUserValue($userId, $appName, $key, $value, $preCondition = null) { + // TODO - FIXME + $this->fixDIInit(); + + $preconditionArray = []; + if (isset($preCondition)) { + $preconditionArray = [ + 'configvalue' => $preCondition, + ]; + } + + $this->connection->setValues('preferences', [ + 'userid' => $userId, + 'appid' => $appName, + 'configkey' => $key, + ], [ + 'configvalue' => $value, + ], $preconditionArray); + + // only add to the cache if we already loaded data for the user + if (isset($this->userCache[$userId])) { + if (!isset($this->userCache[$userId][$appName])) { + $this->userCache[$userId][$appName] = array(); + } + $this->userCache[$userId][$appName][$key] = $value; + } + } + + /** + * Getting a user defined value + * + * @param string $userId the userId of the user that we want to store the value under + * @param string $appName the appName that we stored the value under + * @param string $key the key under which the value is being stored + * @param mixed $default the default value to be returned if the value isn't set + * @return string + */ + public function getUserValue($userId, $appName, $key, $default = '') { + $data = $this->getUserValues($userId); + if (isset($data[$appName]) and isset($data[$appName][$key])) { + return $data[$appName][$key]; + } else { + return $default; + } + } + + /** + * Get the keys of all stored by an app for the user + * + * @param string $userId the userId of the user that we want to store the value under + * @param string $appName the appName that we stored the value under + * @return string[] + */ + public function getUserKeys($userId, $appName) { + $data = $this->getUserValues($userId); + if (isset($data[$appName])) { + return array_keys($data[$appName]); + } else { + return array(); + } + } + + /** + * Delete a user value + * + * @param string $userId the userId of the user that we want to store the value under + * @param string $appName the appName that we stored the value under + * @param string $key the key under which the value is being stored + */ + public function deleteUserValue($userId, $appName, $key) { + // TODO - FIXME + $this->fixDIInit(); + + $sql = 'DELETE FROM `*PREFIX*preferences` '. + 'WHERE `userid` = ? AND `appid` = ? AND `configkey` = ?'; + $this->connection->executeUpdate($sql, array($userId, $appName, $key)); + + if (isset($this->userCache[$userId]) and isset($this->userCache[$userId][$appName])) { + unset($this->userCache[$userId][$appName][$key]); + } + } + + /** + * Delete all user values + * + * @param string $userId the userId of the user that we want to remove all values from + */ + public function deleteAllUserValues($userId) { + // TODO - FIXME + $this->fixDIInit(); + + $sql = 'DELETE FROM `*PREFIX*preferences` '. + 'WHERE `userid` = ?'; + $this->connection->executeUpdate($sql, array($userId)); + + unset($this->userCache[$userId]); + } + + /** + * Delete all user related values of one app + * + * @param string $appName the appName of the app that we want to remove all values from + */ + public function deleteAppFromAllUsers($appName) { + // TODO - FIXME + $this->fixDIInit(); + + $sql = 'DELETE FROM `*PREFIX*preferences` '. + 'WHERE `appid` = ?'; + $this->connection->executeUpdate($sql, array($appName)); + + foreach ($this->userCache as &$userCache) { + unset($userCache[$appName]); + } + } + + /** + * Returns all user configs sorted by app of one user + * + * @param string $userId the user ID to get the app configs from + * @return array[] - 2 dimensional array with the following structure: + * [ $appId => + * [ $key => $value ] + * ] + */ + private function getUserValues($userId) { + // TODO - FIXME + $this->fixDIInit(); + + if (isset($this->userCache[$userId])) { + return $this->userCache[$userId]; + } + $data = array(); + $query = 'SELECT `appid`, `configkey`, `configvalue` FROM `*PREFIX*preferences` WHERE `userid` = ?'; + $result = $this->connection->executeQuery($query, array($userId)); + while ($row = $result->fetch()) { + $appId = $row['appid']; + if (!isset($data[$appId])) { + $data[$appId] = array(); + } + $data[$appId][$row['configkey']] = $row['configvalue']; + } + $this->userCache[$userId] = $data; + return $data; + } + + /** + * Fetches a mapped list of userId -> value, for a specified app and key and a list of user IDs. + * + * @param string $appName app to get the value for + * @param string $key the key to get the value for + * @param array $userIds the user IDs to fetch the values for + * @return array Mapped values: userId => value + */ + public function getUserValueForUsers($appName, $key, $userIds) { + // TODO - FIXME + $this->fixDIInit(); + + if (empty($userIds) || !is_array($userIds)) { + return array(); + } + + $chunkedUsers = array_chunk($userIds, 50, true); + $placeholders50 = implode(',', array_fill(0, 50, '?')); + + $userValues = array(); + foreach ($chunkedUsers as $chunk) { + $queryParams = $chunk; + // create [$app, $key, $chunkedUsers] + array_unshift($queryParams, $key); + array_unshift($queryParams, $appName); + + $placeholders = (sizeof($chunk) == 50) ? $placeholders50 : implode(',', array_fill(0, sizeof($chunk), '?')); + + $query = 'SELECT `userid`, `configvalue` ' . + 'FROM `*PREFIX*preferences` ' . + 'WHERE `appid` = ? AND `configkey` = ? ' . + 'AND `userid` IN (' . $placeholders . ')'; + $result = $this->connection->executeQuery($query, $queryParams); + + while ($row = $result->fetch()) { + $userValues[$row['userid']] = $row['configvalue']; + } + } + + return $userValues; + } + + /** + * Determines the users that have the given value set for a specific app-key-pair + * + * @param string $appName the app to get the user for + * @param string $key the key to get the user for + * @param string $value the value to get the user for + * @return array of user IDs + */ + public function getUsersForUserValue($appName, $key, $value) { + // TODO - FIXME + $this->fixDIInit(); + + $sql = 'SELECT `userid` FROM `*PREFIX*preferences` ' . + 'WHERE `appid` = ? AND `configkey` = ? '; + + if($this->getSystemValue('dbtype', 'sqlite') === 'oci') { + //oracle hack: need to explicitly cast CLOB to CHAR for comparison + $sql .= 'AND to_char(`configvalue`) = ?'; + } else { + $sql .= 'AND `configvalue` = ?'; + } + + $result = $this->connection->executeQuery($sql, array($appName, $key, $value)); + + $userIDs = array(); + while ($row = $result->fetch()) { + $userIDs[] = $row['userid']; + } + + return $userIDs; + } +} diff --git a/lib/private/AppConfig.php b/lib/private/AppConfig.php new file mode 100644 index 00000000000..14c48299a8a --- /dev/null +++ b/lib/private/AppConfig.php @@ -0,0 +1,287 @@ + + * @author Bart Visscher + * @author Jakob Sack + * @author Joas Schilling + * @author Jörn Friedrich Dreyer + * @author Morris Jobke + * @author Robin Appelman + * @author Robin McCorkell + * + * @copyright Copyright (c) 2016, ownCloud, Inc. + * @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 + * + */ + +namespace OC; + +use OCP\IAppConfig; +use OCP\IDBConnection; + +/** + * This class provides an easy way for apps to store config values in the + * database. + */ +class AppConfig implements IAppConfig { + /** + * @var \OCP\IDBConnection $conn + */ + protected $conn; + + private $cache = array(); + + /** + * @param IDBConnection $conn + */ + public function __construct(IDBConnection $conn) { + $this->conn = $conn; + $this->configLoaded = false; + } + + /** + * @param string $app + * @return array + */ + private function getAppValues($app) { + $this->loadConfigValues(); + + if (isset($this->cache[$app])) { + return $this->cache[$app]; + } + + return []; + } + + /** + * Get all apps using the config + * + * @return array an array of app ids + * + * This function returns a list of all apps that have at least one + * entry in the appconfig table. + */ + public function getApps() { + $this->loadConfigValues(); + + return $this->getSortedKeys($this->cache); + } + + /** + * Get the available keys for an app + * + * @param string $app the app we are looking for + * @return array an array of key names + * + * This function gets all keys of an app. Please note that the values are + * not returned. + */ + public function getKeys($app) { + $this->loadConfigValues(); + + if (isset($this->cache[$app])) { + return $this->getSortedKeys($this->cache[$app]); + } + + return []; + } + + public function getSortedKeys($data) { + $keys = array_keys($data); + sort($keys); + return $keys; + } + + /** + * Gets the config value + * + * @param string $app app + * @param string $key key + * @param string $default = null, default value if the key does not exist + * @return string the value or $default + * + * This function gets a value from the appconfig table. If the key does + * not exist the default value will be returned + */ + public function getValue($app, $key, $default = null) { + $this->loadConfigValues(); + + if ($this->hasKey($app, $key)) { + return $this->cache[$app][$key]; + } + + return $default; + } + + /** + * check if a key is set in the appconfig + * + * @param string $app + * @param string $key + * @return bool + */ + public function hasKey($app, $key) { + $this->loadConfigValues(); + + return isset($this->cache[$app][$key]); + } + + /** + * Sets a value. If the key did not exist before it will be created. + * + * @param string $app app + * @param string $key key + * @param string $value value + * @return bool True if the value was inserted or updated, false if the value was the same + */ + public function setValue($app, $key, $value) { + if (!$this->hasKey($app, $key)) { + $inserted = (bool) $this->conn->insertIfNotExist('*PREFIX*appconfig', [ + 'appid' => $app, + 'configkey' => $key, + 'configvalue' => $value, + ], [ + 'appid', + 'configkey', + ]); + + if ($inserted) { + if (!isset($this->cache[$app])) { + $this->cache[$app] = []; + } + + $this->cache[$app][$key] = $value; + return true; + } + } + + $sql = $this->conn->getQueryBuilder(); + $sql->update('appconfig') + ->set('configvalue', $sql->createParameter('configvalue')) + ->where($sql->expr()->eq('appid', $sql->createParameter('app'))) + ->andWhere($sql->expr()->eq('configkey', $sql->createParameter('configkey'))) + ->setParameter('configvalue', $value) + ->setParameter('app', $app) + ->setParameter('configkey', $key); + + /* + * Only limit to the existing value for non-Oracle DBs: + * http://docs.oracle.com/cd/E11882_01/server.112/e26088/conditions002.htm#i1033286 + * > Large objects (LOBs) are not supported in comparison conditions. + */ + if (!($this->conn instanceof \OC\DB\OracleConnection)) { + // Only update the value when it is not the same + $sql->andWhere($sql->expr()->neq('configvalue', $sql->createParameter('configvalue'))) + ->setParameter('configvalue', $value); + } + + $changedRow = (bool) $sql->execute(); + + $this->cache[$app][$key] = $value; + + return $changedRow; + } + + /** + * Deletes a key + * + * @param string $app app + * @param string $key key + * @return boolean|null + */ + public function deleteKey($app, $key) { + $this->loadConfigValues(); + + $sql = $this->conn->getQueryBuilder(); + $sql->delete('appconfig') + ->where($sql->expr()->eq('appid', $sql->createParameter('app'))) + ->andWhere($sql->expr()->eq('configkey', $sql->createParameter('configkey'))) + ->setParameter('app', $app) + ->setParameter('configkey', $key); + $sql->execute(); + + unset($this->cache[$app][$key]); + } + + /** + * Remove app from appconfig + * + * @param string $app app + * @return boolean|null + * + * Removes all keys in appconfig belonging to the app. + */ + public function deleteApp($app) { + $this->loadConfigValues(); + + $sql = $this->conn->getQueryBuilder(); + $sql->delete('appconfig') + ->where($sql->expr()->eq('appid', $sql->createParameter('app'))) + ->setParameter('app', $app); + $sql->execute(); + + unset($this->cache[$app]); + } + + /** + * get multiple values, either the app or key can be used as wildcard by setting it to false + * + * @param string|false $app + * @param string|false $key + * @return array|false + */ + public function getValues($app, $key) { + if (($app !== false) === ($key !== false)) { + return false; + } + + if ($key === false) { + return $this->getAppValues($app); + } else { + $appIds = $this->getApps(); + $values = array_map(function($appId) use ($key) { + return isset($this->cache[$appId][$key]) ? $this->cache[$appId][$key] : null; + }, $appIds); + $result = array_combine($appIds, $values); + + return array_filter($result); + } + } + + /** + * Load all the app config values + */ + protected function loadConfigValues() { + if ($this->configLoaded) return; + + $this->cache = []; + + $sql = $this->conn->getQueryBuilder(); + $sql->select('*') + ->from('appconfig'); + $result = $sql->execute(); + + while ($row = $result->fetch()) { + if (!isset($this->cache[$row['appid']])) { + $this->cache[$row['appid']] = []; + } + + $this->cache[$row['appid']][$row['configkey']] = $row['configvalue']; + } + $result->closeCursor(); + + $this->configLoaded = true; + } +} diff --git a/lib/private/AppHelper.php b/lib/private/AppHelper.php new file mode 100644 index 00000000000..c19ed2f5b67 --- /dev/null +++ b/lib/private/AppHelper.php @@ -0,0 +1,47 @@ + + * @author Lukas Reschke + * @author Morris Jobke + * + * @copyright Copyright (c) 2016, ownCloud, Inc. + * @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 + * + */ + +namespace OC; + +/** + * Class AppHelper + * @deprecated 8.1.0 + */ +class AppHelper implements \OCP\IHelper { + /** + * Gets the content of an URL by using CURL or a fallback if it is not + * installed + * @param string $url the url that should be fetched + * @return string the content of the webpage + * @deprecated 8.1.0 Use \OCP\IServerContainer::getHTTPClientService + */ + public function getUrlContent($url) { + try { + $client = \OC::$server->getHTTPClientService()->newClient(); + $response = $client->get($url); + return $response->getBody(); + } catch (\Exception $e) { + return false; + } + } +} diff --git a/lib/private/Avatar.php b/lib/private/Avatar.php new file mode 100644 index 00000000000..3f8038360a4 --- /dev/null +++ b/lib/private/Avatar.php @@ -0,0 +1,198 @@ + + * @author Christopher Schäpers + * @author Lukas Reschke + * @author Morris Jobke + * @author Robin Appelman + * @author Roeland Jago Douma + * @author Thomas Müller + * + * @copyright Copyright (c) 2016, ownCloud, Inc. + * @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 + * + */ + +namespace OC; + +use OC\User\User; +use OCP\Files\Folder; +use OCP\Files\File; +use OCP\Files\NotFoundException; +use OCP\Files\NotPermittedException; +use OCP\IAvatar; +use OCP\IImage; +use OCP\IL10N; +use OC_Image; +use OCP\ILogger; + +/** + * This class gets and sets users avatars. + */ + +class Avatar implements IAvatar { + /** @var Folder */ + private $folder; + /** @var IL10N */ + private $l; + /** @var User */ + private $user; + /** @var ILogger */ + private $logger; + + /** + * constructor + * + * @param Folder $folder The folder where the avatars are + * @param IL10N $l + * @param User $user + * @param ILogger $logger + */ + public function __construct (Folder $folder, IL10N $l, $user, ILogger $logger) { + $this->folder = $folder; + $this->l = $l; + $this->user = $user; + $this->logger = $logger; + } + + /** + * @inheritdoc + */ + public function get ($size = 64) { + try { + $file = $this->getFile($size); + } catch (NotFoundException $e) { + return false; + } + + $avatar = new OC_Image(); + $avatar->loadFromData($file->getContent()); + return $avatar; + } + + /** + * Check if an avatar exists for the user + * + * @return bool + */ + public function exists() { + return $this->folder->nodeExists('avatar.jpg') || $this->folder->nodeExists('avatar.png'); + } + + /** + * sets the users avatar + * @param IImage|resource|string $data An image object, imagedata or path to set a new avatar + * @throws \Exception if the provided file is not a jpg or png image + * @throws \Exception if the provided image is not valid + * @throws NotSquareException if the image is not square + * @return void + */ + public function set ($data) { + + if($data instanceOf IImage) { + $img = $data; + $data = $img->data(); + } else { + $img = new OC_Image($data); + } + $type = substr($img->mimeType(), -3); + if ($type === 'peg') { + $type = 'jpg'; + } + if ($type !== 'jpg' && $type !== 'png') { + throw new \Exception($this->l->t("Unknown filetype")); + } + + if (!$img->valid()) { + throw new \Exception($this->l->t("Invalid image")); + } + + if (!($img->height() === $img->width())) { + throw new NotSquareException(); + } + + $this->remove(); + $this->folder->newFile('avatar.'.$type)->putContent($data); + $this->user->triggerChange('avatar'); + } + + /** + * remove the users avatar + * @return void + */ + public function remove () { + $regex = '/^avatar\.([0-9]+\.)?(jpg|png)$/'; + $avatars = $this->folder->getDirectoryListing(); + + foreach ($avatars as $avatar) { + if (preg_match($regex, $avatar->getName())) { + $avatar->delete(); + } + } + $this->user->triggerChange('avatar'); + } + + /** + * @inheritdoc + */ + public function getFile($size) { + $ext = $this->getExtension(); + + if ($size === -1) { + $path = 'avatar.' . $ext; + } else { + $path = 'avatar.' . $size . '.' . $ext; + } + + try { + $file = $this->folder->get($path); + } catch (NotFoundException $e) { + if ($size <= 0) { + throw new NotFoundException; + } + + $avatar = new OC_Image(); + /** @var File $file */ + $file = $this->folder->get('avatar.' . $ext); + $avatar->loadFromData($file->getContent()); + if ($size !== -1) { + $avatar->resize($size); + } + try { + $file = $this->folder->newFile($path); + $file->putContent($avatar->data()); + } catch (NotPermittedException $e) { + $this->logger->error('Failed to save avatar for ' . $this->user->getUID()); + } + } + + return $file; + } + + /** + * Get the extension of the avatar. If there is no avatar throw Exception + * + * @return string + * @throws NotFoundException + */ + private function getExtension() { + if ($this->folder->nodeExists('avatar.jpg')) { + return 'jpg'; + } elseif ($this->folder->nodeExists('avatar.png')) { + return 'png'; + } + throw new NotFoundException; + } +} diff --git a/lib/private/AvatarManager.php b/lib/private/AvatarManager.php new file mode 100644 index 00000000000..62f4faf436c --- /dev/null +++ b/lib/private/AvatarManager.php @@ -0,0 +1,97 @@ + + * @author Lukas Reschke + * @author Morris Jobke + * @author Roeland Jago Douma + * @author Thomas Müller + * + * @copyright Copyright (c) 2016, ownCloud, Inc. + * @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 + * + */ + +namespace OC; + +use OCP\Files\Folder; +use OCP\Files\NotFoundException; +use OCP\IAvatarManager; +use OCP\ILogger; +use OCP\IUserManager; +use OCP\Files\IRootFolder; +use OCP\IL10N; + +/** + * This class implements methods to access Avatar functionality + */ +class AvatarManager implements IAvatarManager { + + /** @var IUserManager */ + private $userManager; + + /** @var IRootFolder */ + private $rootFolder; + + /** @var IL10N */ + private $l; + + /** @var ILogger */ + private $logger; + + /** + * AvatarManager constructor. + * + * @param IUserManager $userManager + * @param IRootFolder $rootFolder + * @param IL10N $l + * @param ILogger $logger + */ + public function __construct( + IUserManager $userManager, + IRootFolder $rootFolder, + IL10N $l, + ILogger $logger) { + $this->userManager = $userManager; + $this->rootFolder = $rootFolder; + $this->l = $l; + $this->logger = $logger; + } + + /** + * return a user specific instance of \OCP\IAvatar + * @see \OCP\IAvatar + * @param string $userId the ownCloud user id + * @return \OCP\IAvatar + * @throws \Exception In case the username is potentially dangerous + * @throws NotFoundException In case there is no user folder yet + */ + public function getAvatar($userId) { + $user = $this->userManager->get($userId); + if (is_null($user)) { + throw new \Exception('user does not exist'); + } + + /* + * Fix for #22119 + * Basically we do not want to copy the skeleton folder + */ + \OC\Files\Filesystem::initMountPoints($userId); + $dir = '/' . $userId; + /** @var Folder $folder */ + $folder = $this->rootFolder->get($dir); + + return new Avatar($folder, $this->l, $user, $this->logger); + } +} diff --git a/lib/private/CapabilitiesManager.php b/lib/private/CapabilitiesManager.php new file mode 100644 index 00000000000..8b89692faa9 --- /dev/null +++ b/lib/private/CapabilitiesManager.php @@ -0,0 +1,64 @@ + + * + * @copyright Copyright (c) 2016, ownCloud, Inc. + * @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 + * + */ +namespace OC; + + +use OCP\Capabilities\ICapability; + +class CapabilitiesManager { + + /** + * @var \Closure[] + */ + private $capabilities = array(); + + /** + * Get an array of al the capabilities that are registered at this manager + * + * @throws \InvalidArgumentException + * @return array + */ + public function getCapabilities() { + $capabilities = []; + foreach($this->capabilities as $capability) { + $c = $capability(); + if ($c instanceof ICapability) { + $capabilities = array_replace_recursive($capabilities, $c->getCapabilities()); + } else { + throw new \InvalidArgumentException('The given Capability (' . get_class($c) . ') does not implement the ICapability interface'); + } + } + + return $capabilities; + } + + /** + * In order to improve lazy loading a closure can be registered which will be called in case + * capabilities are actually requested + * + * $callable has to return an instance of OCP\Capabilities\ICapability + * + * @param \Closure $callable + */ + public function registerCapability(\Closure $callable) { + array_push($this->capabilities, $callable); + } +} diff --git a/lib/private/Config.php b/lib/private/Config.php new file mode 100644 index 00000000000..9bb5c299463 --- /dev/null +++ b/lib/private/Config.php @@ -0,0 +1,264 @@ + + * @author Aldo "xoen" Giambelluca + * @author Bart Visscher + * @author Brice Maron + * @author Frank Karlitschek + * @author Jakob Sack + * @author Jan-Christoph Borchardt + * @author Joas Schilling + * @author Lukas Reschke + * @author Michael Gapczynski + * @author Morris Jobke + * @author Robin Appelman + * @author Robin McCorkell + * + * @copyright Copyright (c) 2016, ownCloud, Inc. + * @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 + * + */ + +namespace OC; + +/** + * This class is responsible for reading and writing config.php, the very basic + * configuration file of ownCloud. + */ +class Config { + /** @var array Associative array ($key => $value) */ + protected $cache = array(); + /** @var string */ + protected $configDir; + /** @var string */ + protected $configFilePath; + /** @var string */ + protected $configFileName; + + /** + * @param string $configDir Path to the config dir, needs to end with '/' + * @param string $fileName (Optional) Name of the config file. Defaults to config.php + */ + public function __construct($configDir, $fileName = 'config.php') { + $this->configDir = $configDir; + $this->configFilePath = $this->configDir.$fileName; + $this->configFileName = $fileName; + $this->readData(); + } + + /** + * Lists all available config keys + * + * Please note that it does not return the values. + * + * @return array an array of key names + */ + public function getKeys() { + return array_keys($this->cache); + } + + /** + * Gets a value from config.php + * + * If it does not exist, $default will be returned. + * + * @param string $key key + * @param mixed $default = null default value + * @return mixed the value or $default + */ + public function getValue($key, $default = null) { + if (isset($this->cache[$key])) { + return $this->cache[$key]; + } + + return $default; + } + + /** + * Sets and deletes values and writes the config.php + * + * @param array $configs Associative array with `key => value` pairs + * If value is null, the config key will be deleted + */ + public function setValues(array $configs) { + $needsUpdate = false; + foreach ($configs as $key => $value) { + if ($value !== null) { + $needsUpdate |= $this->set($key, $value); + } else { + $needsUpdate |= $this->delete($key); + } + } + + if ($needsUpdate) { + // Write changes + $this->writeData(); + } + } + + /** + * Sets the value and writes it to config.php if required + * + * @param string $key key + * @param mixed $value value + */ + public function setValue($key, $value) { + if ($this->set($key, $value)) { + // Write changes + $this->writeData(); + } + } + + /** + * This function sets the value + * + * @param string $key key + * @param mixed $value value + * @return bool True if the file needs to be updated, false otherwise + */ + protected function set($key, $value) { + if (!isset($this->cache[$key]) || $this->cache[$key] !== $value) { + // Add change + $this->cache[$key] = $value; + return true; + } + + return false; + } + + /** + * Removes a key from the config and removes it from config.php if required + * @param string $key + */ + public function deleteKey($key) { + if ($this->delete($key)) { + // Write changes + $this->writeData(); + } + } + + /** + * This function removes a key from the config + * + * @param string $key + * @return bool True if the file needs to be updated, false otherwise + */ + protected function delete($key) { + if (isset($this->cache[$key])) { + // Delete key from cache + unset($this->cache[$key]); + return true; + } + return false; + } + + /** + * Loads the config file + * + * Reads the config file and saves it to the cache + * + * @throws \Exception If no lock could be acquired or the config file has not been found + */ + private function readData() { + // Default config should always get loaded + $configFiles = array($this->configFilePath); + + // Add all files in the config dir ending with the same file name + $extra = glob($this->configDir.'*.'.$this->configFileName); + if (is_array($extra)) { + natsort($extra); + $configFiles = array_merge($configFiles, $extra); + } + + // Include file and merge config + foreach ($configFiles as $file) { + $filePointer = file_exists($file) ? fopen($file, 'r') : false; + if($file === $this->configFilePath && + $filePointer === false && + @!file_exists($this->configFilePath)) { + // Opening the main config might not be possible, e.g. if the wrong + // permissions are set (likely on a new installation) + continue; + } + + // Try to acquire a file lock + if(!flock($filePointer, LOCK_SH)) { + throw new \Exception(sprintf('Could not acquire a shared lock on the config file %s', $file)); + } + + unset($CONFIG); + include $file; + if(isset($CONFIG) && is_array($CONFIG)) { + $this->cache = array_merge($this->cache, $CONFIG); + } + + // Close the file pointer and release the lock + flock($filePointer, LOCK_UN); + fclose($filePointer); + } + } + + /** + * Writes the config file + * + * Saves the config to the config file. + * + * @throws HintException If the config file cannot be written to + * @throws \Exception If no file lock can be acquired + */ + private function writeData() { + // Create a php file ... + $content = "cache, true); + $content .= ";\n"; + + touch ($this->configFilePath); + $filePointer = fopen($this->configFilePath, 'r+'); + + // Prevent others not to read the config + chmod($this->configFilePath, 0640); + + // File does not exist, this can happen when doing a fresh install + if(!is_resource ($filePointer)) { + // TODO fix this via DI once it is very clear that this doesn't cause side effects due to initialization order + // currently this breaks app routes but also could have other side effects especially during setup and exception handling + $url = \OC::$server->getURLGenerator()->linkToDocs('admin-dir_permissions'); + throw new HintException( + "Can't write into config directory!", + 'This can usually be fixed by ' + .'giving the webserver write access to the config directory.'); + } + + // Try to acquire a file lock + if(!flock($filePointer, LOCK_EX)) { + throw new \Exception(sprintf('Could not acquire an exclusive lock on the config file %s', $this->configFilePath)); + } + + // Write the config and release the lock + ftruncate ($filePointer, 0); + fwrite($filePointer, $content); + fflush($filePointer); + flock($filePointer, LOCK_UN); + fclose($filePointer); + + // Try invalidating the opcache just for the file we wrote... + if (!\OC_Util::deleteFromOpcodeCache($this->configFilePath)) { + // But if that doesn't work, clear the whole cache. + \OC_Util::clearOpcodeCache(); + } + } +} + diff --git a/lib/private/ContactsManager.php b/lib/private/ContactsManager.php new file mode 100644 index 00000000000..a2640d36945 --- /dev/null +++ b/lib/private/ContactsManager.php @@ -0,0 +1,189 @@ + + * @author Joas Schilling + * @author Morris Jobke + * @author Robin McCorkell + * @author Thomas Müller + * @author Tobia De Koninck + * + * @copyright Copyright (c) 2016, ownCloud, Inc. + * @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 + * + */ + +namespace OC { + + class ContactsManager implements \OCP\Contacts\IManager { + + /** + * This function is used to search and find contacts within the users address books. + * In case $pattern is empty all contacts will be returned. + * + * @param string $pattern which should match within the $searchProperties + * @param array $searchProperties defines the properties within the query pattern should match + * @param array $options - for future use. One should always have options! + * @return array an array of contacts which are arrays of key-value-pairs + */ + public function search($pattern, $searchProperties = array(), $options = array()) { + $this->loadAddressBooks(); + $result = array(); + foreach($this->addressBooks as $addressBook) { + $r = $addressBook->search($pattern, $searchProperties, $options); + $contacts = array(); + foreach($r as $c){ + $c['addressbook-key'] = $addressBook->getKey(); + $contacts[] = $c; + } + $result = array_merge($result, $contacts); + } + + return $result; + } + + /** + * This function can be used to delete the contact identified by the given id + * + * @param object $id the unique identifier to a contact + * @param string $addressBookKey identifier of the address book in which the contact shall be deleted + * @return bool successful or not + */ + public function delete($id, $addressBookKey) { + $addressBook = $this->getAddressBook($addressBookKey); + if (!$addressBook) { + return null; + } + + if ($addressBook->getPermissions() & \OCP\Constants::PERMISSION_DELETE) { + return $addressBook->delete($id); + } + + return null; + } + + /** + * This function is used to create a new contact if 'id' is not given or not present. + * Otherwise the contact will be updated by replacing the entire data set. + * + * @param array $properties this array if key-value-pairs defines a contact + * @param string $addressBookKey identifier of the address book in which the contact shall be created or updated + * @return array representing the contact just created or updated + */ + public function createOrUpdate($properties, $addressBookKey) { + $addressBook = $this->getAddressBook($addressBookKey); + if (!$addressBook) { + return null; + } + + if ($addressBook->getPermissions() & \OCP\Constants::PERMISSION_CREATE) { + return $addressBook->createOrUpdate($properties); + } + + return null; + } + + /** + * Check if contacts are available (e.g. contacts app enabled) + * + * @return bool true if enabled, false if not + */ + public function isEnabled() { + return !empty($this->addressBooks) || !empty($this->addressBookLoaders); + } + + /** + * @param \OCP\IAddressBook $addressBook + */ + public function registerAddressBook(\OCP\IAddressBook $addressBook) { + $this->addressBooks[$addressBook->getKey()] = $addressBook; + } + + /** + * @param \OCP\IAddressBook $addressBook + */ + public function unregisterAddressBook(\OCP\IAddressBook $addressBook) { + unset($this->addressBooks[$addressBook->getKey()]); + } + + /** + * @return array + */ + public function getAddressBooks() { + $this->loadAddressBooks(); + $result = array(); + foreach($this->addressBooks as $addressBook) { + $result[$addressBook->getKey()] = $addressBook->getDisplayName(); + } + + return $result; + } + + /** + * removes all registered address book instances + */ + public function clear() { + $this->addressBooks = array(); + $this->addressBookLoaders = array(); + } + + /** + * @var \OCP\IAddressBook[] which holds all registered address books + */ + private $addressBooks = array(); + + /** + * @var \Closure[] to call to load/register address books + */ + private $addressBookLoaders = array(); + + /** + * In order to improve lazy loading a closure can be registered which will be called in case + * address books are actually requested + * + * @param \Closure $callable + */ + public function register(\Closure $callable) + { + $this->addressBookLoaders[] = $callable; + } + + /** + * Get (and load when needed) the address book for $key + * + * @param string $addressBookKey + * @return \OCP\IAddressBook + */ + protected function getAddressBook($addressBookKey) + { + $this->loadAddressBooks(); + if (!array_key_exists($addressBookKey, $this->addressBooks)) { + return null; + } + + return $this->addressBooks[$addressBookKey]; + } + + /** + * Load all address books registered with 'register' + */ + protected function loadAddressBooks() + { + foreach($this->addressBookLoaders as $callable) { + $callable($this); + } + $this->addressBookLoaders = array(); + } + } +} diff --git a/lib/private/DatabaseException.php b/lib/private/DatabaseException.php new file mode 100644 index 00000000000..4d50fe82b0f --- /dev/null +++ b/lib/private/DatabaseException.php @@ -0,0 +1,37 @@ + + * @author Morris Jobke + * + * @copyright Copyright (c) 2016, ownCloud, Inc. + * @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 + * + */ + +namespace OC; + +class DatabaseException extends \Exception { + private $query; + + //FIXME getQuery seems to be unused, maybe use parent constructor with $message, $code and $previous + public function __construct($message, $query = null){ + parent::__construct($message); + $this->query = $query; + } + + public function getQuery() { + return $this->query; + } +} diff --git a/lib/private/DatabaseSetupException.php b/lib/private/DatabaseSetupException.php new file mode 100644 index 00000000000..30bd00de2d6 --- /dev/null +++ b/lib/private/DatabaseSetupException.php @@ -0,0 +1,26 @@ + + * @author Morris Jobke + * + * @copyright Copyright (c) 2016, ownCloud, Inc. + * @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 + * + */ + +namespace OC; + +class DatabaseSetupException extends HintException { +} diff --git a/lib/private/activitymanager.php b/lib/private/activitymanager.php deleted file mode 100644 index e522dca9e3b..00000000000 --- a/lib/private/activitymanager.php +++ /dev/null @@ -1,534 +0,0 @@ - - * @author Joas Schilling - * @author Thomas Müller - * - * @copyright Copyright (c) 2016, ownCloud, Inc. - * @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 - * - */ -namespace OC; - - -use OC\Activity\Event; -use OCP\Activity\IConsumer; -use OCP\Activity\IEvent; -use OCP\Activity\IExtension; -use OCP\Activity\IManager; -use OCP\IConfig; -use OCP\IRequest; -use OCP\IUser; -use OCP\IUserSession; - -class ActivityManager implements IManager { - /** @var IRequest */ - protected $request; - - /** @var IUserSession */ - protected $session; - - /** @var IConfig */ - protected $config; - - /** @var string */ - protected $formattingObjectType; - - /** @var int */ - protected $formattingObjectId; - - /** @var string */ - protected $currentUserId; - - /** - * constructor of the controller - * - * @param IRequest $request - * @param IUserSession $session - * @param IConfig $config - */ - public function __construct(IRequest $request, - IUserSession $session, - IConfig $config) { - $this->request = $request; - $this->session = $session; - $this->config = $config; - } - - /** @var \Closure[] */ - private $consumersClosures = array(); - - /** @var IConsumer[] */ - private $consumers = array(); - - /** @var \Closure[] */ - private $extensionsClosures = array(); - - /** @var IExtension[] */ - private $extensions = array(); - - /** @var array list of filters "name" => "is valid" */ - protected $validFilters = array( - 'all' => true, - 'by' => true, - 'self' => true, - ); - - /** @var array list of type icons "type" => "css class" */ - protected $typeIcons = array(); - - /** @var array list of special parameters "app" => ["text" => ["parameter" => "type"]] */ - protected $specialParameters = array(); - - /** - * @return \OCP\Activity\IConsumer[] - */ - protected function getConsumers() { - if (!empty($this->consumers)) { - return $this->consumers; - } - - $this->consumers = []; - foreach($this->consumersClosures as $consumer) { - $c = $consumer(); - if ($c instanceof IConsumer) { - $this->consumers[] = $c; - } else { - throw new \InvalidArgumentException('The given consumer does not implement the \OCP\Activity\IConsumer interface'); - } - } - - return $this->consumers; - } - - /** - * @return \OCP\Activity\IExtension[] - */ - protected function getExtensions() { - if (!empty($this->extensions)) { - return $this->extensions; - } - - $this->extensions = []; - foreach($this->extensionsClosures as $extension) { - $e = $extension(); - if ($e instanceof IExtension) { - $this->extensions[] = $e; - } else { - throw new \InvalidArgumentException('The given extension does not implement the \OCP\Activity\IExtension interface'); - } - } - - return $this->extensions; - } - - /** - * Generates a new IEvent object - * - * Make sure to call at least the following methods before sending it to the - * app with via the publish() method: - * - setApp() - * - setType() - * - setAffectedUser() - * - setSubject() - * - * @return IEvent - */ - public function generateEvent() { - return new Event(); - } - - /** - * Publish an event to the activity consumers - * - * Make sure to call at least the following methods before sending an Event: - * - setApp() - * - setType() - * - setAffectedUser() - * - setSubject() - * - * @param IEvent $event - * @return null - * @throws \BadMethodCallException if required values have not been set - */ - public function publish(IEvent $event) { - if (!$event->getApp()) { - throw new \BadMethodCallException('App not set', 10); - } - if (!$event->getType()) { - throw new \BadMethodCallException('Type not set', 11); - } - if ($event->getAffectedUser() === null) { - throw new \BadMethodCallException('Affected user not set', 12); - } - if ($event->getSubject() === null || $event->getSubjectParameters() === null) { - throw new \BadMethodCallException('Subject not set', 13); - } - - if ($event->getAuthor() === null) { - if ($this->session->getUser() instanceof IUser) { - $event->setAuthor($this->session->getUser()->getUID()); - } - } - - if (!$event->getTimestamp()) { - $event->setTimestamp(time()); - } - - foreach ($this->getConsumers() as $c) { - $c->receive($event); - } - } - - /** - * @param string $app The app where this event is associated with - * @param string $subject A short description of the event - * @param array $subjectParams Array with parameters that are filled in the subject - * @param string $message A longer description of the event - * @param array $messageParams Array with parameters that are filled in the message - * @param string $file The file including path where this event is associated with - * @param string $link A link where this event is associated with - * @param string $affectedUser Recipient of the activity - * @param string $type Type of the notification - * @param int $priority Priority of the notification - * @return null - */ - public function publishActivity($app, $subject, $subjectParams, $message, $messageParams, $file, $link, $affectedUser, $type, $priority) { - $event = $this->generateEvent(); - $event->setApp($app) - ->setType($type) - ->setAffectedUser($affectedUser) - ->setSubject($subject, $subjectParams) - ->setMessage($message, $messageParams) - ->setObject('', 0, $file) - ->setLink($link); - - $this->publish($event); - } - - /** - * In order to improve lazy loading a closure can be registered which will be called in case - * activity consumers are actually requested - * - * $callable has to return an instance of OCA\Activity\IConsumer - * - * @param \Closure $callable - */ - public function registerConsumer(\Closure $callable) { - array_push($this->consumersClosures, $callable); - $this->consumers = []; - } - - /** - * In order to improve lazy loading a closure can be registered which will be called in case - * activity consumers are actually requested - * - * $callable has to return an instance of OCA\Activity\IConsumer - * - * @param \Closure $callable - * @return void - */ - public function registerExtension(\Closure $callable) { - array_push($this->extensionsClosures, $callable); - $this->extensions = []; - } - - /** - * Will return additional notification types as specified by other apps - * - * @param string $languageCode - * @return array - */ - public function getNotificationTypes($languageCode) { - $filesNotificationTypes = []; - $sharingNotificationTypes = []; - - $notificationTypes = array(); - foreach ($this->getExtensions() as $c) { - $result = $c->getNotificationTypes($languageCode); - if (is_array($result)) { - if (class_exists('\OCA\Files\Activity', false) && $c instanceof \OCA\Files\Activity) { - $filesNotificationTypes = $result; - continue; - } - if (class_exists('\OCA\Files_Sharing\Activity', false) && $c instanceof \OCA\Files_Sharing\Activity) { - $sharingNotificationTypes = $result; - continue; - } - - $notificationTypes = array_merge($notificationTypes, $result); - } - } - - return array_merge($filesNotificationTypes, $sharingNotificationTypes, $notificationTypes); - } - - /** - * @param string $method - * @return array - */ - public function getDefaultTypes($method) { - $defaultTypes = array(); - foreach ($this->getExtensions() as $c) { - $types = $c->getDefaultTypes($method); - if (is_array($types)) { - $defaultTypes = array_merge($types, $defaultTypes); - } - } - return $defaultTypes; - } - - /** - * @param string $type - * @return string - */ - public function getTypeIcon($type) { - if (isset($this->typeIcons[$type])) { - return $this->typeIcons[$type]; - } - - foreach ($this->getExtensions() as $c) { - $icon = $c->getTypeIcon($type); - if (is_string($icon)) { - $this->typeIcons[$type] = $icon; - return $icon; - } - } - - $this->typeIcons[$type] = ''; - return ''; - } - - /** - * @param string $type - * @param string $id - */ - public function setFormattingObject($type, $id) { - $this->formattingObjectType = $type; - $this->formattingObjectId = (string) $id; - } - - /** - * @return bool - */ - public function isFormattingFilteredObject() { - return $this->formattingObjectType !== null && $this->formattingObjectId !== null - && $this->formattingObjectType === $this->request->getParam('object_type') - && $this->formattingObjectId === $this->request->getParam('object_id'); - } - - /** - * @param string $app - * @param string $text - * @param array $params - * @param boolean $stripPath - * @param boolean $highlightParams - * @param string $languageCode - * @return string|false - */ - public function translate($app, $text, $params, $stripPath, $highlightParams, $languageCode) { - foreach ($this->getExtensions() as $c) { - $translation = $c->translate($app, $text, $params, $stripPath, $highlightParams, $languageCode); - if (is_string($translation)) { - return $translation; - } - } - - return false; - } - - /** - * @param string $app - * @param string $text - * @return array|false - */ - public function getSpecialParameterList($app, $text) { - if (isset($this->specialParameters[$app][$text])) { - return $this->specialParameters[$app][$text]; - } - - if (!isset($this->specialParameters[$app])) { - $this->specialParameters[$app] = array(); - } - - foreach ($this->getExtensions() as $c) { - $specialParameter = $c->getSpecialParameterList($app, $text); - if (is_array($specialParameter)) { - $this->specialParameters[$app][$text] = $specialParameter; - return $specialParameter; - } - } - - $this->specialParameters[$app][$text] = false; - return false; - } - - /** - * @param array $activity - * @return integer|false - */ - public function getGroupParameter($activity) { - foreach ($this->getExtensions() as $c) { - $parameter = $c->getGroupParameter($activity); - if ($parameter !== false) { - return $parameter; - } - } - - return false; - } - - /** - * @return array - */ - public function getNavigation() { - $entries = array( - 'apps' => array(), - 'top' => array(), - ); - foreach ($this->getExtensions() as $c) { - $additionalEntries = $c->getNavigation(); - if (is_array($additionalEntries)) { - $entries['apps'] = array_merge($entries['apps'], $additionalEntries['apps']); - $entries['top'] = array_merge($entries['top'], $additionalEntries['top']); - } - } - - return $entries; - } - - /** - * @param string $filterValue - * @return boolean - */ - public function isFilterValid($filterValue) { - if (isset($this->validFilters[$filterValue])) { - return $this->validFilters[$filterValue]; - } - - foreach ($this->getExtensions() as $c) { - if ($c->isFilterValid($filterValue) === true) { - $this->validFilters[$filterValue] = true; - return true; - } - } - - $this->validFilters[$filterValue] = false; - return false; - } - - /** - * @param array $types - * @param string $filter - * @return array - */ - public function filterNotificationTypes($types, $filter) { - if (!$this->isFilterValid($filter)) { - return $types; - } - - foreach ($this->getExtensions() as $c) { - $result = $c->filterNotificationTypes($types, $filter); - if (is_array($result)) { - $types = $result; - } - } - return $types; - } - - /** - * @param string $filter - * @return array - */ - public function getQueryForFilter($filter) { - if (!$this->isFilterValid($filter)) { - return [null, null]; - } - - $conditions = array(); - $parameters = array(); - - foreach ($this->getExtensions() as $c) { - $result = $c->getQueryForFilter($filter); - if (is_array($result)) { - list($condition, $parameter) = $result; - if ($condition && is_array($parameter)) { - $conditions[] = $condition; - $parameters = array_merge($parameters, $parameter); - } - } - } - - if (empty($conditions)) { - return array(null, null); - } - - return array(' and ((' . implode(') or (', $conditions) . '))', $parameters); - } - - /** - * Set the user we need to use - * - * @param string|null $currentUserId - * @throws \UnexpectedValueException If the user is invalid - */ - public function setCurrentUserId($currentUserId) { - if (!is_string($currentUserId) && $currentUserId !== null) { - throw new \UnexpectedValueException('The given current user is invalid'); - } - $this->currentUserId = $currentUserId; - } - - /** - * Get the user we need to use - * - * Either the user is logged in, or we try to get it from the token - * - * @return string - * @throws \UnexpectedValueException If the token is invalid, does not exist or is not unique - */ - public function getCurrentUserId() { - if ($this->currentUserId !== null) { - return $this->currentUserId; - } else if (!$this->session->isLoggedIn()) { - return $this->getUserFromToken(); - } else { - return $this->session->getUser()->getUID(); - } - } - - /** - * Get the user for the token - * - * @return string - * @throws \UnexpectedValueException If the token is invalid, does not exist or is not unique - */ - protected function getUserFromToken() { - $token = (string) $this->request->getParam('token', ''); - if (strlen($token) !== 30) { - throw new \UnexpectedValueException('The token is invalid'); - } - - $users = $this->config->getUsersForUserValue('activity', 'rsstoken', $token); - - if (sizeof($users) !== 1) { - // No unique user found - throw new \UnexpectedValueException('The token is invalid'); - } - - // Token found login as that user - return array_shift($users); - } -} diff --git a/lib/private/allconfig.php b/lib/private/allconfig.php deleted file mode 100644 index b4888fde022..00000000000 --- a/lib/private/allconfig.php +++ /dev/null @@ -1,424 +0,0 @@ - - * @author Joas Schilling - * @author Lukas Reschke - * @author Morris Jobke - * @author Robin Appelman - * @author Robin McCorkell - * @author Thomas Müller - * @author Vincent Petry - * - * @copyright Copyright (c) 2016, ownCloud, Inc. - * @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 - * - */ - -namespace OC; -use OCP\IDBConnection; -use OCP\PreConditionNotMetException; - -/** - * Class to combine all the configuration options ownCloud offers - */ -class AllConfig implements \OCP\IConfig { - /** @var SystemConfig */ - private $systemConfig; - - /** @var IDBConnection */ - private $connection; - - /** - * 3 dimensional array with the following structure: - * [ $userId => - * [ $appId => - * [ $key => $value ] - * ] - * ] - * - * database table: preferences - * - * methods that use this: - * - setUserValue - * - getUserValue - * - getUserKeys - * - deleteUserValue - * - deleteAllUserValues - * - deleteAppFromAllUsers - * - * @var array $userCache - */ - private $userCache = array(); - - /** - * @param SystemConfig $systemConfig - */ - function __construct(SystemConfig $systemConfig) { - $this->systemConfig = $systemConfig; - } - - /** - * TODO - FIXME This fixes an issue with base.php that cause cyclic - * dependencies, especially with autoconfig setup - * - * Replace this by properly injected database connection. Currently the - * base.php triggers the getDatabaseConnection too early which causes in - * autoconfig setup case a too early distributed database connection and - * the autoconfig then needs to reinit all already initialized dependencies - * that use the database connection. - * - * otherwise a SQLite database is created in the wrong directory - * because the database connection was created with an uninitialized config - */ - private function fixDIInit() { - if($this->connection === null) { - $this->connection = \OC::$server->getDatabaseConnection(); - } - } - - /** - * Sets and deletes system wide values - * - * @param array $configs Associative array with `key => value` pairs - * If value is null, the config key will be deleted - */ - public function setSystemValues(array $configs) { - $this->systemConfig->setValues($configs); - } - - /** - * Sets a new system wide value - * - * @param string $key the key of the value, under which will be saved - * @param mixed $value the value that should be stored - */ - public function setSystemValue($key, $value) { - $this->systemConfig->setValue($key, $value); - } - - /** - * Looks up a system wide defined value - * - * @param string $key the key of the value, under which it was saved - * @param mixed $default the default value to be returned if the value isn't set - * @return mixed the value or $default - */ - public function getSystemValue($key, $default = '') { - return $this->systemConfig->getValue($key, $default); - } - - /** - * Looks up a system wide defined value and filters out sensitive data - * - * @param string $key the key of the value, under which it was saved - * @param mixed $default the default value to be returned if the value isn't set - * @return mixed the value or $default - */ - public function getFilteredSystemValue($key, $default = '') { - return $this->systemConfig->getFilteredValue($key, $default); - } - - /** - * Delete a system wide defined value - * - * @param string $key the key of the value, under which it was saved - */ - public function deleteSystemValue($key) { - $this->systemConfig->deleteValue($key); - } - - /** - * Get all keys stored for an app - * - * @param string $appName the appName that we stored the value under - * @return string[] the keys stored for the app - */ - public function getAppKeys($appName) { - return \OC::$server->getAppConfig()->getKeys($appName); - } - - /** - * Writes a new app wide value - * - * @param string $appName the appName that we want to store the value under - * @param string $key the key of the value, under which will be saved - * @param string $value the value that should be stored - */ - public function setAppValue($appName, $key, $value) { - \OC::$server->getAppConfig()->setValue($appName, $key, $value); - } - - /** - * Looks up an app wide defined value - * - * @param string $appName the appName that we stored the value under - * @param string $key the key of the value, under which it was saved - * @param string $default the default value to be returned if the value isn't set - * @return string the saved value - */ - public function getAppValue($appName, $key, $default = '') { - return \OC::$server->getAppConfig()->getValue($appName, $key, $default); - } - - /** - * Delete an app wide defined value - * - * @param string $appName the appName that we stored the value under - * @param string $key the key of the value, under which it was saved - */ - public function deleteAppValue($appName, $key) { - \OC::$server->getAppConfig()->deleteKey($appName, $key); - } - - /** - * Removes all keys in appconfig belonging to the app - * - * @param string $appName the appName the configs are stored under - */ - public function deleteAppValues($appName) { - \OC::$server->getAppConfig()->deleteApp($appName); - } - - - /** - * Set a user defined value - * - * @param string $userId the userId of the user that we want to store the value under - * @param string $appName the appName that we want to store the value under - * @param string $key the key under which the value is being stored - * @param string $value the value that you want to store - * @param string $preCondition only update if the config value was previously the value passed as $preCondition - * @throws \OCP\PreConditionNotMetException if a precondition is specified and is not met - */ - public function setUserValue($userId, $appName, $key, $value, $preCondition = null) { - // TODO - FIXME - $this->fixDIInit(); - - $preconditionArray = []; - if (isset($preCondition)) { - $preconditionArray = [ - 'configvalue' => $preCondition, - ]; - } - - $this->connection->setValues('preferences', [ - 'userid' => $userId, - 'appid' => $appName, - 'configkey' => $key, - ], [ - 'configvalue' => $value, - ], $preconditionArray); - - // only add to the cache if we already loaded data for the user - if (isset($this->userCache[$userId])) { - if (!isset($this->userCache[$userId][$appName])) { - $this->userCache[$userId][$appName] = array(); - } - $this->userCache[$userId][$appName][$key] = $value; - } - } - - /** - * Getting a user defined value - * - * @param string $userId the userId of the user that we want to store the value under - * @param string $appName the appName that we stored the value under - * @param string $key the key under which the value is being stored - * @param mixed $default the default value to be returned if the value isn't set - * @return string - */ - public function getUserValue($userId, $appName, $key, $default = '') { - $data = $this->getUserValues($userId); - if (isset($data[$appName]) and isset($data[$appName][$key])) { - return $data[$appName][$key]; - } else { - return $default; - } - } - - /** - * Get the keys of all stored by an app for the user - * - * @param string $userId the userId of the user that we want to store the value under - * @param string $appName the appName that we stored the value under - * @return string[] - */ - public function getUserKeys($userId, $appName) { - $data = $this->getUserValues($userId); - if (isset($data[$appName])) { - return array_keys($data[$appName]); - } else { - return array(); - } - } - - /** - * Delete a user value - * - * @param string $userId the userId of the user that we want to store the value under - * @param string $appName the appName that we stored the value under - * @param string $key the key under which the value is being stored - */ - public function deleteUserValue($userId, $appName, $key) { - // TODO - FIXME - $this->fixDIInit(); - - $sql = 'DELETE FROM `*PREFIX*preferences` '. - 'WHERE `userid` = ? AND `appid` = ? AND `configkey` = ?'; - $this->connection->executeUpdate($sql, array($userId, $appName, $key)); - - if (isset($this->userCache[$userId]) and isset($this->userCache[$userId][$appName])) { - unset($this->userCache[$userId][$appName][$key]); - } - } - - /** - * Delete all user values - * - * @param string $userId the userId of the user that we want to remove all values from - */ - public function deleteAllUserValues($userId) { - // TODO - FIXME - $this->fixDIInit(); - - $sql = 'DELETE FROM `*PREFIX*preferences` '. - 'WHERE `userid` = ?'; - $this->connection->executeUpdate($sql, array($userId)); - - unset($this->userCache[$userId]); - } - - /** - * Delete all user related values of one app - * - * @param string $appName the appName of the app that we want to remove all values from - */ - public function deleteAppFromAllUsers($appName) { - // TODO - FIXME - $this->fixDIInit(); - - $sql = 'DELETE FROM `*PREFIX*preferences` '. - 'WHERE `appid` = ?'; - $this->connection->executeUpdate($sql, array($appName)); - - foreach ($this->userCache as &$userCache) { - unset($userCache[$appName]); - } - } - - /** - * Returns all user configs sorted by app of one user - * - * @param string $userId the user ID to get the app configs from - * @return array[] - 2 dimensional array with the following structure: - * [ $appId => - * [ $key => $value ] - * ] - */ - private function getUserValues($userId) { - // TODO - FIXME - $this->fixDIInit(); - - if (isset($this->userCache[$userId])) { - return $this->userCache[$userId]; - } - $data = array(); - $query = 'SELECT `appid`, `configkey`, `configvalue` FROM `*PREFIX*preferences` WHERE `userid` = ?'; - $result = $this->connection->executeQuery($query, array($userId)); - while ($row = $result->fetch()) { - $appId = $row['appid']; - if (!isset($data[$appId])) { - $data[$appId] = array(); - } - $data[$appId][$row['configkey']] = $row['configvalue']; - } - $this->userCache[$userId] = $data; - return $data; - } - - /** - * Fetches a mapped list of userId -> value, for a specified app and key and a list of user IDs. - * - * @param string $appName app to get the value for - * @param string $key the key to get the value for - * @param array $userIds the user IDs to fetch the values for - * @return array Mapped values: userId => value - */ - public function getUserValueForUsers($appName, $key, $userIds) { - // TODO - FIXME - $this->fixDIInit(); - - if (empty($userIds) || !is_array($userIds)) { - return array(); - } - - $chunkedUsers = array_chunk($userIds, 50, true); - $placeholders50 = implode(',', array_fill(0, 50, '?')); - - $userValues = array(); - foreach ($chunkedUsers as $chunk) { - $queryParams = $chunk; - // create [$app, $key, $chunkedUsers] - array_unshift($queryParams, $key); - array_unshift($queryParams, $appName); - - $placeholders = (sizeof($chunk) == 50) ? $placeholders50 : implode(',', array_fill(0, sizeof($chunk), '?')); - - $query = 'SELECT `userid`, `configvalue` ' . - 'FROM `*PREFIX*preferences` ' . - 'WHERE `appid` = ? AND `configkey` = ? ' . - 'AND `userid` IN (' . $placeholders . ')'; - $result = $this->connection->executeQuery($query, $queryParams); - - while ($row = $result->fetch()) { - $userValues[$row['userid']] = $row['configvalue']; - } - } - - return $userValues; - } - - /** - * Determines the users that have the given value set for a specific app-key-pair - * - * @param string $appName the app to get the user for - * @param string $key the key to get the user for - * @param string $value the value to get the user for - * @return array of user IDs - */ - public function getUsersForUserValue($appName, $key, $value) { - // TODO - FIXME - $this->fixDIInit(); - - $sql = 'SELECT `userid` FROM `*PREFIX*preferences` ' . - 'WHERE `appid` = ? AND `configkey` = ? '; - - if($this->getSystemValue('dbtype', 'sqlite') === 'oci') { - //oracle hack: need to explicitly cast CLOB to CHAR for comparison - $sql .= 'AND to_char(`configvalue`) = ?'; - } else { - $sql .= 'AND `configvalue` = ?'; - } - - $result = $this->connection->executeQuery($sql, array($appName, $key, $value)); - - $userIDs = array(); - while ($row = $result->fetch()) { - $userIDs[] = $row['userid']; - } - - return $userIDs; - } -} diff --git a/lib/private/appconfig.php b/lib/private/appconfig.php deleted file mode 100644 index 14c48299a8a..00000000000 --- a/lib/private/appconfig.php +++ /dev/null @@ -1,287 +0,0 @@ - - * @author Bart Visscher - * @author Jakob Sack - * @author Joas Schilling - * @author Jörn Friedrich Dreyer - * @author Morris Jobke - * @author Robin Appelman - * @author Robin McCorkell - * - * @copyright Copyright (c) 2016, ownCloud, Inc. - * @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 - * - */ - -namespace OC; - -use OCP\IAppConfig; -use OCP\IDBConnection; - -/** - * This class provides an easy way for apps to store config values in the - * database. - */ -class AppConfig implements IAppConfig { - /** - * @var \OCP\IDBConnection $conn - */ - protected $conn; - - private $cache = array(); - - /** - * @param IDBConnection $conn - */ - public function __construct(IDBConnection $conn) { - $this->conn = $conn; - $this->configLoaded = false; - } - - /** - * @param string $app - * @return array - */ - private function getAppValues($app) { - $this->loadConfigValues(); - - if (isset($this->cache[$app])) { - return $this->cache[$app]; - } - - return []; - } - - /** - * Get all apps using the config - * - * @return array an array of app ids - * - * This function returns a list of all apps that have at least one - * entry in the appconfig table. - */ - public function getApps() { - $this->loadConfigValues(); - - return $this->getSortedKeys($this->cache); - } - - /** - * Get the available keys for an app - * - * @param string $app the app we are looking for - * @return array an array of key names - * - * This function gets all keys of an app. Please note that the values are - * not returned. - */ - public function getKeys($app) { - $this->loadConfigValues(); - - if (isset($this->cache[$app])) { - return $this->getSortedKeys($this->cache[$app]); - } - - return []; - } - - public function getSortedKeys($data) { - $keys = array_keys($data); - sort($keys); - return $keys; - } - - /** - * Gets the config value - * - * @param string $app app - * @param string $key key - * @param string $default = null, default value if the key does not exist - * @return string the value or $default - * - * This function gets a value from the appconfig table. If the key does - * not exist the default value will be returned - */ - public function getValue($app, $key, $default = null) { - $this->loadConfigValues(); - - if ($this->hasKey($app, $key)) { - return $this->cache[$app][$key]; - } - - return $default; - } - - /** - * check if a key is set in the appconfig - * - * @param string $app - * @param string $key - * @return bool - */ - public function hasKey($app, $key) { - $this->loadConfigValues(); - - return isset($this->cache[$app][$key]); - } - - /** - * Sets a value. If the key did not exist before it will be created. - * - * @param string $app app - * @param string $key key - * @param string $value value - * @return bool True if the value was inserted or updated, false if the value was the same - */ - public function setValue($app, $key, $value) { - if (!$this->hasKey($app, $key)) { - $inserted = (bool) $this->conn->insertIfNotExist('*PREFIX*appconfig', [ - 'appid' => $app, - 'configkey' => $key, - 'configvalue' => $value, - ], [ - 'appid', - 'configkey', - ]); - - if ($inserted) { - if (!isset($this->cache[$app])) { - $this->cache[$app] = []; - } - - $this->cache[$app][$key] = $value; - return true; - } - } - - $sql = $this->conn->getQueryBuilder(); - $sql->update('appconfig') - ->set('configvalue', $sql->createParameter('configvalue')) - ->where($sql->expr()->eq('appid', $sql->createParameter('app'))) - ->andWhere($sql->expr()->eq('configkey', $sql->createParameter('configkey'))) - ->setParameter('configvalue', $value) - ->setParameter('app', $app) - ->setParameter('configkey', $key); - - /* - * Only limit to the existing value for non-Oracle DBs: - * http://docs.oracle.com/cd/E11882_01/server.112/e26088/conditions002.htm#i1033286 - * > Large objects (LOBs) are not supported in comparison conditions. - */ - if (!($this->conn instanceof \OC\DB\OracleConnection)) { - // Only update the value when it is not the same - $sql->andWhere($sql->expr()->neq('configvalue', $sql->createParameter('configvalue'))) - ->setParameter('configvalue', $value); - } - - $changedRow = (bool) $sql->execute(); - - $this->cache[$app][$key] = $value; - - return $changedRow; - } - - /** - * Deletes a key - * - * @param string $app app - * @param string $key key - * @return boolean|null - */ - public function deleteKey($app, $key) { - $this->loadConfigValues(); - - $sql = $this->conn->getQueryBuilder(); - $sql->delete('appconfig') - ->where($sql->expr()->eq('appid', $sql->createParameter('app'))) - ->andWhere($sql->expr()->eq('configkey', $sql->createParameter('configkey'))) - ->setParameter('app', $app) - ->setParameter('configkey', $key); - $sql->execute(); - - unset($this->cache[$app][$key]); - } - - /** - * Remove app from appconfig - * - * @param string $app app - * @return boolean|null - * - * Removes all keys in appconfig belonging to the app. - */ - public function deleteApp($app) { - $this->loadConfigValues(); - - $sql = $this->conn->getQueryBuilder(); - $sql->delete('appconfig') - ->where($sql->expr()->eq('appid', $sql->createParameter('app'))) - ->setParameter('app', $app); - $sql->execute(); - - unset($this->cache[$app]); - } - - /** - * get multiple values, either the app or key can be used as wildcard by setting it to false - * - * @param string|false $app - * @param string|false $key - * @return array|false - */ - public function getValues($app, $key) { - if (($app !== false) === ($key !== false)) { - return false; - } - - if ($key === false) { - return $this->getAppValues($app); - } else { - $appIds = $this->getApps(); - $values = array_map(function($appId) use ($key) { - return isset($this->cache[$appId][$key]) ? $this->cache[$appId][$key] : null; - }, $appIds); - $result = array_combine($appIds, $values); - - return array_filter($result); - } - } - - /** - * Load all the app config values - */ - protected function loadConfigValues() { - if ($this->configLoaded) return; - - $this->cache = []; - - $sql = $this->conn->getQueryBuilder(); - $sql->select('*') - ->from('appconfig'); - $result = $sql->execute(); - - while ($row = $result->fetch()) { - if (!isset($this->cache[$row['appid']])) { - $this->cache[$row['appid']] = []; - } - - $this->cache[$row['appid']][$row['configkey']] = $row['configvalue']; - } - $result->closeCursor(); - - $this->configLoaded = true; - } -} diff --git a/lib/private/apphelper.php b/lib/private/apphelper.php deleted file mode 100644 index c19ed2f5b67..00000000000 --- a/lib/private/apphelper.php +++ /dev/null @@ -1,47 +0,0 @@ - - * @author Lukas Reschke - * @author Morris Jobke - * - * @copyright Copyright (c) 2016, ownCloud, Inc. - * @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 - * - */ - -namespace OC; - -/** - * Class AppHelper - * @deprecated 8.1.0 - */ -class AppHelper implements \OCP\IHelper { - /** - * Gets the content of an URL by using CURL or a fallback if it is not - * installed - * @param string $url the url that should be fetched - * @return string the content of the webpage - * @deprecated 8.1.0 Use \OCP\IServerContainer::getHTTPClientService - */ - public function getUrlContent($url) { - try { - $client = \OC::$server->getHTTPClientService()->newClient(); - $response = $client->get($url); - return $response->getBody(); - } catch (\Exception $e) { - return false; - } - } -} diff --git a/lib/private/avatar.php b/lib/private/avatar.php deleted file mode 100644 index 3f8038360a4..00000000000 --- a/lib/private/avatar.php +++ /dev/null @@ -1,198 +0,0 @@ - - * @author Christopher Schäpers - * @author Lukas Reschke - * @author Morris Jobke - * @author Robin Appelman - * @author Roeland Jago Douma - * @author Thomas Müller - * - * @copyright Copyright (c) 2016, ownCloud, Inc. - * @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 - * - */ - -namespace OC; - -use OC\User\User; -use OCP\Files\Folder; -use OCP\Files\File; -use OCP\Files\NotFoundException; -use OCP\Files\NotPermittedException; -use OCP\IAvatar; -use OCP\IImage; -use OCP\IL10N; -use OC_Image; -use OCP\ILogger; - -/** - * This class gets and sets users avatars. - */ - -class Avatar implements IAvatar { - /** @var Folder */ - private $folder; - /** @var IL10N */ - private $l; - /** @var User */ - private $user; - /** @var ILogger */ - private $logger; - - /** - * constructor - * - * @param Folder $folder The folder where the avatars are - * @param IL10N $l - * @param User $user - * @param ILogger $logger - */ - public function __construct (Folder $folder, IL10N $l, $user, ILogger $logger) { - $this->folder = $folder; - $this->l = $l; - $this->user = $user; - $this->logger = $logger; - } - - /** - * @inheritdoc - */ - public function get ($size = 64) { - try { - $file = $this->getFile($size); - } catch (NotFoundException $e) { - return false; - } - - $avatar = new OC_Image(); - $avatar->loadFromData($file->getContent()); - return $avatar; - } - - /** - * Check if an avatar exists for the user - * - * @return bool - */ - public function exists() { - return $this->folder->nodeExists('avatar.jpg') || $this->folder->nodeExists('avatar.png'); - } - - /** - * sets the users avatar - * @param IImage|resource|string $data An image object, imagedata or path to set a new avatar - * @throws \Exception if the provided file is not a jpg or png image - * @throws \Exception if the provided image is not valid - * @throws NotSquareException if the image is not square - * @return void - */ - public function set ($data) { - - if($data instanceOf IImage) { - $img = $data; - $data = $img->data(); - } else { - $img = new OC_Image($data); - } - $type = substr($img->mimeType(), -3); - if ($type === 'peg') { - $type = 'jpg'; - } - if ($type !== 'jpg' && $type !== 'png') { - throw new \Exception($this->l->t("Unknown filetype")); - } - - if (!$img->valid()) { - throw new \Exception($this->l->t("Invalid image")); - } - - if (!($img->height() === $img->width())) { - throw new NotSquareException(); - } - - $this->remove(); - $this->folder->newFile('avatar.'.$type)->putContent($data); - $this->user->triggerChange('avatar'); - } - - /** - * remove the users avatar - * @return void - */ - public function remove () { - $regex = '/^avatar\.([0-9]+\.)?(jpg|png)$/'; - $avatars = $this->folder->getDirectoryListing(); - - foreach ($avatars as $avatar) { - if (preg_match($regex, $avatar->getName())) { - $avatar->delete(); - } - } - $this->user->triggerChange('avatar'); - } - - /** - * @inheritdoc - */ - public function getFile($size) { - $ext = $this->getExtension(); - - if ($size === -1) { - $path = 'avatar.' . $ext; - } else { - $path = 'avatar.' . $size . '.' . $ext; - } - - try { - $file = $this->folder->get($path); - } catch (NotFoundException $e) { - if ($size <= 0) { - throw new NotFoundException; - } - - $avatar = new OC_Image(); - /** @var File $file */ - $file = $this->folder->get('avatar.' . $ext); - $avatar->loadFromData($file->getContent()); - if ($size !== -1) { - $avatar->resize($size); - } - try { - $file = $this->folder->newFile($path); - $file->putContent($avatar->data()); - } catch (NotPermittedException $e) { - $this->logger->error('Failed to save avatar for ' . $this->user->getUID()); - } - } - - return $file; - } - - /** - * Get the extension of the avatar. If there is no avatar throw Exception - * - * @return string - * @throws NotFoundException - */ - private function getExtension() { - if ($this->folder->nodeExists('avatar.jpg')) { - return 'jpg'; - } elseif ($this->folder->nodeExists('avatar.png')) { - return 'png'; - } - throw new NotFoundException; - } -} diff --git a/lib/private/avatarmanager.php b/lib/private/avatarmanager.php deleted file mode 100644 index 62f4faf436c..00000000000 --- a/lib/private/avatarmanager.php +++ /dev/null @@ -1,97 +0,0 @@ - - * @author Lukas Reschke - * @author Morris Jobke - * @author Roeland Jago Douma - * @author Thomas Müller - * - * @copyright Copyright (c) 2016, ownCloud, Inc. - * @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 - * - */ - -namespace OC; - -use OCP\Files\Folder; -use OCP\Files\NotFoundException; -use OCP\IAvatarManager; -use OCP\ILogger; -use OCP\IUserManager; -use OCP\Files\IRootFolder; -use OCP\IL10N; - -/** - * This class implements methods to access Avatar functionality - */ -class AvatarManager implements IAvatarManager { - - /** @var IUserManager */ - private $userManager; - - /** @var IRootFolder */ - private $rootFolder; - - /** @var IL10N */ - private $l; - - /** @var ILogger */ - private $logger; - - /** - * AvatarManager constructor. - * - * @param IUserManager $userManager - * @param IRootFolder $rootFolder - * @param IL10N $l - * @param ILogger $logger - */ - public function __construct( - IUserManager $userManager, - IRootFolder $rootFolder, - IL10N $l, - ILogger $logger) { - $this->userManager = $userManager; - $this->rootFolder = $rootFolder; - $this->l = $l; - $this->logger = $logger; - } - - /** - * return a user specific instance of \OCP\IAvatar - * @see \OCP\IAvatar - * @param string $userId the ownCloud user id - * @return \OCP\IAvatar - * @throws \Exception In case the username is potentially dangerous - * @throws NotFoundException In case there is no user folder yet - */ - public function getAvatar($userId) { - $user = $this->userManager->get($userId); - if (is_null($user)) { - throw new \Exception('user does not exist'); - } - - /* - * Fix for #22119 - * Basically we do not want to copy the skeleton folder - */ - \OC\Files\Filesystem::initMountPoints($userId); - $dir = '/' . $userId; - /** @var Folder $folder */ - $folder = $this->rootFolder->get($dir); - - return new Avatar($folder, $this->l, $user, $this->logger); - } -} diff --git a/lib/private/capabilitiesmanager.php b/lib/private/capabilitiesmanager.php deleted file mode 100644 index 8b89692faa9..00000000000 --- a/lib/private/capabilitiesmanager.php +++ /dev/null @@ -1,64 +0,0 @@ - - * - * @copyright Copyright (c) 2016, ownCloud, Inc. - * @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 - * - */ -namespace OC; - - -use OCP\Capabilities\ICapability; - -class CapabilitiesManager { - - /** - * @var \Closure[] - */ - private $capabilities = array(); - - /** - * Get an array of al the capabilities that are registered at this manager - * - * @throws \InvalidArgumentException - * @return array - */ - public function getCapabilities() { - $capabilities = []; - foreach($this->capabilities as $capability) { - $c = $capability(); - if ($c instanceof ICapability) { - $capabilities = array_replace_recursive($capabilities, $c->getCapabilities()); - } else { - throw new \InvalidArgumentException('The given Capability (' . get_class($c) . ') does not implement the ICapability interface'); - } - } - - return $capabilities; - } - - /** - * In order to improve lazy loading a closure can be registered which will be called in case - * capabilities are actually requested - * - * $callable has to return an instance of OCP\Capabilities\ICapability - * - * @param \Closure $callable - */ - public function registerCapability(\Closure $callable) { - array_push($this->capabilities, $callable); - } -} diff --git a/lib/private/config.php b/lib/private/config.php deleted file mode 100644 index 9bb5c299463..00000000000 --- a/lib/private/config.php +++ /dev/null @@ -1,264 +0,0 @@ - - * @author Aldo "xoen" Giambelluca - * @author Bart Visscher - * @author Brice Maron - * @author Frank Karlitschek - * @author Jakob Sack - * @author Jan-Christoph Borchardt - * @author Joas Schilling - * @author Lukas Reschke - * @author Michael Gapczynski - * @author Morris Jobke - * @author Robin Appelman - * @author Robin McCorkell - * - * @copyright Copyright (c) 2016, ownCloud, Inc. - * @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 - * - */ - -namespace OC; - -/** - * This class is responsible for reading and writing config.php, the very basic - * configuration file of ownCloud. - */ -class Config { - /** @var array Associative array ($key => $value) */ - protected $cache = array(); - /** @var string */ - protected $configDir; - /** @var string */ - protected $configFilePath; - /** @var string */ - protected $configFileName; - - /** - * @param string $configDir Path to the config dir, needs to end with '/' - * @param string $fileName (Optional) Name of the config file. Defaults to config.php - */ - public function __construct($configDir, $fileName = 'config.php') { - $this->configDir = $configDir; - $this->configFilePath = $this->configDir.$fileName; - $this->configFileName = $fileName; - $this->readData(); - } - - /** - * Lists all available config keys - * - * Please note that it does not return the values. - * - * @return array an array of key names - */ - public function getKeys() { - return array_keys($this->cache); - } - - /** - * Gets a value from config.php - * - * If it does not exist, $default will be returned. - * - * @param string $key key - * @param mixed $default = null default value - * @return mixed the value or $default - */ - public function getValue($key, $default = null) { - if (isset($this->cache[$key])) { - return $this->cache[$key]; - } - - return $default; - } - - /** - * Sets and deletes values and writes the config.php - * - * @param array $configs Associative array with `key => value` pairs - * If value is null, the config key will be deleted - */ - public function setValues(array $configs) { - $needsUpdate = false; - foreach ($configs as $key => $value) { - if ($value !== null) { - $needsUpdate |= $this->set($key, $value); - } else { - $needsUpdate |= $this->delete($key); - } - } - - if ($needsUpdate) { - // Write changes - $this->writeData(); - } - } - - /** - * Sets the value and writes it to config.php if required - * - * @param string $key key - * @param mixed $value value - */ - public function setValue($key, $value) { - if ($this->set($key, $value)) { - // Write changes - $this->writeData(); - } - } - - /** - * This function sets the value - * - * @param string $key key - * @param mixed $value value - * @return bool True if the file needs to be updated, false otherwise - */ - protected function set($key, $value) { - if (!isset($this->cache[$key]) || $this->cache[$key] !== $value) { - // Add change - $this->cache[$key] = $value; - return true; - } - - return false; - } - - /** - * Removes a key from the config and removes it from config.php if required - * @param string $key - */ - public function deleteKey($key) { - if ($this->delete($key)) { - // Write changes - $this->writeData(); - } - } - - /** - * This function removes a key from the config - * - * @param string $key - * @return bool True if the file needs to be updated, false otherwise - */ - protected function delete($key) { - if (isset($this->cache[$key])) { - // Delete key from cache - unset($this->cache[$key]); - return true; - } - return false; - } - - /** - * Loads the config file - * - * Reads the config file and saves it to the cache - * - * @throws \Exception If no lock could be acquired or the config file has not been found - */ - private function readData() { - // Default config should always get loaded - $configFiles = array($this->configFilePath); - - // Add all files in the config dir ending with the same file name - $extra = glob($this->configDir.'*.'.$this->configFileName); - if (is_array($extra)) { - natsort($extra); - $configFiles = array_merge($configFiles, $extra); - } - - // Include file and merge config - foreach ($configFiles as $file) { - $filePointer = file_exists($file) ? fopen($file, 'r') : false; - if($file === $this->configFilePath && - $filePointer === false && - @!file_exists($this->configFilePath)) { - // Opening the main config might not be possible, e.g. if the wrong - // permissions are set (likely on a new installation) - continue; - } - - // Try to acquire a file lock - if(!flock($filePointer, LOCK_SH)) { - throw new \Exception(sprintf('Could not acquire a shared lock on the config file %s', $file)); - } - - unset($CONFIG); - include $file; - if(isset($CONFIG) && is_array($CONFIG)) { - $this->cache = array_merge($this->cache, $CONFIG); - } - - // Close the file pointer and release the lock - flock($filePointer, LOCK_UN); - fclose($filePointer); - } - } - - /** - * Writes the config file - * - * Saves the config to the config file. - * - * @throws HintException If the config file cannot be written to - * @throws \Exception If no file lock can be acquired - */ - private function writeData() { - // Create a php file ... - $content = "cache, true); - $content .= ";\n"; - - touch ($this->configFilePath); - $filePointer = fopen($this->configFilePath, 'r+'); - - // Prevent others not to read the config - chmod($this->configFilePath, 0640); - - // File does not exist, this can happen when doing a fresh install - if(!is_resource ($filePointer)) { - // TODO fix this via DI once it is very clear that this doesn't cause side effects due to initialization order - // currently this breaks app routes but also could have other side effects especially during setup and exception handling - $url = \OC::$server->getURLGenerator()->linkToDocs('admin-dir_permissions'); - throw new HintException( - "Can't write into config directory!", - 'This can usually be fixed by ' - .'giving the webserver write access to the config directory.'); - } - - // Try to acquire a file lock - if(!flock($filePointer, LOCK_EX)) { - throw new \Exception(sprintf('Could not acquire an exclusive lock on the config file %s', $this->configFilePath)); - } - - // Write the config and release the lock - ftruncate ($filePointer, 0); - fwrite($filePointer, $content); - fflush($filePointer); - flock($filePointer, LOCK_UN); - fclose($filePointer); - - // Try invalidating the opcache just for the file we wrote... - if (!\OC_Util::deleteFromOpcodeCache($this->configFilePath)) { - // But if that doesn't work, clear the whole cache. - \OC_Util::clearOpcodeCache(); - } - } -} - diff --git a/lib/private/contactsmanager.php b/lib/private/contactsmanager.php deleted file mode 100644 index a2640d36945..00000000000 --- a/lib/private/contactsmanager.php +++ /dev/null @@ -1,189 +0,0 @@ - - * @author Joas Schilling - * @author Morris Jobke - * @author Robin McCorkell - * @author Thomas Müller - * @author Tobia De Koninck - * - * @copyright Copyright (c) 2016, ownCloud, Inc. - * @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 - * - */ - -namespace OC { - - class ContactsManager implements \OCP\Contacts\IManager { - - /** - * This function is used to search and find contacts within the users address books. - * In case $pattern is empty all contacts will be returned. - * - * @param string $pattern which should match within the $searchProperties - * @param array $searchProperties defines the properties within the query pattern should match - * @param array $options - for future use. One should always have options! - * @return array an array of contacts which are arrays of key-value-pairs - */ - public function search($pattern, $searchProperties = array(), $options = array()) { - $this->loadAddressBooks(); - $result = array(); - foreach($this->addressBooks as $addressBook) { - $r = $addressBook->search($pattern, $searchProperties, $options); - $contacts = array(); - foreach($r as $c){ - $c['addressbook-key'] = $addressBook->getKey(); - $contacts[] = $c; - } - $result = array_merge($result, $contacts); - } - - return $result; - } - - /** - * This function can be used to delete the contact identified by the given id - * - * @param object $id the unique identifier to a contact - * @param string $addressBookKey identifier of the address book in which the contact shall be deleted - * @return bool successful or not - */ - public function delete($id, $addressBookKey) { - $addressBook = $this->getAddressBook($addressBookKey); - if (!$addressBook) { - return null; - } - - if ($addressBook->getPermissions() & \OCP\Constants::PERMISSION_DELETE) { - return $addressBook->delete($id); - } - - return null; - } - - /** - * This function is used to create a new contact if 'id' is not given or not present. - * Otherwise the contact will be updated by replacing the entire data set. - * - * @param array $properties this array if key-value-pairs defines a contact - * @param string $addressBookKey identifier of the address book in which the contact shall be created or updated - * @return array representing the contact just created or updated - */ - public function createOrUpdate($properties, $addressBookKey) { - $addressBook = $this->getAddressBook($addressBookKey); - if (!$addressBook) { - return null; - } - - if ($addressBook->getPermissions() & \OCP\Constants::PERMISSION_CREATE) { - return $addressBook->createOrUpdate($properties); - } - - return null; - } - - /** - * Check if contacts are available (e.g. contacts app enabled) - * - * @return bool true if enabled, false if not - */ - public function isEnabled() { - return !empty($this->addressBooks) || !empty($this->addressBookLoaders); - } - - /** - * @param \OCP\IAddressBook $addressBook - */ - public function registerAddressBook(\OCP\IAddressBook $addressBook) { - $this->addressBooks[$addressBook->getKey()] = $addressBook; - } - - /** - * @param \OCP\IAddressBook $addressBook - */ - public function unregisterAddressBook(\OCP\IAddressBook $addressBook) { - unset($this->addressBooks[$addressBook->getKey()]); - } - - /** - * @return array - */ - public function getAddressBooks() { - $this->loadAddressBooks(); - $result = array(); - foreach($this->addressBooks as $addressBook) { - $result[$addressBook->getKey()] = $addressBook->getDisplayName(); - } - - return $result; - } - - /** - * removes all registered address book instances - */ - public function clear() { - $this->addressBooks = array(); - $this->addressBookLoaders = array(); - } - - /** - * @var \OCP\IAddressBook[] which holds all registered address books - */ - private $addressBooks = array(); - - /** - * @var \Closure[] to call to load/register address books - */ - private $addressBookLoaders = array(); - - /** - * In order to improve lazy loading a closure can be registered which will be called in case - * address books are actually requested - * - * @param \Closure $callable - */ - public function register(\Closure $callable) - { - $this->addressBookLoaders[] = $callable; - } - - /** - * Get (and load when needed) the address book for $key - * - * @param string $addressBookKey - * @return \OCP\IAddressBook - */ - protected function getAddressBook($addressBookKey) - { - $this->loadAddressBooks(); - if (!array_key_exists($addressBookKey, $this->addressBooks)) { - return null; - } - - return $this->addressBooks[$addressBookKey]; - } - - /** - * Load all address books registered with 'register' - */ - protected function loadAddressBooks() - { - foreach($this->addressBookLoaders as $callable) { - $callable($this); - } - $this->addressBookLoaders = array(); - } - } -} diff --git a/lib/private/databaseexception.php b/lib/private/databaseexception.php deleted file mode 100644 index 4d50fe82b0f..00000000000 --- a/lib/private/databaseexception.php +++ /dev/null @@ -1,37 +0,0 @@ - - * @author Morris Jobke - * - * @copyright Copyright (c) 2016, ownCloud, Inc. - * @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 - * - */ - -namespace OC; - -class DatabaseException extends \Exception { - private $query; - - //FIXME getQuery seems to be unused, maybe use parent constructor with $message, $code and $previous - public function __construct($message, $query = null){ - parent::__construct($message); - $this->query = $query; - } - - public function getQuery() { - return $this->query; - } -} diff --git a/lib/private/databasesetupexception.php b/lib/private/databasesetupexception.php deleted file mode 100644 index 30bd00de2d6..00000000000 --- a/lib/private/databasesetupexception.php +++ /dev/null @@ -1,26 +0,0 @@ - - * @author Morris Jobke - * - * @copyright Copyright (c) 2016, ownCloud, Inc. - * @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 - * - */ - -namespace OC; - -class DatabaseSetupException extends HintException { -} -- cgit v1.2.3