diff options
author | Roeland Jago Douma <rullzer@owncloud.com> | 2016-04-22 15:28:09 +0200 |
---|---|---|
committer | Roeland Jago Douma <rullzer@owncloud.com> | 2016-04-22 15:28:09 +0200 |
commit | 1d33a5ef133d917074a94d40a939b6cbbe698711 (patch) | |
tree | 6880e3e6eb5b5c5be2a39d078416f92e7b359b91 /lib/private/appframework | |
parent | 606b756a94643eaae87e18b39f6c75e6d18fec7e (diff) | |
download | nextcloud-server-1d33a5ef133d917074a94d40a939b6cbbe698711.tar.gz nextcloud-server-1d33a5ef133d917074a94d40a939b6cbbe698711.zip |
Move \OC\AppFramework to PSR-4
* Also moved the autoloader setup a bit up since we need it in initpaths
Diffstat (limited to 'lib/private/appframework')
22 files changed, 0 insertions, 3683 deletions
diff --git a/lib/private/appframework/app.php b/lib/private/appframework/app.php deleted file mode 100644 index 376a8559454..00000000000 --- a/lib/private/appframework/app.php +++ /dev/null @@ -1,171 +0,0 @@ -<?php -/** - * @author Andreas Fischer <bantu@owncloud.com> - * @author Bernhard Posselt <dev@bernhard-posselt.com> - * @author Lukas Reschke <lukas@owncloud.com> - * @author Morris Jobke <hey@morrisjobke.de> - * @author Thomas Müller <thomas.mueller@tmit.eu> - * - * @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 <http://www.gnu.org/licenses/> - * - */ - - -namespace OC\AppFramework; - -use OC\AppFramework\Http\Dispatcher; -use OC_App; -use OC\AppFramework\DependencyInjection\DIContainer; -use OCP\AppFramework\QueryException; -use OCP\AppFramework\Http\ICallbackResponse; - -/** - * Entry point for every request in your app. You can consider this as your - * public static void main() method - * - * Handles all the dependency injection, controllers and output flow - */ -class App { - - - /** - * Turns an app id into a namespace by either reading the appinfo.xml's - * namespace tag or uppercasing the appid's first letter - * @param string $appId the app id - * @param string $topNamespace the namespace which should be prepended to - * the transformed app id, defaults to OCA\ - * @return string the starting namespace for the app - */ - public static function buildAppNamespace($appId, $topNamespace='OCA\\') { - // first try to parse the app's appinfo/info.xml <namespace> tag - $appPath = OC_App::getAppPath($appId); - if ($appPath !== false) { - $filePath = "$appPath/appinfo/info.xml"; - if (is_file($filePath)) { - $loadEntities = libxml_disable_entity_loader(false); - $xml = @simplexml_load_file($filePath); - libxml_disable_entity_loader($loadEntities); - if ($xml) { - $result = $xml->xpath('/info/namespace'); - if ($result && count($result) > 0) { - // take first namespace result - return $topNamespace . trim((string) $result[0]); - } - } - } - } - // if the tag is not found, fall back to uppercasing the first letter - return $topNamespace . ucfirst($appId); - } - - - /** - * Shortcut for calling a controller method and printing the result - * @param string $controllerName the name of the controller under which it is - * stored in the DI container - * @param string $methodName the method that you want to call - * @param DIContainer $container an instance of a pimple container. - * @param array $urlParams list of URL parameters (optional) - */ - public static function main($controllerName, $methodName, DIContainer $container, array $urlParams = null) { - if (!is_null($urlParams)) { - $container['OCP\\IRequest']->setUrlParameters($urlParams); - } else if (isset($container['urlParams']) && !is_null($container['urlParams'])) { - $container['OCP\\IRequest']->setUrlParameters($container['urlParams']); - } - $appName = $container['AppName']; - - // first try $controllerName then go for \OCA\AppName\Controller\$controllerName - try { - $controller = $container->query($controllerName); - } catch(QueryException $e) { - $appNameSpace = self::buildAppNamespace($appName); - $controllerName = $appNameSpace . '\\Controller\\' . $controllerName; - $controller = $container->query($controllerName); - } - - // initialize the dispatcher and run all the middleware before the controller - /** @var Dispatcher $dispatcher */ - $dispatcher = $container['Dispatcher']; - - list( - $httpHeaders, - $responseHeaders, - $responseCookies, - $output, - $response - ) = $dispatcher->dispatch($controller, $methodName); - - $io = $container['OCP\\AppFramework\\Http\\IOutput']; - - if(!is_null($httpHeaders)) { - $io->setHeader($httpHeaders); - } - - foreach($responseHeaders as $name => $value) { - $io->setHeader($name . ': ' . $value); - } - - foreach($responseCookies as $name => $value) { - $expireDate = null; - if($value['expireDate'] instanceof \DateTime) { - $expireDate = $value['expireDate']->getTimestamp(); - } - $io->setCookie( - $name, - $value['value'], - $expireDate, - $container->getServer()->getWebRoot(), - null, - $container->getServer()->getRequest()->getServerProtocol() === 'https', - true - ); - } - - if ($response instanceof ICallbackResponse) { - $response->callback($io); - } else if(!is_null($output)) { - $io->setHeader('Content-Length: ' . strlen($output)); - $io->setOutput($output); - } - - } - - /** - * Shortcut for calling a controller method and printing the result. - * Similar to App:main except that no headers will be sent. - * This should be used for example when registering sections via - * \OC\AppFramework\Core\API::registerAdmin() - * - * @param string $controllerName the name of the controller under which it is - * stored in the DI container - * @param string $methodName the method that you want to call - * @param array $urlParams an array with variables extracted from the routes - * @param DIContainer $container an instance of a pimple container. - */ - public static function part($controllerName, $methodName, array $urlParams, - DIContainer $container){ - - $container['urlParams'] = $urlParams; - $controller = $container[$controllerName]; - - $dispatcher = $container['Dispatcher']; - - list(, , $output) = $dispatcher->dispatch($controller, $methodName); - return $output; - } - -} diff --git a/lib/private/appframework/core/api.php b/lib/private/appframework/core/api.php deleted file mode 100644 index 67b696948f0..00000000000 --- a/lib/private/appframework/core/api.php +++ /dev/null @@ -1,200 +0,0 @@ -<?php -/** - * @author Bernhard Posselt <dev@bernhard-posselt.com> - * @author Lukas Reschke <lukas@owncloud.com> - * @author Morris Jobke <hey@morrisjobke.de> - * @author Robin Appelman <icewind@owncloud.com> - * @author Robin McCorkell <robin@mccorkell.me.uk> - * @author Thomas Müller <thomas.mueller@tmit.eu> - * - * @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 <http://www.gnu.org/licenses/> - * - */ - - -namespace OC\AppFramework\Core; -use OCP\AppFramework\IApi; - - -/** - * This is used to wrap the owncloud static api calls into an object to make the - * code better abstractable for use in the dependency injection container - * - * Should you find yourself in need for more methods, simply inherit from this - * class and add your methods - * @deprecated - */ -class API implements IApi{ - - private $appName; - - /** - * constructor - * @param string $appName the name of your application - */ - public function __construct($appName){ - $this->appName = $appName; - } - - - /** - * Gets the userid of the current user - * @return string the user id of the current user - * @deprecated Use \OC::$server->getUserSession()->getUser()->getUID() - */ - public function getUserId(){ - return \OCP\User::getUser(); - } - - - /** - * Adds a new javascript file - * @deprecated include javascript and css in template files - * @param string $scriptName the name of the javascript in js/ without the suffix - * @param string $appName the name of the app, defaults to the current one - */ - public function addScript($scriptName, $appName=null){ - if($appName === null){ - $appName = $this->appName; - } - \OCP\Util::addScript($appName, $scriptName); - } - - - /** - * Adds a new css file - * @deprecated include javascript and css in template files - * @param string $styleName the name of the css file in css/without the suffix - * @param string $appName the name of the app, defaults to the current one - */ - public function addStyle($styleName, $appName=null){ - if($appName === null){ - $appName = $this->appName; - } - \OCP\Util::addStyle($appName, $styleName); - } - - - /** - * @deprecated include javascript and css in template files - * shorthand for addScript for files in the 3rdparty directory - * @param string $name the name of the file without the suffix - */ - public function add3rdPartyScript($name){ - \OCP\Util::addScript($this->appName . '/3rdparty', $name); - } - - - /** - * @deprecated include javascript and css in template files - * shorthand for addStyle for files in the 3rdparty directory - * @param string $name the name of the file without the suffix - */ - public function add3rdPartyStyle($name){ - \OCP\Util::addStyle($this->appName . '/3rdparty', $name); - } - - - /** - * @deprecated communication between apps should happen over built in - * callbacks or interfaces (check the contacts and calendar managers) - * Checks if an app is enabled - * also use \OC::$server->getAppManager()->isEnabledForUser($appName) - * @param string $appName the name of an app - * @return bool true if app is enabled - */ - public function isAppEnabled($appName){ - return \OCP\App::isEnabled($appName); - } - - - /** - * used to return and open a new event source - * @return \OCP\IEventSource a new open EventSource class - * @deprecated Use \OC::$server->createEventSource(); - */ - public function openEventSource(){ - return \OC::$server->createEventSource(); - } - - /** - * @deprecated register hooks directly for class that build in hook interfaces - * connects a function to a hook - * @param string $signalClass class name of emitter - * @param string $signalName name of signal - * @param string $slotClass class name of slot - * @param string $slotName name of slot, in another word, this is the - * name of the method that will be called when registered - * signal is emitted. - * @return bool always true - */ - public function connectHook($signalClass, $signalName, $slotClass, $slotName) { - return \OCP\Util::connectHook($signalClass, $signalName, $slotClass, $slotName); - } - - /** - * @deprecated implement the emitter interface instead - * Emits a signal. To get data from the slot use references! - * @param string $signalClass class name of emitter - * @param string $signalName name of signal - * @param array $params default: array() array with additional data - * @return bool true if slots exists or false if not - */ - public function emitHook($signalClass, $signalName, $params = array()) { - return \OCP\Util::emitHook($signalClass, $signalName, $params); - } - - /** - * clear hooks - * @deprecated clear hooks directly for class that build in hook interfaces - * @param string $signalClass - * @param string $signalName - */ - public function clearHook($signalClass=false, $signalName=false) { - if ($signalClass) { - \OC_Hook::clear($signalClass, $signalName); - } - } - - - /** - * Register a backgroundjob task - * @param string $className full namespace and class name of the class - * @param string $methodName the name of the static method that should be - * called - * @deprecated Use \OC::$server->getJobList()->add(); - */ - public function addRegularTask($className, $methodName) { - \OCP\Backgroundjob::addRegularTask($className, $methodName); - } - - - /** - * Tells ownCloud to include a template in the admin overview - * @param string $mainPath the path to the main php file without the php - * suffix, relative to your apps directory! not the template directory - * @param string $appName the name of the app, defaults to the current one - */ - public function registerAdmin($mainPath, $appName=null) { - if($appName === null){ - $appName = $this->appName; - } - - \OCP\App::registerAdmin($appName, $mainPath); - } - - -} diff --git a/lib/private/appframework/db/db.php b/lib/private/appframework/db/db.php deleted file mode 100644 index 0d17d7bc225..00000000000 --- a/lib/private/appframework/db/db.php +++ /dev/null @@ -1,287 +0,0 @@ -<?php -/** - * @author Bernhard Posselt <dev@bernhard-posselt.com> - * @author Joas Schilling <nickvergessen@owncloud.com> - * @author Morris Jobke <hey@morrisjobke.de> - * @author Robin Appelman <icewind@owncloud.com> - * @author Robin McCorkell <robin@mccorkell.me.uk> - * @author Thomas Müller <thomas.mueller@tmit.eu> - * - * @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 <http://www.gnu.org/licenses/> - * - */ - -namespace OC\AppFramework\Db; - -use OCP\DB\QueryBuilder\IQueryBuilder; -use OCP\IDb; -use OCP\IDBConnection; - -/** - * @deprecated use IDBConnection directly, will be removed in ownCloud 10 - * Small Facade for being able to inject the database connection for tests - */ -class Db implements IDb { - /** - * @var IDBConnection - */ - protected $connection; - - /** - * @param IDBConnection $connection - */ - public function __construct(IDBConnection $connection) { - $this->connection = $connection; - } - - /** - * Gets the ExpressionBuilder for the connection. - * - * @return \OCP\DB\QueryBuilder\IQueryBuilder - */ - public function getQueryBuilder() { - return $this->connection->getQueryBuilder(); - } - - /** - * Used to abstract the ownCloud database access away - * - * @param string $sql the sql query with ? placeholder for params - * @param int $limit the maximum number of rows - * @param int $offset from which row we want to start - * @deprecated use prepare instead, will be removed in ownCloud 10 - * @return \OC_DB_StatementWrapper prepared SQL query - */ - public function prepareQuery($sql, $limit = null, $offset = null) { - $isManipulation = \OC_DB::isManipulation($sql); - $statement = $this->connection->prepare($sql, $limit, $offset); - return new \OC_DB_StatementWrapper($statement, $isManipulation); - } - - - /** - * Used to get the id of the just inserted element - * - * @deprecated use lastInsertId instead, will be removed in ownCloud 10 - * @param string $tableName the name of the table where we inserted the item - * @return int the id of the inserted element - */ - public function getInsertId($tableName) { - return $this->connection->lastInsertId($tableName); - } - - /** - * Used to abstract the ownCloud database access away - * @param string $sql the sql query with ? placeholder for params - * @param int $limit the maximum number of rows - * @param int $offset from which row we want to start - * @return \Doctrine\DBAL\Driver\Statement The prepared statement. - */ - public function prepare($sql, $limit=null, $offset=null) { - return $this->connection->prepare($sql, $limit, $offset); - } - - /** - * Executes an, optionally parameterized, SQL query. - * - * If the query is parameterized, a prepared statement is used. - * If an SQLLogger is configured, the execution is logged. - * - * @param string $query The SQL query to execute. - * @param string[] $params The parameters to bind to the query, if any. - * @param array $types The types the previous parameters are in. - * @return \Doctrine\DBAL\Driver\Statement The executed statement. - */ - public function executeQuery($query, array $params = array(), $types = array()) { - return $this->connection->executeQuery($query, $params, $types); - } - - /** - * Executes an SQL INSERT/UPDATE/DELETE query with the given parameters - * and returns the number of affected rows. - * - * This method supports PDO binding types as well as DBAL mapping types. - * - * @param string $query The SQL query. - * @param array $params The query parameters. - * @param array $types The parameter types. - * @return integer The number of affected rows. - */ - public function executeUpdate($query, array $params = array(), array $types = array()) { - return $this->connection->executeUpdate($query, $params, $types); - } - - /** - * Used to get the id of the just inserted element - * @param string $table the name of the table where we inserted the item - * @return int the id of the inserted element - */ - public function lastInsertId($table = null) { - return $this->connection->lastInsertId($table); - } - - /** - * Insert a row if the matching row does not exists. - * - * @param string $table The table name (will replace *PREFIX* with the actual prefix) - * @param array $input data that should be inserted into the table (column name => value) - * @param array|null $compare List of values that should be checked for "if not exists" - * If this is null or an empty array, all keys of $input will be compared - * Please note: text fields (clob) must not be used in the compare array - * @return int number of inserted rows - * @throws \Doctrine\DBAL\DBALException - */ - public function insertIfNotExist($table, $input, array $compare = null) { - return $this->connection->insertIfNotExist($table, $input, $compare); - } - - /** - * Insert or update a row value - * - * @param string $table - * @param array $keys (column name => value) - * @param array $values (column name => value) - * @param array $updatePreconditionValues ensure values match preconditions (column name => value) - * @return int number of new rows - * @throws \Doctrine\DBAL\DBALException - * @throws PreconditionNotMetException - */ - public function setValues($table, array $keys, array $values, array $updatePreconditionValues = []) { - return $this->connection->setValues($table, $keys, $values, $updatePreconditionValues); - } - - /** - * Start a transaction - */ - public function beginTransaction() { - $this->connection->beginTransaction(); - } - - /** - * Check if a transaction is active - * - * @return bool - */ - public function inTransaction() { - return $this->connection->inTransaction(); - } - - /** - * Commit the database changes done during a transaction that is in progress - */ - public function commit() { - $this->connection->commit(); - } - - /** - * Rollback the database changes done during a transaction that is in progress - */ - public function rollBack() { - $this->connection->rollBack(); - } - - /** - * Gets the error code and message as a string for logging - * @return string - */ - public function getError() { - return $this->connection->getError(); - } - - /** - * Fetch the SQLSTATE associated with the last database operation. - * - * @return integer The last error code. - */ - public function errorCode() { - return $this->connection->errorCode(); - } - - /** - * Fetch extended error information associated with the last database operation. - * - * @return array The last error information. - */ - public function errorInfo() { - return $this->connection->errorInfo(); - } - - /** - * Establishes the connection with the database. - * - * @return bool - */ - public function connect() { - return $this->connection->connect(); - } - - /** - * Close the database connection - */ - public function close() { - $this->connection->close(); - } - - /** - * Quotes a given input parameter. - * - * @param mixed $input Parameter to be quoted. - * @param int $type Type of the parameter. - * @return string The quoted parameter. - */ - public function quote($input, $type = IQueryBuilder::PARAM_STR) { - return $this->connection->quote($input, $type); - } - - /** - * Gets the DatabasePlatform instance that provides all the metadata about - * the platform this driver connects to. - * - * @return \Doctrine\DBAL\Platforms\AbstractPlatform The database platform. - */ - public function getDatabasePlatform() { - return $this->connection->getDatabasePlatform(); - } - - /** - * Drop a table from the database if it exists - * - * @param string $table table name without the prefix - */ - public function dropTable($table) { - $this->connection->dropTable($table); - } - - /** - * Check if a table exists - * - * @param string $table table name without the prefix - * @return bool - */ - public function tableExists($table) { - return $this->connection->tableExists($table); - } - - /** - * Espace a parameter to be used in a LIKE query - * - * @param string $param - * @return string - */ - public function escapeLikeParameter($param) { - return $this->connection->escapeLikeParameter($param); - } -} diff --git a/lib/private/appframework/dependencyinjection/dicontainer.php b/lib/private/appframework/dependencyinjection/dicontainer.php deleted file mode 100644 index f74fe4aeb99..00000000000 --- a/lib/private/appframework/dependencyinjection/dicontainer.php +++ /dev/null @@ -1,461 +0,0 @@ -<?php -/** - * @author Bernhard Posselt <dev@bernhard-posselt.com> - * @author Joas Schilling <nickvergessen@owncloud.com> - * @author Jörn Friedrich Dreyer <jfd@butonic.de> - * @author Lukas Reschke <lukas@owncloud.com> - * @author Morris Jobke <hey@morrisjobke.de> - * @author Robin McCorkell <robin@mccorkell.me.uk> - * @author Roeland Jago Douma <rullzer@owncloud.com> - * @author Thomas Müller <thomas.mueller@tmit.eu> - * @author Thomas Tanghus <thomas@tanghus.net> - * - * @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 <http://www.gnu.org/licenses/> - * - */ - - -namespace OC\AppFramework\DependencyInjection; - -use OC; -use OC\AppFramework\Http; -use OC\AppFramework\Http\Dispatcher; -use OC\AppFramework\Http\Output; -use OC\AppFramework\Core\API; -use OC\AppFramework\Middleware\MiddlewareDispatcher; -use OC\AppFramework\Middleware\Security\SecurityMiddleware; -use OC\AppFramework\Middleware\Security\CORSMiddleware; -use OC\AppFramework\Middleware\SessionMiddleware; -use OC\AppFramework\Utility\SimpleContainer; -use OCP\AppFramework\IApi; -use OCP\AppFramework\IAppContainer; - - -class DIContainer extends SimpleContainer implements IAppContainer { - - /** - * @var array - */ - private $middleWares = array(); - - /** - * Put your class dependencies in here - * @param string $appName the name of the app - */ - public function __construct($appName, $urlParams = array()){ - parent::__construct(); - $this['AppName'] = $appName; - $this['urlParams'] = $urlParams; - - /** @var \OC\ServerContainer $server */ - $server = $this->getServer(); - $server->registerAppContainer($appName, $this); - - // aliases - $this->registerAlias('appName', 'AppName'); - $this->registerAlias('webRoot', 'WebRoot'); - $this->registerAlias('userId', 'UserId'); - - /** - * Core services - */ - $this->registerService('OCP\\IAppConfig', function($c) { - return $this->getServer()->getAppConfig(); - }); - - $this->registerService('OCP\\App\\IAppManager', function($c) { - return $this->getServer()->getAppManager(); - }); - - $this->registerService('OCP\\AppFramework\\Http\\IOutput', function($c){ - return new Output($this->getServer()->getWebRoot()); - }); - - $this->registerService('OCP\\IAvatarManager', function($c) { - return $this->getServer()->getAvatarManager(); - }); - - $this->registerService('OCP\\Activity\\IManager', function($c) { - return $this->getServer()->getActivityManager(); - }); - - $this->registerService('OCP\\ICache', function($c) { - return $this->getServer()->getCache(); - }); - - $this->registerService('OCP\\ICacheFactory', function($c) { - return $this->getServer()->getMemCacheFactory(); - }); - - $this->registerService('OC\\CapabilitiesManager', function($c) { - return $this->getServer()->getCapabilitiesManager(); - }); - - $this->registerService('OCP\Comments\ICommentsManager', function($c) { - return $this->getServer()->getCommentsManager(); - }); - - $this->registerService('OCP\\IConfig', function($c) { - return $this->getServer()->getConfig(); - }); - - $this->registerService('OCP\\Contacts\\IManager', function($c) { - return $this->getServer()->getContactsManager(); - }); - - $this->registerService('OCP\\IDateTimeZone', function($c) { - return $this->getServer()->getDateTimeZone(); - }); - - $this->registerService('OCP\\IDb', function($c) { - return $this->getServer()->getDb(); - }); - - $this->registerService('OCP\\IDBConnection', function($c) { - return $this->getServer()->getDatabaseConnection(); - }); - - $this->registerService('OCP\\Diagnostics\\IEventLogger', function($c) { - return $this->getServer()->getEventLogger(); - }); - - $this->registerService('OCP\\Diagnostics\\IQueryLogger', function($c) { - return $this->getServer()->getQueryLogger(); - }); - - $this->registerService('OCP\\Files\\IMimeTypeDetector', function($c) { - return $this->getServer()->getMimeTypeDetector(); - }); - - $this->registerService('OCP\\Files\\Config\\IMountProviderCollection', function($c) { - return $this->getServer()->getMountProviderCollection(); - }); - - $this->registerService('OCP\\Files\\IRootFolder', function($c) { - return $this->getServer()->getRootFolder(); - }); - - $this->registerService('OCP\\IGroupManager', function($c) { - return $this->getServer()->getGroupManager(); - }); - - $this->registerService('OCP\\IL10N', function($c) { - return $this->getServer()->getL10N($c->query('AppName')); - }); - - $this->registerService('OCP\\L10N\\IFactory', function($c) { - return $this->getServer()->getL10NFactory(); - }); - - $this->registerService('OCP\\ILogger', function($c) { - return $this->getServer()->getLogger(); - }); - - $this->registerService('OCP\\BackgroundJob\\IJobList', function($c) { - return $this->getServer()->getJobList(); - }); - - $this->registerAlias('OCP\\AppFramework\\Utility\\IControllerMethodReflector', 'OC\AppFramework\Utility\ControllerMethodReflector'); - $this->registerAlias('ControllerMethodReflector', 'OCP\\AppFramework\\Utility\\IControllerMethodReflector'); - - $this->registerService('OCP\\Files\\IMimeTypeDetector', function($c) { - return $this->getServer()->getMimeTypeDetector(); - }); - - $this->registerService('OCP\\INavigationManager', function($c) { - return $this->getServer()->getNavigationManager(); - }); - - $this->registerService('OCP\\Notification\IManager', function($c) { - return $this->getServer()->getNotificationManager(); - }); - - $this->registerService('OCP\\IPreview', function($c) { - return $this->getServer()->getPreviewManager(); - }); - - $this->registerService('OCP\\IRequest', function () { - return $this->getServer()->getRequest(); - }); - $this->registerAlias('Request', 'OCP\\IRequest'); - - $this->registerService('OCP\\ITagManager', function($c) { - return $this->getServer()->getTagManager(); - }); - - $this->registerService('OCP\\ITempManager', function($c) { - return $this->getServer()->getTempManager(); - }); - - $this->registerAlias('OCP\\AppFramework\\Utility\\ITimeFactory', 'OC\AppFramework\Utility\TimeFactory'); - $this->registerAlias('TimeFactory', 'OCP\\AppFramework\\Utility\\ITimeFactory'); - - - $this->registerService('OCP\\Route\\IRouter', function($c) { - return $this->getServer()->getRouter(); - }); - - $this->registerService('OCP\\ISearch', function($c) { - return $this->getServer()->getSearch(); - }); - - $this->registerService('OCP\\ISearch', function($c) { - return $this->getServer()->getSearch(); - }); - - $this->registerService('OCP\\Security\\ICrypto', function($c) { - return $this->getServer()->getCrypto(); - }); - - $this->registerService('OCP\\Security\\IHasher', function($c) { - return $this->getServer()->getHasher(); - }); - - $this->registerService('OCP\\Security\\ICredentialsManager', function($c) { - return $this->getServer()->getCredentialsManager(); - }); - - $this->registerService('OCP\\Security\\ISecureRandom', function($c) { - return $this->getServer()->getSecureRandom(); - }); - - $this->registerService('OCP\\Share\\IManager', function($c) { - return $this->getServer()->getShareManager(); - }); - - $this->registerService('OCP\\SystemTag\\ISystemTagManager', function() { - return $this->getServer()->getSystemTagManager(); - }); - - $this->registerService('OCP\\SystemTag\\ISystemTagObjectMapper', function() { - return $this->getServer()->getSystemTagObjectMapper(); - }); - - $this->registerService('OCP\\IURLGenerator', function($c) { - return $this->getServer()->getURLGenerator(); - }); - - $this->registerService('OCP\\IUserManager', function($c) { - return $this->getServer()->getUserManager(); - }); - - $this->registerService('OCP\\IUserSession', function($c) { - return $this->getServer()->getUserSession(); - }); - - $this->registerService('OCP\\ISession', function($c) { - return $this->getServer()->getSession(); - }); - - $this->registerService('OCP\\Security\\IContentSecurityPolicyManager', function($c) { - return $this->getServer()->getContentSecurityPolicyManager(); - }); - - $this->registerService('ServerContainer', function ($c) { - return $this->getServer(); - }); - $this->registerAlias('OCP\\IServerContainer', 'ServerContainer'); - - $this->registerService('Symfony\Component\EventDispatcher\EventDispatcherInterface', function ($c) { - return $this->getServer()->getEventDispatcher(); - }); - - $this->registerService('OCP\\AppFramework\\IAppContainer', function ($c) { - return $c; - }); - - // commonly used attributes - $this->registerService('UserId', function ($c) { - return $c->query('OCP\\IUserSession')->getSession()->get('user_id'); - }); - - $this->registerService('WebRoot', function ($c) { - return $c->query('ServerContainer')->getWebRoot(); - }); - - - /** - * App Framework APIs - */ - $this->registerService('API', function($c){ - $c->query('OCP\\ILogger')->debug( - 'Accessing the API class is deprecated! Use the appropriate ' . - 'services instead!' - ); - return new API($c['AppName']); - }); - - $this->registerService('Protocol', function($c){ - /** @var \OC\Server $server */ - $server = $c->query('ServerContainer'); - $protocol = $server->getRequest()->getHttpProtocol(); - return new Http($_SERVER, $protocol); - }); - - $this->registerService('Dispatcher', function($c) { - return new Dispatcher( - $c['Protocol'], - $c['MiddlewareDispatcher'], - $c['ControllerMethodReflector'], - $c['Request'] - ); - }); - - - /** - * Middleware - */ - $app = $this; - $this->registerService('SecurityMiddleware', function($c) use ($app){ - return new SecurityMiddleware( - $c['Request'], - $c['ControllerMethodReflector'], - $app->getServer()->getNavigationManager(), - $app->getServer()->getURLGenerator(), - $app->getServer()->getLogger(), - $c['AppName'], - $app->isLoggedIn(), - $app->isAdminUser(), - $app->getServer()->getContentSecurityPolicyManager() - ); - }); - - $this->registerService('CORSMiddleware', function($c) { - return new CORSMiddleware( - $c['Request'], - $c['ControllerMethodReflector'], - $c['OCP\IUserSession'] - ); - }); - - $this->registerService('SessionMiddleware', function($c) use ($app) { - return new SessionMiddleware( - $c['Request'], - $c['ControllerMethodReflector'], - $app->getServer()->getSession() - ); - }); - - $middleWares = &$this->middleWares; - $this->registerService('MiddlewareDispatcher', function($c) use (&$middleWares) { - $dispatcher = new MiddlewareDispatcher(); - $dispatcher->registerMiddleware($c['CORSMiddleware']); - $dispatcher->registerMiddleware($c['SecurityMiddleware']); - - foreach($middleWares as $middleWare) { - $dispatcher->registerMiddleware($c[$middleWare]); - } - - $dispatcher->registerMiddleware($c['SessionMiddleware']); - return $dispatcher; - }); - - } - - - /** - * @deprecated implements only deprecated methods - * @return IApi - */ - function getCoreApi() - { - return $this->query('API'); - } - - /** - * @return \OCP\IServerContainer - */ - function getServer() - { - return OC::$server; - } - - /** - * @param string $middleWare - * @return boolean|null - */ - function registerMiddleWare($middleWare) { - array_push($this->middleWares, $middleWare); - } - - /** - * used to return the appname of the set application - * @return string the name of your application - */ - function getAppName() { - return $this->query('AppName'); - } - - /** - * @deprecated use IUserSession->isLoggedIn() - * @return boolean - */ - function isLoggedIn() { - return \OC_User::isLoggedIn(); - } - - /** - * @deprecated use IGroupManager->isAdmin($userId) - * @return boolean - */ - function isAdminUser() { - $uid = $this->getUserId(); - return \OC_User::isAdminUser($uid); - } - - private function getUserId() { - return $this->getServer()->getSession()->get('user_id'); - } - - /** - * @deprecated use the ILogger instead - * @param string $message - * @param string $level - * @return mixed - */ - function log($message, $level) { - switch($level){ - case 'debug': - $level = \OCP\Util::DEBUG; - break; - case 'info': - $level = \OCP\Util::INFO; - break; - case 'warn': - $level = \OCP\Util::WARN; - break; - case 'fatal': - $level = \OCP\Util::FATAL; - break; - default: - $level = \OCP\Util::ERROR; - break; - } - \OCP\Util::writeLog($this->getAppName(), $message, $level); - } - - /** - * Register a capability - * - * @param string $serviceName e.g. 'OCA\Files\Capabilities' - */ - public function registerCapability($serviceName) { - $this->query('OC\CapabilitiesManager')->registerCapability(function() use ($serviceName) { - return $this->query($serviceName); - }); - - } -} diff --git a/lib/private/appframework/http.php b/lib/private/appframework/http.php deleted file mode 100644 index a99f7ea437f..00000000000 --- a/lib/private/appframework/http.php +++ /dev/null @@ -1,154 +0,0 @@ -<?php -/** - * @author Jörn Friedrich Dreyer <jfd@butonic.de> - * @author Lukas Reschke <lukas@owncloud.com> - * @author Morris Jobke <hey@morrisjobke.de> - * @author Robin McCorkell <robin@mccorkell.me.uk> - * @author Roeland Jago Douma <rullzer@owncloud.com> - * @author Thomas Müller <thomas.mueller@tmit.eu> - * @author Thomas Tanghus <thomas@tanghus.net> - * - * @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 <http://www.gnu.org/licenses/> - * - */ - - -namespace OC\AppFramework; - -use OCP\AppFramework\Http as BaseHttp; - -class Http extends BaseHttp { - - private $server; - private $protocolVersion; - protected $headers; - - /** - * @param array $server $_SERVER - * @param string $protocolVersion the http version to use defaults to HTTP/1.1 - */ - public function __construct($server, $protocolVersion='HTTP/1.1') { - $this->server = $server; - $this->protocolVersion = $protocolVersion; - - $this->headers = array( - self::STATUS_CONTINUE => 'Continue', - self::STATUS_SWITCHING_PROTOCOLS => 'Switching Protocols', - self::STATUS_PROCESSING => 'Processing', - self::STATUS_OK => 'OK', - self::STATUS_CREATED => 'Created', - self::STATUS_ACCEPTED => 'Accepted', - self::STATUS_NON_AUTHORATIVE_INFORMATION => 'Non-Authorative Information', - self::STATUS_NO_CONTENT => 'No Content', - self::STATUS_RESET_CONTENT => 'Reset Content', - self::STATUS_PARTIAL_CONTENT => 'Partial Content', - self::STATUS_MULTI_STATUS => 'Multi-Status', // RFC 4918 - self::STATUS_ALREADY_REPORTED => 'Already Reported', // RFC 5842 - self::STATUS_IM_USED => 'IM Used', // RFC 3229 - self::STATUS_MULTIPLE_CHOICES => 'Multiple Choices', - self::STATUS_MOVED_PERMANENTLY => 'Moved Permanently', - self::STATUS_FOUND => 'Found', - self::STATUS_SEE_OTHER => 'See Other', - self::STATUS_NOT_MODIFIED => 'Not Modified', - self::STATUS_USE_PROXY => 'Use Proxy', - self::STATUS_RESERVED => 'Reserved', - self::STATUS_TEMPORARY_REDIRECT => 'Temporary Redirect', - self::STATUS_BAD_REQUEST => 'Bad request', - self::STATUS_UNAUTHORIZED => 'Unauthorized', - self::STATUS_PAYMENT_REQUIRED => 'Payment Required', - self::STATUS_FORBIDDEN => 'Forbidden', - self::STATUS_NOT_FOUND => 'Not Found', - self::STATUS_METHOD_NOT_ALLOWED => 'Method Not Allowed', - self::STATUS_NOT_ACCEPTABLE => 'Not Acceptable', - self::STATUS_PROXY_AUTHENTICATION_REQUIRED => 'Proxy Authentication Required', - self::STATUS_REQUEST_TIMEOUT => 'Request Timeout', - self::STATUS_CONFLICT => 'Conflict', - self::STATUS_GONE => 'Gone', - self::STATUS_LENGTH_REQUIRED => 'Length Required', - self::STATUS_PRECONDITION_FAILED => 'Precondition failed', - self::STATUS_REQUEST_ENTITY_TOO_LARGE => 'Request Entity Too Large', - self::STATUS_REQUEST_URI_TOO_LONG => 'Request-URI Too Long', - self::STATUS_UNSUPPORTED_MEDIA_TYPE => 'Unsupported Media Type', - self::STATUS_REQUEST_RANGE_NOT_SATISFIABLE => 'Requested Range Not Satisfiable', - self::STATUS_EXPECTATION_FAILED => 'Expectation Failed', - self::STATUS_IM_A_TEAPOT => 'I\'m a teapot', // RFC 2324 - self::STATUS_UNPROCESSABLE_ENTITY => 'Unprocessable Entity', // RFC 4918 - self::STATUS_LOCKED => 'Locked', // RFC 4918 - self::STATUS_FAILED_DEPENDENCY => 'Failed Dependency', // RFC 4918 - self::STATUS_UPGRADE_REQUIRED => 'Upgrade required', - self::STATUS_PRECONDITION_REQUIRED => 'Precondition required', // draft-nottingham-http-new-status - self::STATUS_TOO_MANY_REQUESTS => 'Too Many Requests', // draft-nottingham-http-new-status - self::STATUS_REQUEST_HEADER_FIELDS_TOO_LARGE => 'Request Header Fields Too Large', // draft-nottingham-http-new-status - self::STATUS_INTERNAL_SERVER_ERROR => 'Internal Server Error', - self::STATUS_NOT_IMPLEMENTED => 'Not Implemented', - self::STATUS_BAD_GATEWAY => 'Bad Gateway', - self::STATUS_SERVICE_UNAVAILABLE => 'Service Unavailable', - self::STATUS_GATEWAY_TIMEOUT => 'Gateway Timeout', - self::STATUS_HTTP_VERSION_NOT_SUPPORTED => 'HTTP Version not supported', - self::STATUS_VARIANT_ALSO_NEGOTIATES => 'Variant Also Negotiates', - self::STATUS_INSUFFICIENT_STORAGE => 'Insufficient Storage', // RFC 4918 - self::STATUS_LOOP_DETECTED => 'Loop Detected', // RFC 5842 - self::STATUS_BANDWIDTH_LIMIT_EXCEEDED => 'Bandwidth Limit Exceeded', // non-standard - self::STATUS_NOT_EXTENDED => 'Not extended', - self::STATUS_NETWORK_AUTHENTICATION_REQUIRED => 'Network Authentication Required', // draft-nottingham-http-new-status - ); - } - - - /** - * Gets the correct header - * @param Http::CONSTANT $status the constant from the Http class - * @param \DateTime $lastModified formatted last modified date - * @param string $ETag the etag - * @return string - */ - public function getStatusHeader($status, \DateTime $lastModified=null, - $ETag=null) { - - if(!is_null($lastModified)) { - $lastModified = $lastModified->format(\DateTime::RFC2822); - } - - // if etag or lastmodified have not changed, return a not modified - if ((isset($this->server['HTTP_IF_NONE_MATCH']) - && trim(trim($this->server['HTTP_IF_NONE_MATCH']), '"') === (string)$ETag) - - || - - (isset($this->server['HTTP_IF_MODIFIED_SINCE']) - && trim($this->server['HTTP_IF_MODIFIED_SINCE']) === - $lastModified)) { - - $status = self::STATUS_NOT_MODIFIED; - } - - // we have one change currently for the http 1.0 header that differs - // from 1.1: STATUS_TEMPORARY_REDIRECT should be STATUS_FOUND - // if this differs any more, we want to create childclasses for this - if($status === self::STATUS_TEMPORARY_REDIRECT - && $this->protocolVersion === 'HTTP/1.0') { - - $status = self::STATUS_FOUND; - } - - return $this->protocolVersion . ' ' . $status . ' ' . - $this->headers[$status]; - } - - -} - - diff --git a/lib/private/appframework/http/dispatcher.php b/lib/private/appframework/http/dispatcher.php deleted file mode 100644 index 641339c0d94..00000000000 --- a/lib/private/appframework/http/dispatcher.php +++ /dev/null @@ -1,179 +0,0 @@ -<?php -/** - * @author Bernhard Posselt <dev@bernhard-posselt.com> - * @author Georg Ehrke <georg@owncloud.com> - * @author Lukas Reschke <lukas@owncloud.com> - * @author Morris Jobke <hey@morrisjobke.de> - * @author Thomas Müller <thomas.mueller@tmit.eu> - * @author Thomas Tanghus <thomas@tanghus.net> - * - * @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 <http://www.gnu.org/licenses/> - * - */ - - -namespace OC\AppFramework\Http; - -use \OC\AppFramework\Middleware\MiddlewareDispatcher; -use \OC\AppFramework\Http; -use \OC\AppFramework\Utility\ControllerMethodReflector; - -use OCP\AppFramework\Controller; -use OCP\AppFramework\Http\Response; -use OCP\AppFramework\Http\DataResponse; -use OCP\IRequest; - - -/** - * Class to dispatch the request to the middleware dispatcher - */ -class Dispatcher { - - private $middlewareDispatcher; - private $protocol; - private $reflector; - private $request; - - /** - * @param Http $protocol the http protocol with contains all status headers - * @param MiddlewareDispatcher $middlewareDispatcher the dispatcher which - * runs the middleware - * @param ControllerMethodReflector $reflector the reflector that is used to inject - * the arguments for the controller - * @param IRequest $request the incoming request - */ - public function __construct(Http $protocol, - MiddlewareDispatcher $middlewareDispatcher, - ControllerMethodReflector $reflector, - IRequest $request) { - $this->protocol = $protocol; - $this->middlewareDispatcher = $middlewareDispatcher; - $this->reflector = $reflector; - $this->request = $request; - } - - - /** - * Handles a request and calls the dispatcher on the controller - * @param Controller $controller the controller which will be called - * @param string $methodName the method name which will be called on - * the controller - * @return array $array[0] contains a string with the http main header, - * $array[1] contains headers in the form: $key => value, $array[2] contains - * the response output - * @throws \Exception - */ - public function dispatch(Controller $controller, $methodName) { - $out = array(null, array(), null); - - try { - // prefill reflector with everything thats needed for the - // middlewares - $this->reflector->reflect($controller, $methodName); - - $this->middlewareDispatcher->beforeController($controller, - $methodName); - $response = $this->executeController($controller, $methodName); - - // if an exception appears, the middleware checks if it can handle the - // exception and creates a response. If no response is created, it is - // assumed that theres no middleware who can handle it and the error is - // thrown again - } catch(\Exception $exception){ - $response = $this->middlewareDispatcher->afterException( - $controller, $methodName, $exception); - if (is_null($response)) { - throw $exception; - } - } - - $response = $this->middlewareDispatcher->afterController( - $controller, $methodName, $response); - - // depending on the cache object the headers need to be changed - $out[0] = $this->protocol->getStatusHeader($response->getStatus(), - $response->getLastModified(), $response->getETag()); - $out[1] = array_merge($response->getHeaders()); - $out[2] = $response->getCookies(); - $out[3] = $this->middlewareDispatcher->beforeOutput( - $controller, $methodName, $response->render() - ); - $out[4] = $response; - - return $out; - } - - - /** - * Uses the reflected parameters, types and request parameters to execute - * the controller - * @param Controller $controller the controller to be executed - * @param string $methodName the method on the controller that should be executed - * @return Response - */ - private function executeController($controller, $methodName) { - $arguments = array(); - - // valid types that will be casted - $types = array('int', 'integer', 'bool', 'boolean', 'float'); - - foreach($this->reflector->getParameters() as $param => $default) { - - // try to get the parameter from the request object and cast - // it to the type annotated in the @param annotation - $value = $this->request->getParam($param, $default); - $type = $this->reflector->getType($param); - - // if this is submitted using GET or a POST form, 'false' should be - // converted to false - if(($type === 'bool' || $type === 'boolean') && - $value === 'false' && - ( - $this->request->method === 'GET' || - strpos($this->request->getHeader('Content-Type'), - 'application/x-www-form-urlencoded') !== false - ) - ) { - $value = false; - - } elseif($value !== null && in_array($type, $types)) { - settype($value, $type); - } - - $arguments[] = $value; - } - - $response = call_user_func_array(array($controller, $methodName), $arguments); - - // format response - if($response instanceof DataResponse || !($response instanceof Response)) { - - // get format from the url format or request format parameter - $format = $this->request->getParam('format'); - - // if none is given try the first Accept header - if($format === null) { - $headers = $this->request->getHeader('Accept'); - $format = $controller->getResponderByHTTPHeader($headers); - } - - $response = $controller->buildResponse($response, $format); - } - - return $response; - } - -} diff --git a/lib/private/appframework/http/output.php b/lib/private/appframework/http/output.php deleted file mode 100644 index 469c809c21c..00000000000 --- a/lib/private/appframework/http/output.php +++ /dev/null @@ -1,92 +0,0 @@ -<?php -/** - * @author Bernhard Posselt <dev@bernhard-posselt.com> - * @author Lukas Reschke <lukas@owncloud.com> - * - * @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 <http://www.gnu.org/licenses/> - * - */ - -namespace OC\AppFramework\Http; - -use OCP\AppFramework\Http\IOutput; - -/** - * Very thin wrapper class to make output testable - */ -class Output implements IOutput { - /** @var string */ - private $webRoot; - - /** - * @param $webRoot - */ - public function __construct($webRoot) { - $this->webRoot = $webRoot; - } - - /** - * @param string $out - */ - public function setOutput($out) { - print($out); - } - - /** - * @param string $path - * - * @return bool false if an error occurred - */ - public function setReadfile($path) { - return @readfile($path); - } - - /** - * @param string $header - */ - public function setHeader($header) { - header($header); - } - - /** - * @param int $code sets the http status code - */ - public function setHttpResponseCode($code) { - http_response_code($code); - } - - /** - * @return int returns the current http response code - */ - public function getHttpResponseCode() { - return http_response_code(); - } - - /** - * @param string $name - * @param string $value - * @param int $expire - * @param string $path - * @param string $domain - * @param bool $secure - * @param bool $httpOnly - */ - public function setCookie($name, $value, $expire, $path, $domain, $secure, $httpOnly) { - $path = $this->webRoot ? : '/'; - setcookie($name, $value, $expire, $path, $domain, $secure, $httpOnly); - } - -} diff --git a/lib/private/appframework/http/request.php b/lib/private/appframework/http/request.php deleted file mode 100644 index 7cd8cedcfdd..00000000000 --- a/lib/private/appframework/http/request.php +++ /dev/null @@ -1,771 +0,0 @@ -<?php -/** - * @author Bart Visscher <bartv@thisnet.nl> - * @author Bernhard Posselt <dev@bernhard-posselt.com> - * @author Joas Schilling <nickvergessen@owncloud.com> - * @author Jörn Friedrich Dreyer <jfd@butonic.de> - * @author Lukas Reschke <lukas@owncloud.com> - * @author Mitar <mitar.git@tnode.com> - * @author Morris Jobke <hey@morrisjobke.de> - * @author Robin Appelman <icewind@owncloud.com> - * @author Robin McCorkell <robin@mccorkell.me.uk> - * @author Roeland Jago Douma <rullzer@owncloud.com> - * @author Thomas Müller <thomas.mueller@tmit.eu> - * @author Thomas Tanghus <thomas@tanghus.net> - * @author Vincent Petry <pvince81@owncloud.com> - * - * @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 <http://www.gnu.org/licenses/> - * - */ - -namespace OC\AppFramework\Http; - -use OC\Security\CSRF\CsrfToken; -use OC\Security\CSRF\CsrfTokenManager; -use OC\Security\TrustedDomainHelper; -use OCP\IConfig; -use OCP\IRequest; -use OCP\Security\ICrypto; -use OCP\Security\ISecureRandom; - -/** - * Class for accessing variables in the request. - * This class provides an immutable object with request variables. - * - * @property mixed[] cookies - * @property mixed[] env - * @property mixed[] files - * @property string method - * @property mixed[] parameters - * @property mixed[] server - */ -class Request implements \ArrayAccess, \Countable, IRequest { - - const USER_AGENT_IE = '/(MSIE)|(Trident)/'; - const USER_AGENT_IE_8 = '/MSIE 8.0/'; - // Microsoft Edge User Agent from https://msdn.microsoft.com/en-us/library/hh869301(v=vs.85).aspx - const USER_AGENT_MS_EDGE = '/^Mozilla\/5\.0 \([^)]+\) AppleWebKit\/[0-9.]+ \(KHTML, like Gecko\) Chrome\/[0-9.]+ (Mobile Safari|Safari)\/[0-9.]+ Edge\/[0-9.]+$/'; - // Firefox User Agent from https://developer.mozilla.org/en-US/docs/Web/HTTP/Gecko_user_agent_string_reference - const USER_AGENT_FIREFOX = '/^Mozilla\/5\.0 \([^)]+\) Gecko\/[0-9.]+ Firefox\/[0-9.]+$/'; - // Chrome User Agent from https://developer.chrome.com/multidevice/user-agent - const USER_AGENT_CHROME = '/^Mozilla\/5\.0 \([^)]+\) AppleWebKit\/[0-9.]+ \(KHTML, like Gecko\) Chrome\/[0-9.]+ (Mobile Safari|Safari)\/[0-9.]+$/'; - // Safari User Agent from http://www.useragentstring.com/pages/Safari/ - const USER_AGENT_SAFARI = '/^Mozilla\/5\.0 \([^)]+\) AppleWebKit\/[0-9.]+ \(KHTML, like Gecko\) Version\/[0-9.]+ Safari\/[0-9.A-Z]+$/'; - // Android Chrome user agent: https://developers.google.com/chrome/mobile/docs/user-agent - const USER_AGENT_ANDROID_MOBILE_CHROME = '#Android.*Chrome/[.0-9]*#'; - const USER_AGENT_FREEBOX = '#^Mozilla/5\.0$#'; - const USER_AGENT_OWNCLOUD_IOS = '/^Mozilla\/5\.0 \(iOS\) ownCloud\-iOS.*$/'; - const USER_AGENT_OWNCLOUD_ANDROID = '/^Mozilla\/5\.0 \(Android\) ownCloud\-android.*$/'; - const USER_AGENT_OWNCLOUD_DESKTOP = '/^Mozilla\/5\.0 \([A-Za-z ]+\) (mirall|csyncoC)\/.*$/'; - const REGEX_LOCALHOST = '/^(127\.0\.0\.1|localhost)$/'; - - protected $inputStream; - protected $content; - protected $items = array(); - protected $allowedKeys = array( - 'get', - 'post', - 'files', - 'server', - 'env', - 'cookies', - 'urlParams', - 'parameters', - 'method', - 'requesttoken', - ); - /** @var ISecureRandom */ - protected $secureRandom; - /** @var IConfig */ - protected $config; - /** @var string */ - protected $requestId = ''; - /** @var ICrypto */ - protected $crypto; - /** @var CsrfTokenManager|null */ - protected $csrfTokenManager; - - /** @var bool */ - protected $contentDecoded = false; - - /** - * @param array $vars An associative array with the following optional values: - * - array 'urlParams' the parameters which were matched from the URL - * - array 'get' the $_GET array - * - array|string 'post' the $_POST array or JSON string - * - array 'files' the $_FILES array - * - array 'server' the $_SERVER array - * - array 'env' the $_ENV array - * - array 'cookies' the $_COOKIE array - * - string 'method' the request method (GET, POST etc) - * - string|false 'requesttoken' the requesttoken or false when not available - * @param ISecureRandom $secureRandom - * @param IConfig $config - * @param CsrfTokenManager|null $csrfTokenManager - * @param string $stream - * @see http://www.php.net/manual/en/reserved.variables.php - */ - public function __construct(array $vars=array(), - ISecureRandom $secureRandom = null, - IConfig $config, - CsrfTokenManager $csrfTokenManager = null, - $stream = 'php://input') { - $this->inputStream = $stream; - $this->items['params'] = array(); - $this->secureRandom = $secureRandom; - $this->config = $config; - $this->csrfTokenManager = $csrfTokenManager; - - if(!array_key_exists('method', $vars)) { - $vars['method'] = 'GET'; - } - - foreach($this->allowedKeys as $name) { - $this->items[$name] = isset($vars[$name]) - ? $vars[$name] - : array(); - } - - $this->items['parameters'] = array_merge( - $this->items['get'], - $this->items['post'], - $this->items['urlParams'], - $this->items['params'] - ); - - } - /** - * @param array $parameters - */ - public function setUrlParameters(array $parameters) { - $this->items['urlParams'] = $parameters; - $this->items['parameters'] = array_merge( - $this->items['parameters'], - $this->items['urlParams'] - ); - } - - /** - * Countable method - * @return int - */ - public function count() { - return count(array_keys($this->items['parameters'])); - } - - /** - * ArrayAccess methods - * - * Gives access to the combined GET, POST and urlParams arrays - * - * Examples: - * - * $var = $request['myvar']; - * - * or - * - * if(!isset($request['myvar']) { - * // Do something - * } - * - * $request['myvar'] = 'something'; // This throws an exception. - * - * @param string $offset The key to lookup - * @return boolean - */ - public function offsetExists($offset) { - return isset($this->items['parameters'][$offset]); - } - - /** - * @see offsetExists - */ - public function offsetGet($offset) { - return isset($this->items['parameters'][$offset]) - ? $this->items['parameters'][$offset] - : null; - } - - /** - * @see offsetExists - */ - public function offsetSet($offset, $value) { - throw new \RuntimeException('You cannot change the contents of the request object'); - } - - /** - * @see offsetExists - */ - public function offsetUnset($offset) { - throw new \RuntimeException('You cannot change the contents of the request object'); - } - - /** - * Magic property accessors - * @param string $name - * @param mixed $value - */ - public function __set($name, $value) { - throw new \RuntimeException('You cannot change the contents of the request object'); - } - - /** - * Access request variables by method and name. - * Examples: - * - * $request->post['myvar']; // Only look for POST variables - * $request->myvar; or $request->{'myvar'}; or $request->{$myvar} - * Looks in the combined GET, POST and urlParams array. - * - * If you access e.g. ->post but the current HTTP request method - * is GET a \LogicException will be thrown. - * - * @param string $name The key to look for. - * @throws \LogicException - * @return mixed|null - */ - public function __get($name) { - switch($name) { - case 'put': - case 'patch': - case 'get': - case 'post': - if($this->method !== strtoupper($name)) { - throw new \LogicException(sprintf('%s cannot be accessed in a %s request.', $name, $this->method)); - } - return $this->getContent(); - case 'files': - case 'server': - case 'env': - case 'cookies': - case 'urlParams': - case 'method': - return isset($this->items[$name]) - ? $this->items[$name] - : null; - case 'parameters': - case 'params': - return $this->getContent(); - default; - return isset($this[$name]) - ? $this[$name] - : null; - } - } - - /** - * @param string $name - * @return bool - */ - public function __isset($name) { - return isset($this->items['parameters'][$name]); - } - - /** - * @param string $id - */ - public function __unset($id) { - throw new \RuntimeException('You cannot change the contents of the request object'); - } - - /** - * Returns the value for a specific http header. - * - * This method returns null if the header did not exist. - * - * @param string $name - * @return string - */ - public function getHeader($name) { - - $name = strtoupper(str_replace(array('-'),array('_'),$name)); - if (isset($this->server['HTTP_' . $name])) { - return $this->server['HTTP_' . $name]; - } - - // There's a few headers that seem to end up in the top-level - // server array. - switch($name) { - case 'CONTENT_TYPE' : - case 'CONTENT_LENGTH' : - if (isset($this->server[$name])) { - return $this->server[$name]; - } - break; - - } - - return null; - } - - /** - * Lets you access post and get parameters by the index - * In case of json requests the encoded json body is accessed - * - * @param string $key the key which you want to access in the URL Parameter - * placeholder, $_POST or $_GET array. - * The priority how they're returned is the following: - * 1. URL parameters - * 2. POST parameters - * 3. GET parameters - * @param mixed $default If the key is not found, this value will be returned - * @return mixed the content of the array - */ - public function getParam($key, $default = null) { - return isset($this->parameters[$key]) - ? $this->parameters[$key] - : $default; - } - - /** - * Returns all params that were received, be it from the request - * (as GET or POST) or throuh the URL by the route - * @return array the array with all parameters - */ - public function getParams() { - return $this->parameters; - } - - /** - * Returns the method of the request - * @return string the method of the request (POST, GET, etc) - */ - public function getMethod() { - return $this->method; - } - - /** - * Shortcut for accessing an uploaded file through the $_FILES array - * @param string $key the key that will be taken from the $_FILES array - * @return array the file in the $_FILES element - */ - public function getUploadedFile($key) { - return isset($this->files[$key]) ? $this->files[$key] : null; - } - - /** - * Shortcut for getting env variables - * @param string $key the key that will be taken from the $_ENV array - * @return array the value in the $_ENV element - */ - public function getEnv($key) { - return isset($this->env[$key]) ? $this->env[$key] : null; - } - - /** - * Shortcut for getting cookie variables - * @param string $key the key that will be taken from the $_COOKIE array - * @return string the value in the $_COOKIE element - */ - public function getCookie($key) { - return isset($this->cookies[$key]) ? $this->cookies[$key] : null; - } - - /** - * Returns the request body content. - * - * If the HTTP request method is PUT and the body - * not application/x-www-form-urlencoded or application/json a stream - * resource is returned, otherwise an array. - * - * @return array|string|resource The request body content or a resource to read the body stream. - * - * @throws \LogicException - */ - protected function getContent() { - // If the content can't be parsed into an array then return a stream resource. - if ($this->method === 'PUT' - && strpos($this->getHeader('Content-Type'), 'application/x-www-form-urlencoded') === false - && strpos($this->getHeader('Content-Type'), 'application/json') === false - ) { - if ($this->content === false) { - throw new \LogicException( - '"put" can only be accessed once if not ' - . 'application/x-www-form-urlencoded or application/json.' - ); - } - $this->content = false; - return fopen($this->inputStream, 'rb'); - } else { - $this->decodeContent(); - return $this->items['parameters']; - } - } - - /** - * Attempt to decode the content and populate parameters - */ - protected function decodeContent() { - if ($this->contentDecoded) { - return; - } - $params = []; - - // 'application/json' must be decoded manually. - if (strpos($this->getHeader('Content-Type'), 'application/json') !== false) { - $params = json_decode(file_get_contents($this->inputStream), true); - if(count($params) > 0) { - $this->items['params'] = $params; - if($this->method === 'POST') { - $this->items['post'] = $params; - } - } - - // Handle application/x-www-form-urlencoded for methods other than GET - // or post correctly - } elseif($this->method !== 'GET' - && $this->method !== 'POST' - && strpos($this->getHeader('Content-Type'), 'application/x-www-form-urlencoded') !== false) { - - parse_str(file_get_contents($this->inputStream), $params); - if(is_array($params)) { - $this->items['params'] = $params; - } - } - - if (is_array($params)) { - $this->items['parameters'] = array_merge($this->items['parameters'], $params); - } - $this->contentDecoded = true; - } - - - /** - * Checks if the CSRF check was correct - * @return bool true if CSRF check passed - */ - public function passesCSRFCheck() { - if($this->csrfTokenManager === null) { - return false; - } - - if (isset($this->items['get']['requesttoken'])) { - $token = $this->items['get']['requesttoken']; - } elseif (isset($this->items['post']['requesttoken'])) { - $token = $this->items['post']['requesttoken']; - } elseif (isset($this->items['server']['HTTP_REQUESTTOKEN'])) { - $token = $this->items['server']['HTTP_REQUESTTOKEN']; - } else { - //no token found. - return false; - } - $token = new CsrfToken($token); - - return $this->csrfTokenManager->isTokenValid($token); - } - - /** - * Returns an ID for the request, value is not guaranteed to be unique and is mostly meant for logging - * If `mod_unique_id` is installed this value will be taken. - * @return string - */ - public function getId() { - if(isset($this->server['UNIQUE_ID'])) { - return $this->server['UNIQUE_ID']; - } - - if(empty($this->requestId)) { - $this->requestId = $this->secureRandom->generate(20); - } - - return $this->requestId; - } - - /** - * Returns the remote address, if the connection came from a trusted proxy - * and `forwarded_for_headers` has been configured then the IP address - * specified in this header will be returned instead. - * Do always use this instead of $_SERVER['REMOTE_ADDR'] - * @return string IP address - */ - public function getRemoteAddress() { - $remoteAddress = isset($this->server['REMOTE_ADDR']) ? $this->server['REMOTE_ADDR'] : ''; - $trustedProxies = $this->config->getSystemValue('trusted_proxies', []); - - if(is_array($trustedProxies) && in_array($remoteAddress, $trustedProxies)) { - $forwardedForHeaders = $this->config->getSystemValue('forwarded_for_headers', [ - 'HTTP_X_FORWARDED_FOR' - // only have one default, so we cannot ship an insecure product out of the box - ]); - - foreach($forwardedForHeaders as $header) { - if(isset($this->server[$header])) { - foreach(explode(',', $this->server[$header]) as $IP) { - $IP = trim($IP); - if (filter_var($IP, FILTER_VALIDATE_IP) !== false) { - return $IP; - } - } - } - } - } - - return $remoteAddress; - } - - /** - * Check overwrite condition - * @param string $type - * @return bool - */ - private function isOverwriteCondition($type = '') { - $regex = '/' . $this->config->getSystemValue('overwritecondaddr', '') . '/'; - $remoteAddr = isset($this->server['REMOTE_ADDR']) ? $this->server['REMOTE_ADDR'] : ''; - return $regex === '//' || preg_match($regex, $remoteAddr) === 1 - || $type !== 'protocol'; - } - - /** - * Returns the server protocol. It respects one or more reverse proxies servers - * and load balancers - * @return string Server protocol (http or https) - */ - public function getServerProtocol() { - if($this->config->getSystemValue('overwriteprotocol') !== '' - && $this->isOverwriteCondition('protocol')) { - return $this->config->getSystemValue('overwriteprotocol'); - } - - if (isset($this->server['HTTP_X_FORWARDED_PROTO'])) { - if (strpos($this->server['HTTP_X_FORWARDED_PROTO'], ',') !== false) { - $parts = explode(',', $this->server['HTTP_X_FORWARDED_PROTO']); - $proto = strtolower(trim($parts[0])); - } else { - $proto = strtolower($this->server['HTTP_X_FORWARDED_PROTO']); - } - - // Verify that the protocol is always HTTP or HTTPS - // default to http if an invalid value is provided - return $proto === 'https' ? 'https' : 'http'; - } - - if (isset($this->server['HTTPS']) - && $this->server['HTTPS'] !== null - && $this->server['HTTPS'] !== 'off' - && $this->server['HTTPS'] !== '') { - return 'https'; - } - - return 'http'; - } - - /** - * Returns the used HTTP protocol. - * - * @return string HTTP protocol. HTTP/2, HTTP/1.1 or HTTP/1.0. - */ - public function getHttpProtocol() { - $claimedProtocol = strtoupper($this->server['SERVER_PROTOCOL']); - - $validProtocols = [ - 'HTTP/1.0', - 'HTTP/1.1', - 'HTTP/2', - ]; - - if(in_array($claimedProtocol, $validProtocols, true)) { - return $claimedProtocol; - } - - return 'HTTP/1.1'; - } - - /** - * Returns the request uri, even if the website uses one or more - * reverse proxies - * @return string - */ - public function getRequestUri() { - $uri = isset($this->server['REQUEST_URI']) ? $this->server['REQUEST_URI'] : ''; - if($this->config->getSystemValue('overwritewebroot') !== '' && $this->isOverwriteCondition()) { - $uri = $this->getScriptName() . substr($uri, strlen($this->server['SCRIPT_NAME'])); - } - return $uri; - } - - /** - * Get raw PathInfo from request (not urldecoded) - * @throws \Exception - * @return string Path info - */ - public function getRawPathInfo() { - $requestUri = isset($this->server['REQUEST_URI']) ? $this->server['REQUEST_URI'] : ''; - // remove too many leading slashes - can be caused by reverse proxy configuration - if (strpos($requestUri, '/') === 0) { - $requestUri = '/' . ltrim($requestUri, '/'); - } - - $requestUri = preg_replace('%/{2,}%', '/', $requestUri); - - // Remove the query string from REQUEST_URI - if ($pos = strpos($requestUri, '?')) { - $requestUri = substr($requestUri, 0, $pos); - } - - $scriptName = $this->server['SCRIPT_NAME']; - $pathInfo = $requestUri; - - // strip off the script name's dir and file name - // FIXME: Sabre does not really belong here - list($path, $name) = \Sabre\HTTP\URLUtil::splitPath($scriptName); - if (!empty($path)) { - if($path === $pathInfo || strpos($pathInfo, $path.'/') === 0) { - $pathInfo = substr($pathInfo, strlen($path)); - } else { - throw new \Exception("The requested uri($requestUri) cannot be processed by the script '$scriptName')"); - } - } - if (strpos($pathInfo, '/'.$name) === 0) { - $pathInfo = substr($pathInfo, strlen($name) + 1); - } - if (strpos($pathInfo, $name) === 0) { - $pathInfo = substr($pathInfo, strlen($name)); - } - if($pathInfo === false || $pathInfo === '/'){ - return ''; - } else { - return $pathInfo; - } - } - - /** - * Get PathInfo from request - * @throws \Exception - * @return string|false Path info or false when not found - */ - public function getPathInfo() { - if(isset($this->server['PATH_INFO'])) { - return $this->server['PATH_INFO']; - } - - $pathInfo = $this->getRawPathInfo(); - // following is taken from \Sabre\HTTP\URLUtil::decodePathSegment - $pathInfo = rawurldecode($pathInfo); - $encoding = mb_detect_encoding($pathInfo, ['UTF-8', 'ISO-8859-1']); - - switch($encoding) { - case 'ISO-8859-1' : - $pathInfo = utf8_encode($pathInfo); - } - // end copy - - return $pathInfo; - } - - /** - * Returns the script name, even if the website uses one or more - * reverse proxies - * @return string the script name - */ - public function getScriptName() { - $name = $this->server['SCRIPT_NAME']; - $overwriteWebRoot = $this->config->getSystemValue('overwritewebroot'); - if ($overwriteWebRoot !== '' && $this->isOverwriteCondition()) { - // FIXME: This code is untestable due to __DIR__, also that hardcoded path is really dangerous - $serverRoot = str_replace('\\', '/', substr(__DIR__, 0, -strlen('lib/private/appframework/http/'))); - $suburi = str_replace('\\', '/', substr(realpath($this->server['SCRIPT_FILENAME']), strlen($serverRoot))); - $name = '/' . ltrim($overwriteWebRoot . $suburi, '/'); - } - return $name; - } - - /** - * Checks whether the user agent matches a given regex - * @param array $agent array of agent names - * @return bool true if at least one of the given agent matches, false otherwise - */ - public function isUserAgent(array $agent) { - if (!isset($this->server['HTTP_USER_AGENT'])) { - return false; - } - foreach ($agent as $regex) { - if (preg_match($regex, $this->server['HTTP_USER_AGENT'])) { - return true; - } - } - return false; - } - - /** - * Returns the unverified server host from the headers without checking - * whether it is a trusted domain - * @return string Server host - */ - public function getInsecureServerHost() { - $host = 'localhost'; - if (isset($this->server['HTTP_X_FORWARDED_HOST'])) { - if (strpos($this->server['HTTP_X_FORWARDED_HOST'], ',') !== false) { - $parts = explode(',', $this->server['HTTP_X_FORWARDED_HOST']); - $host = trim(current($parts)); - } else { - $host = $this->server['HTTP_X_FORWARDED_HOST']; - } - } else { - if (isset($this->server['HTTP_HOST'])) { - $host = $this->server['HTTP_HOST']; - } else if (isset($this->server['SERVER_NAME'])) { - $host = $this->server['SERVER_NAME']; - } - } - return $host; - } - - - /** - * Returns the server host from the headers, or the first configured - * trusted domain if the host isn't in the trusted list - * @return string Server host - */ - public function getServerHost() { - // overwritehost is always trusted - $host = $this->getOverwriteHost(); - if ($host !== null) { - return $host; - } - - // get the host from the headers - $host = $this->getInsecureServerHost(); - - // Verify that the host is a trusted domain if the trusted domains - // are defined - // If no trusted domain is provided the first trusted domain is returned - $trustedDomainHelper = new TrustedDomainHelper($this->config); - if ($trustedDomainHelper->isTrustedDomain($host)) { - return $host; - } else { - $trustedList = $this->config->getSystemValue('trusted_domains', []); - if(!empty($trustedList)) { - return $trustedList[0]; - } else { - return ''; - } - } - } - - /** - * Returns the overwritehost setting from the config if set and - * if the overwrite condition is met - * @return string|null overwritehost value or null if not defined or the defined condition - * isn't met - */ - private function getOverwriteHost() { - if($this->config->getSystemValue('overwritehost') !== '' && $this->isOverwriteCondition()) { - return $this->config->getSystemValue('overwritehost'); - } - return null; - } - -} diff --git a/lib/private/appframework/middleware/middlewaredispatcher.php b/lib/private/appframework/middleware/middlewaredispatcher.php deleted file mode 100644 index 4bd25f79bba..00000000000 --- a/lib/private/appframework/middleware/middlewaredispatcher.php +++ /dev/null @@ -1,162 +0,0 @@ -<?php -/** - * @author Jörn Friedrich Dreyer <jfd@butonic.de> - * @author Lukas Reschke <lukas@owncloud.com> - * @author Morris Jobke <hey@morrisjobke.de> - * @author Thomas Müller <thomas.mueller@tmit.eu> - * @author Thomas Tanghus <thomas@tanghus.net> - * - * @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 <http://www.gnu.org/licenses/> - * - */ - - -namespace OC\AppFramework\Middleware; - -use OCP\AppFramework\Controller; -use OCP\AppFramework\Http\Response; -use OCP\AppFramework\MiddleWare; - -/** - * This class is used to store and run all the middleware in correct order - */ -class MiddlewareDispatcher { - - /** - * @var array array containing all the middlewares - */ - private $middlewares; - - /** - * @var int counter which tells us what middlware was executed once an - * exception occurs - */ - private $middlewareCounter; - - - /** - * Constructor - */ - public function __construct(){ - $this->middlewares = array(); - $this->middlewareCounter = 0; - } - - - /** - * Adds a new middleware - * @param Middleware $middleWare the middleware which will be added - */ - public function registerMiddleware(Middleware $middleWare){ - array_push($this->middlewares, $middleWare); - } - - - /** - * returns an array with all middleware elements - * @return array the middlewares - */ - public function getMiddlewares(){ - return $this->middlewares; - } - - - /** - * This is being run in normal order before the controller is being - * called which allows several modifications and checks - * - * @param Controller $controller the controller that is being called - * @param string $methodName the name of the method that will be called on - * the controller - */ - public function beforeController(Controller $controller, $methodName){ - // we need to count so that we know which middlewares we have to ask in - // case there is an exception - $middlewareCount = count($this->middlewares); - for($i = 0; $i < $middlewareCount; $i++){ - $this->middlewareCounter++; - $middleware = $this->middlewares[$i]; - $middleware->beforeController($controller, $methodName); - } - } - - - /** - * This is being run when either the beforeController method or the - * controller method itself is throwing an exception. The middleware is asked - * in reverse order to handle the exception and to return a response. - * If the response is null, it is assumed that the exception could not be - * handled and the error will be thrown again - * - * @param Controller $controller the controller that is being called - * @param string $methodName the name of the method that will be called on - * the controller - * @param \Exception $exception the thrown exception - * @return Response a Response object if the middleware can handle the - * exception - * @throws \Exception the passed in exception if it can't handle it - */ - public function afterException(Controller $controller, $methodName, \Exception $exception){ - for($i=$this->middlewareCounter-1; $i>=0; $i--){ - $middleware = $this->middlewares[$i]; - try { - return $middleware->afterException($controller, $methodName, $exception); - } catch(\Exception $exception){ - continue; - } - } - throw $exception; - } - - - /** - * This is being run after a successful controllermethod call and allows - * the manipulation of a Response object. The middleware is run in reverse order - * - * @param Controller $controller the controller that is being called - * @param string $methodName the name of the method that will be called on - * the controller - * @param Response $response the generated response from the controller - * @return Response a Response object - */ - public function afterController(Controller $controller, $methodName, Response $response){ - for($i=count($this->middlewares)-1; $i>=0; $i--){ - $middleware = $this->middlewares[$i]; - $response = $middleware->afterController($controller, $methodName, $response); - } - return $response; - } - - - /** - * This is being run after the response object has been rendered and - * allows the manipulation of the output. The middleware is run in reverse order - * - * @param Controller $controller the controller that is being called - * @param string $methodName the name of the method that will be called on - * the controller - * @param string $output the generated output from a response - * @return string the output that should be printed - */ - public function beforeOutput(Controller $controller, $methodName, $output){ - for($i=count($this->middlewares)-1; $i>=0; $i--){ - $middleware = $this->middlewares[$i]; - $output = $middleware->beforeOutput($controller, $methodName, $output); - } - return $output; - } - -} diff --git a/lib/private/appframework/middleware/security/corsmiddleware.php b/lib/private/appframework/middleware/security/corsmiddleware.php deleted file mode 100644 index 258119b326a..00000000000 --- a/lib/private/appframework/middleware/security/corsmiddleware.php +++ /dev/null @@ -1,155 +0,0 @@ -<?php -/** - * @author Bernhard Posselt <dev@bernhard-posselt.com> - * @author Lukas Reschke <lukas@owncloud.com> - * @author Morris Jobke <hey@morrisjobke.de> - * - * @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 <http://www.gnu.org/licenses/> - * - */ - -namespace OC\AppFramework\Middleware\Security; - -use OC\AppFramework\Middleware\Security\Exceptions\SecurityException; -use OC\AppFramework\Utility\ControllerMethodReflector; -use OCP\AppFramework\Controller; -use OCP\AppFramework\Http; -use OCP\AppFramework\Http\JSONResponse; -use OCP\IRequest; -use OCP\IUserSession; -use OCP\AppFramework\Http\Response; -use OCP\AppFramework\Middleware; - -/** - * This middleware sets the correct CORS headers on a response if the - * controller has the @CORS annotation. This is needed for webapps that want - * to access an API and don't run on the same domain, see - * https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS - */ -class CORSMiddleware extends Middleware { - - /** - * @var IRequest - */ - private $request; - - /** - * @var ControllerMethodReflector - */ - private $reflector; - - /** - * @var IUserSession - */ - private $session; - - /** - * @param IRequest $request - * @param ControllerMethodReflector $reflector - * @param IUserSession $session - */ - public function __construct(IRequest $request, - ControllerMethodReflector $reflector, - IUserSession $session) { - $this->request = $request; - $this->reflector = $reflector; - $this->session = $session; - } - - /** - * This is being run in normal order before the controller is being - * called which allows several modifications and checks - * - * @param Controller $controller the controller that is being called - * @param string $methodName the name of the method that will be called on - * the controller - * @throws SecurityException - * @since 6.0.0 - */ - public function beforeController($controller, $methodName){ - // ensure that @CORS annotated API routes are not used in conjunction - // with session authentication since this enables CSRF attack vectors - if ($this->reflector->hasAnnotation('CORS') && - !$this->reflector->hasAnnotation('PublicPage')) { - $user = $this->request->server['PHP_AUTH_USER']; - $pass = $this->request->server['PHP_AUTH_PW']; - - $this->session->logout(); - if(!$this->session->login($user, $pass)) { - throw new SecurityException('CORS requires basic auth', Http::STATUS_UNAUTHORIZED); - } - } - } - - /** - * This is being run after a successful controllermethod call and allows - * the manipulation of a Response object. The middleware is run in reverse order - * - * @param Controller $controller the controller that is being called - * @param string $methodName the name of the method that will be called on - * the controller - * @param Response $response the generated response from the controller - * @return Response a Response object - * @throws SecurityException - */ - public function afterController($controller, $methodName, Response $response){ - // only react if its a CORS request and if the request sends origin and - - if(isset($this->request->server['HTTP_ORIGIN']) && - $this->reflector->hasAnnotation('CORS')) { - - // allow credentials headers must not be true or CSRF is possible - // otherwise - foreach($response->getHeaders() as $header => $value) { - if(strtolower($header) === 'access-control-allow-credentials' && - strtolower(trim($value)) === 'true') { - $msg = 'Access-Control-Allow-Credentials must not be '. - 'set to true in order to prevent CSRF'; - throw new SecurityException($msg); - } - } - - $origin = $this->request->server['HTTP_ORIGIN']; - $response->addHeader('Access-Control-Allow-Origin', $origin); - } - return $response; - } - - /** - * If an SecurityException is being caught return a JSON error response - * - * @param Controller $controller the controller that is being called - * @param string $methodName the name of the method that will be called on - * the controller - * @param \Exception $exception the thrown exception - * @throws \Exception the passed in exception if it can't handle it - * @return Response a Response object or null in case that the exception could not be handled - */ - public function afterException($controller, $methodName, \Exception $exception){ - if($exception instanceof SecurityException){ - $response = new JSONResponse(['message' => $exception->getMessage()]); - if($exception->getCode() !== 0) { - $response->setStatus($exception->getCode()); - } else { - $response->setStatus(Http::STATUS_INTERNAL_SERVER_ERROR); - } - return $response; - } - - throw $exception; - } - -} diff --git a/lib/private/appframework/middleware/security/exceptions/appnotenabledexception.php b/lib/private/appframework/middleware/security/exceptions/appnotenabledexception.php deleted file mode 100644 index 59e247f3307..00000000000 --- a/lib/private/appframework/middleware/security/exceptions/appnotenabledexception.php +++ /dev/null @@ -1,38 +0,0 @@ -<?php -/** - * @author Lukas Reschke <lukas@owncloud.com> - * @author Morris Jobke <hey@morrisjobke.de> - * @author Thomas Müller <thomas.mueller@tmit.eu> - * - * @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 <http://www.gnu.org/licenses/> - * - */ - -namespace OC\Appframework\Middleware\Security\Exceptions; - -use OCP\AppFramework\Http; - -/** - * Class AppNotEnabledException is thrown when a resource for an application is - * requested that is not enabled. - * - * @package OC\Appframework\Middleware\Security\Exceptions - */ -class AppNotEnabledException extends SecurityException { - public function __construct() { - parent::__construct('App is not enabled', Http::STATUS_PRECONDITION_FAILED); - } -} diff --git a/lib/private/appframework/middleware/security/exceptions/crosssiterequestforgeryexception.php b/lib/private/appframework/middleware/security/exceptions/crosssiterequestforgeryexception.php deleted file mode 100644 index 0eeb81730d4..00000000000 --- a/lib/private/appframework/middleware/security/exceptions/crosssiterequestforgeryexception.php +++ /dev/null @@ -1,38 +0,0 @@ -<?php -/** - * @author Lukas Reschke <lukas@owncloud.com> - * @author Morris Jobke <hey@morrisjobke.de> - * @author Thomas Müller <thomas.mueller@tmit.eu> - * - * @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 <http://www.gnu.org/licenses/> - * - */ - -namespace OC\Appframework\Middleware\Security\Exceptions; - -use OCP\AppFramework\Http; - -/** - * Class CrossSiteRequestForgeryException is thrown when a CSRF exception has - * been encountered. - * - * @package OC\Appframework\Middleware\Security\Exceptions - */ -class CrossSiteRequestForgeryException extends SecurityException { - public function __construct() { - parent::__construct('CSRF check failed', Http::STATUS_PRECONDITION_FAILED); - } -} diff --git a/lib/private/appframework/middleware/security/exceptions/notadminexception.php b/lib/private/appframework/middleware/security/exceptions/notadminexception.php deleted file mode 100644 index be0f2f9d2a9..00000000000 --- a/lib/private/appframework/middleware/security/exceptions/notadminexception.php +++ /dev/null @@ -1,38 +0,0 @@ -<?php -/** - * @author Lukas Reschke <lukas@owncloud.com> - * @author Morris Jobke <hey@morrisjobke.de> - * @author Thomas Müller <thomas.mueller@tmit.eu> - * - * @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 <http://www.gnu.org/licenses/> - * - */ - -namespace OC\Appframework\Middleware\Security\Exceptions; - -use OCP\AppFramework\Http; - -/** - * Class NotAdminException is thrown when a resource has been requested by a - * non-admin user that is not accessible to non-admin users. - * - * @package OC\Appframework\Middleware\Security\Exceptions - */ -class NotAdminException extends SecurityException { - public function __construct() { - parent::__construct('Logged in user must be an admin', Http::STATUS_FORBIDDEN); - } -} diff --git a/lib/private/appframework/middleware/security/exceptions/notloggedinexception.php b/lib/private/appframework/middleware/security/exceptions/notloggedinexception.php deleted file mode 100644 index f5b2e032032..00000000000 --- a/lib/private/appframework/middleware/security/exceptions/notloggedinexception.php +++ /dev/null @@ -1,38 +0,0 @@ -<?php -/** - * @author Lukas Reschke <lukas@owncloud.com> - * @author Morris Jobke <hey@morrisjobke.de> - * @author Thomas Müller <thomas.mueller@tmit.eu> - * - * @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 <http://www.gnu.org/licenses/> - * - */ - -namespace OC\Appframework\Middleware\Security\Exceptions; - -use OCP\AppFramework\Http; - -/** - * Class NotLoggedInException is thrown when a resource has been requested by a - * guest user that is not accessible to the public. - * - * @package OC\Appframework\Middleware\Security\Exceptions - */ -class NotLoggedInException extends SecurityException { - public function __construct() { - parent::__construct('Current user is not logged in', Http::STATUS_UNAUTHORIZED); - } -} diff --git a/lib/private/appframework/middleware/security/exceptions/securityexception.php b/lib/private/appframework/middleware/security/exceptions/securityexception.php deleted file mode 100644 index c86614ec477..00000000000 --- a/lib/private/appframework/middleware/security/exceptions/securityexception.php +++ /dev/null @@ -1,32 +0,0 @@ -<?php -/** - * @author Lukas Reschke <lukas@owncloud.com> - * @author Morris Jobke <hey@morrisjobke.de> - * @author Thomas Müller <thomas.mueller@tmit.eu> - * - * @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 <http://www.gnu.org/licenses/> - * - */ - -namespace OC\AppFramework\Middleware\Security\Exceptions; - -/** - * Class SecurityException is the base class for security exceptions thrown by - * the security middleware. - * - * @package OC\AppFramework\Middleware\Security\Exceptions - */ -class SecurityException extends \Exception {} diff --git a/lib/private/appframework/middleware/security/securitymiddleware.php b/lib/private/appframework/middleware/security/securitymiddleware.php deleted file mode 100644 index 4afd29cd060..00000000000 --- a/lib/private/appframework/middleware/security/securitymiddleware.php +++ /dev/null @@ -1,215 +0,0 @@ -<?php -/** - * @author Bernhard Posselt <dev@bernhard-posselt.com> - * @author Lukas Reschke <lukas@owncloud.com> - * @author Morris Jobke <hey@morrisjobke.de> - * @author Thomas Müller <thomas.mueller@tmit.eu> - * @author Thomas Tanghus <thomas@tanghus.net> - * - * @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 <http://www.gnu.org/licenses/> - * - */ - - -namespace OC\AppFramework\Middleware\Security; - -use OC\Appframework\Middleware\Security\Exceptions\AppNotEnabledException; -use OC\Appframework\Middleware\Security\Exceptions\CrossSiteRequestForgeryException; -use OC\Appframework\Middleware\Security\Exceptions\NotAdminException; -use OC\Appframework\Middleware\Security\Exceptions\NotLoggedInException; -use OC\AppFramework\Utility\ControllerMethodReflector; -use OC\Security\CSP\ContentSecurityPolicyManager; -use OCP\AppFramework\Http\ContentSecurityPolicy; -use OCP\AppFramework\Http\RedirectResponse; -use OCP\AppFramework\Http\TemplateResponse; -use OCP\AppFramework\Middleware; -use OCP\AppFramework\Http\Response; -use OCP\AppFramework\Http\JSONResponse; -use OCP\INavigationManager; -use OCP\IURLGenerator; -use OCP\IRequest; -use OCP\ILogger; -use OCP\AppFramework\Controller; -use OCP\Util; -use OC\AppFramework\Middleware\Security\Exceptions\SecurityException; - -/** - * Used to do all the authentication and checking stuff for a controller method - * It reads out the annotations of a controller method and checks which if - * security things should be checked and also handles errors in case a security - * check fails - */ -class SecurityMiddleware extends Middleware { - /** @var INavigationManager */ - private $navigationManager; - /** @var IRequest */ - private $request; - /** @var ControllerMethodReflector */ - private $reflector; - /** @var string */ - private $appName; - /** @var IURLGenerator */ - private $urlGenerator; - /** @var ILogger */ - private $logger; - /** @var bool */ - private $isLoggedIn; - /** @var bool */ - private $isAdminUser; - /** @var ContentSecurityPolicyManager */ - private $contentSecurityPolicyManager; - - /** - * @param IRequest $request - * @param ControllerMethodReflector $reflector - * @param INavigationManager $navigationManager - * @param IURLGenerator $urlGenerator - * @param ILogger $logger - * @param string $appName - * @param bool $isLoggedIn - * @param bool $isAdminUser - * @param ContentSecurityPolicyManager $contentSecurityPolicyManager - */ - public function __construct(IRequest $request, - ControllerMethodReflector $reflector, - INavigationManager $navigationManager, - IURLGenerator $urlGenerator, - ILogger $logger, - $appName, - $isLoggedIn, - $isAdminUser, - ContentSecurityPolicyManager $contentSecurityPolicyManager) { - $this->navigationManager = $navigationManager; - $this->request = $request; - $this->reflector = $reflector; - $this->appName = $appName; - $this->urlGenerator = $urlGenerator; - $this->logger = $logger; - $this->isLoggedIn = $isLoggedIn; - $this->isAdminUser = $isAdminUser; - $this->contentSecurityPolicyManager = $contentSecurityPolicyManager; - } - - - /** - * This runs all the security checks before a method call. The - * security checks are determined by inspecting the controller method - * annotations - * @param string $controller the controllername or string - * @param string $methodName the name of the method - * @throws SecurityException when a security check fails - */ - public function beforeController($controller, $methodName) { - - // this will set the current navigation entry of the app, use this only - // for normal HTML requests and not for AJAX requests - $this->navigationManager->setActiveEntry($this->appName); - - // security checks - $isPublicPage = $this->reflector->hasAnnotation('PublicPage'); - if(!$isPublicPage) { - if(!$this->isLoggedIn) { - throw new NotLoggedInException(); - } - - if(!$this->reflector->hasAnnotation('NoAdminRequired')) { - if(!$this->isAdminUser) { - throw new NotAdminException(); - } - } - } - - // CSRF check - also registers the CSRF token since the session may be closed later - Util::callRegister(); - if(!$this->reflector->hasAnnotation('NoCSRFRequired')) { - if(!$this->request->passesCSRFCheck()) { - throw new CrossSiteRequestForgeryException(); - } - } - - /** - * FIXME: Use DI once available - * Checks if app is enabled (also includes a check whether user is allowed to access the resource) - * The getAppPath() check is here since components such as settings also use the AppFramework and - * therefore won't pass this check. - */ - if(\OC_App::getAppPath($this->appName) !== false && !\OC_App::isEnabled($this->appName)) { - throw new AppNotEnabledException(); - } - - } - - /** - * Performs the default CSP modifications that may be injected by other - * applications - * - * @param Controller $controller - * @param string $methodName - * @param Response $response - * @return Response - */ - public function afterController($controller, $methodName, Response $response) { - $policy = !is_null($response->getContentSecurityPolicy()) ? $response->getContentSecurityPolicy() : new ContentSecurityPolicy(); - - $defaultPolicy = $this->contentSecurityPolicyManager->getDefaultPolicy(); - $defaultPolicy = $this->contentSecurityPolicyManager->mergePolicies($defaultPolicy, $policy); - - $response->setContentSecurityPolicy($defaultPolicy); - - return $response; - } - - /** - * If an SecurityException is being caught, ajax requests return a JSON error - * response and non ajax requests redirect to the index - * @param Controller $controller the controller that is being called - * @param string $methodName the name of the method that will be called on - * the controller - * @param \Exception $exception the thrown exception - * @throws \Exception the passed in exception if it can't handle it - * @return Response a Response object or null in case that the exception could not be handled - */ - public function afterException($controller, $methodName, \Exception $exception) { - if($exception instanceof SecurityException) { - - if (stripos($this->request->getHeader('Accept'),'html') === false) { - $response = new JSONResponse( - array('message' => $exception->getMessage()), - $exception->getCode() - ); - } else { - if($exception instanceof NotLoggedInException) { - $url = $this->urlGenerator->linkToRoute( - 'core.login.showLoginForm', - [ - 'redirect_url' => urlencode($this->request->server['REQUEST_URI']), - ] - ); - $response = new RedirectResponse($url); - } else { - $response = new TemplateResponse('core', '403', ['file' => $exception->getMessage()], 'guest'); - $response->setStatus($exception->getCode()); - } - } - - $this->logger->debug($exception->getMessage()); - return $response; - } - - throw $exception; - } - -} diff --git a/lib/private/appframework/middleware/sessionmiddleware.php b/lib/private/appframework/middleware/sessionmiddleware.php deleted file mode 100644 index b218b48ea11..00000000000 --- a/lib/private/appframework/middleware/sessionmiddleware.php +++ /dev/null @@ -1,81 +0,0 @@ -<?php -/** - * @author Morris Jobke <hey@morrisjobke.de> - * @author Thomas Müller <thomas.mueller@tmit.eu> - * - * @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 <http://www.gnu.org/licenses/> - * - */ - -namespace OC\AppFramework\Middleware; - -use OC\AppFramework\Utility\ControllerMethodReflector; -use OCP\IRequest; -use OCP\AppFramework\Http\Response; -use OCP\AppFramework\Middleware; -use OCP\ISession; - -class SessionMiddleware extends Middleware { - - /** - * @var IRequest - */ - private $request; - - /** - * @var ControllerMethodReflector - */ - private $reflector; - - /** - * @param IRequest $request - * @param ControllerMethodReflector $reflector - */ - public function __construct(IRequest $request, - ControllerMethodReflector $reflector, - ISession $session -) { - $this->request = $request; - $this->reflector = $reflector; - $this->session = $session; - } - - /** - * @param \OCP\AppFramework\Controller $controller - * @param string $methodName - */ - public function beforeController($controller, $methodName) { - $useSession = $this->reflector->hasAnnotation('UseSession'); - if (!$useSession) { - $this->session->close(); - } - } - - /** - * @param \OCP\AppFramework\Controller $controller - * @param string $methodName - * @param Response $response - * @return Response - */ - public function afterController($controller, $methodName, Response $response){ - $useSession = $this->reflector->hasAnnotation('UseSession'); - if ($useSession) { - $this->session->close(); - } - return $response; - } - -} diff --git a/lib/private/appframework/routing/routeactionhandler.php b/lib/private/appframework/routing/routeactionhandler.php deleted file mode 100644 index b282fc1b452..00000000000 --- a/lib/private/appframework/routing/routeactionhandler.php +++ /dev/null @@ -1,47 +0,0 @@ -<?php -/** - * @author Jörn Friedrich Dreyer <jfd@butonic.de> - * @author Morris Jobke <hey@morrisjobke.de> - * @author Thomas Müller <thomas.mueller@tmit.eu> - * - * @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 <http://www.gnu.org/licenses/> - * - */ - -namespace OC\AppFramework\routing; - -use \OC\AppFramework\App; -use \OC\AppFramework\DependencyInjection\DIContainer; - -class RouteActionHandler { - private $controllerName; - private $actionName; - private $container; - - /** - * @param string $controllerName - * @param string $actionName - */ - public function __construct(DIContainer $container, $controllerName, $actionName) { - $this->controllerName = $controllerName; - $this->actionName = $actionName; - $this->container = $container; - } - - public function __invoke($params) { - App::main($this->controllerName, $this->actionName, $this->container, $params); - } -} diff --git a/lib/private/appframework/routing/routeconfig.php b/lib/private/appframework/routing/routeconfig.php deleted file mode 100644 index dd029ba9a00..00000000000 --- a/lib/private/appframework/routing/routeconfig.php +++ /dev/null @@ -1,200 +0,0 @@ -<?php -/** - * @author Bernhard Posselt <dev@bernhard-posselt.com> - * @author Morris Jobke <hey@morrisjobke.de> - * @author Patrick Paysant <ppaysant@linagora.com> - * @author Robin Appelman <icewind@owncloud.com> - * @author Robin McCorkell <robin@mccorkell.me.uk> - * @author Thomas Müller <thomas.mueller@tmit.eu> - * - * @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 <http://www.gnu.org/licenses/> - * - */ - -namespace OC\AppFramework\routing; - -use OC\AppFramework\DependencyInjection\DIContainer; -use OCP\Route\IRouter; - -/** - * Class RouteConfig - * @package OC\AppFramework\routing - */ -class RouteConfig { - private $container; - private $router; - private $routes; - private $appName; - - /** - * @param \OC\AppFramework\DependencyInjection\DIContainer $container - * @param \OCP\Route\IRouter $router - * @internal param $appName - */ - public function __construct(DIContainer $container, IRouter $router, $routes) { - $this->routes = $routes; - $this->container = $container; - $this->router = $router; - $this->appName = $container['AppName']; - } - - /** - * The routes and resource will be registered to the \OCP\Route\IRouter - */ - public function register() { - - // parse simple - $this->processSimpleRoutes($this->routes); - - // parse resources - $this->processResources($this->routes); - } - - /** - * Creates one route base on the give configuration - * @param array $routes - * @throws \UnexpectedValueException - */ - private function processSimpleRoutes($routes) - { - $simpleRoutes = isset($routes['routes']) ? $routes['routes'] : array(); - foreach ($simpleRoutes as $simpleRoute) { - $name = $simpleRoute['name']; - $postfix = ''; - - if (isset($simpleRoute['postfix'])) { - $postfix = $simpleRoute['postfix']; - } - - $url = $simpleRoute['url']; - $verb = isset($simpleRoute['verb']) ? strtoupper($simpleRoute['verb']) : 'GET'; - - $split = explode('#', $name, 2); - if (count($split) != 2) { - throw new \UnexpectedValueException('Invalid route name'); - } - $controller = $split[0]; - $action = $split[1]; - - $controllerName = $this->buildControllerName($controller); - $actionName = $this->buildActionName($action); - - // register the route - $handler = new RouteActionHandler($this->container, $controllerName, $actionName); - $router = $this->router->create($this->appName.'.'.$controller.'.'.$action . $postfix, $url) - ->method($verb) - ->action($handler); - - // optionally register requirements for route. This is used to - // tell the route parser how url parameters should be matched - if(array_key_exists('requirements', $simpleRoute)) { - $router->requirements($simpleRoute['requirements']); - } - - // optionally register defaults for route. This is used to - // tell the route parser how url parameters should be default valued - if(array_key_exists('defaults', $simpleRoute)) { - $router->defaults($simpleRoute['defaults']); - } - } - } - - /** - * For a given name and url restful routes are created: - * - index - * - show - * - new - * - create - * - update - * - destroy - * - * @param array $routes - */ - private function processResources($routes) - { - // declaration of all restful actions - $actions = array( - array('name' => 'index', 'verb' => 'GET', 'on-collection' => true), - array('name' => 'show', 'verb' => 'GET'), - array('name' => 'create', 'verb' => 'POST', 'on-collection' => true), - array('name' => 'update', 'verb' => 'PUT'), - array('name' => 'destroy', 'verb' => 'DELETE'), - ); - - $resources = isset($routes['resources']) ? $routes['resources'] : array(); - foreach ($resources as $resource => $config) { - - // the url parameter used as id to the resource - foreach($actions as $action) { - $url = $config['url']; - $method = $action['name']; - $verb = isset($action['verb']) ? strtoupper($action['verb']) : 'GET'; - $collectionAction = isset($action['on-collection']) ? $action['on-collection'] : false; - if (!$collectionAction) { - $url = $url . '/{id}'; - } - if (isset($action['url-postfix'])) { - $url = $url . '/' . $action['url-postfix']; - } - - $controller = $resource; - - $controllerName = $this->buildControllerName($controller); - $actionName = $this->buildActionName($method); - - $routeName = $this->appName . '.' . strtolower($resource) . '.' . strtolower($method); - - $this->router->create($routeName, $url)->method($verb)->action( - new RouteActionHandler($this->container, $controllerName, $actionName) - ); - } - } - } - - /** - * Based on a given route name the controller name is generated - * @param string $controller - * @return string - */ - private function buildControllerName($controller) - { - return $this->underScoreToCamelCase(ucfirst($controller)) . 'Controller'; - } - - /** - * Based on the action part of the route name the controller method name is generated - * @param string $action - * @return string - */ - private function buildActionName($action) { - return $this->underScoreToCamelCase($action); - } - - /** - * Underscored strings are converted to camel case strings - * @param string $str - * @return string - */ - private function underScoreToCamelCase($str) { - $pattern = "/_[a-z]?/"; - return preg_replace_callback( - $pattern, - function ($matches) { - return strtoupper(ltrim($matches[0], "_")); - }, - $str); - } -} diff --git a/lib/private/appframework/utility/controllermethodreflector.php b/lib/private/appframework/utility/controllermethodreflector.php deleted file mode 100644 index de83749fbaf..00000000000 --- a/lib/private/appframework/utility/controllermethodreflector.php +++ /dev/null @@ -1,118 +0,0 @@ -<?php -/** - * @author Bernhard Posselt <dev@bernhard-posselt.com> - * @author Morris Jobke <hey@morrisjobke.de> - * @author Olivier Paroz <github@oparoz.com> - * @author Robin McCorkell <robin@mccorkell.me.uk> - * @author Thomas Müller <thomas.mueller@tmit.eu> - * - * @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 <http://www.gnu.org/licenses/> - * - */ - - -namespace OC\AppFramework\Utility; - -use \OCP\AppFramework\Utility\IControllerMethodReflector; - - -/** - * Reads and parses annotations from doc comments - */ -class ControllerMethodReflector implements IControllerMethodReflector{ - - private $annotations; - private $types; - private $parameters; - - public function __construct() { - $this->types = array(); - $this->parameters = array(); - $this->annotations = array(); - } - - - /** - * @param object $object an object or classname - * @param string $method the method which we want to inspect - */ - public function reflect($object, $method){ - $reflection = new \ReflectionMethod($object, $method); - $docs = $reflection->getDocComment(); - - // extract everything prefixed by @ and first letter uppercase - preg_match_all('/@([A-Z]\w+)/', $docs, $matches); - $this->annotations = $matches[1]; - - // extract type parameter information - preg_match_all('/@param\h+(?P<type>\w+)\h+\$(?P<var>\w+)/', $docs, $matches); - $this->types = array_combine($matches['var'], $matches['type']); - - foreach ($reflection->getParameters() as $param) { - // extract type information from PHP 7 scalar types and prefer them - // over phpdoc annotations - if (method_exists($param, 'getType')) { - $type = $param->getType(); - if ($type !== null) { - $this->types[$param->getName()] = (string) $type; - } - } - - if($param->isOptional()) { - $default = $param->getDefaultValue(); - } else { - $default = null; - } - $this->parameters[$param->name] = $default; - } - } - - - /** - * Inspects the PHPDoc parameters for types - * @param string $parameter the parameter whose type comments should be - * parsed - * @return string|null type in the type parameters (@param int $something) - * would return int or null if not existing - */ - public function getType($parameter) { - if(array_key_exists($parameter, $this->types)) { - return $this->types[$parameter]; - } else { - return null; - } - } - - - /** - * @return array the arguments of the method with key => default value - */ - public function getParameters() { - return $this->parameters; - } - - - /** - * Check if a method contains an annotation - * @param string $name the name of the annotation - * @return bool true if the annotation is found - */ - public function hasAnnotation($name){ - return in_array($name, $this->annotations); - } - - -} diff --git a/lib/private/appframework/utility/simplecontainer.php b/lib/private/appframework/utility/simplecontainer.php deleted file mode 100644 index 78ded39735e..00000000000 --- a/lib/private/appframework/utility/simplecontainer.php +++ /dev/null @@ -1,162 +0,0 @@ -<?php -/** - * @author Bernhard Posselt <dev@bernhard-posselt.com> - * @author Joas Schilling <nickvergessen@owncloud.com> - * @author Lukas Reschke <lukas@owncloud.com> - * @author Morris Jobke <hey@morrisjobke.de> - * @author Robin McCorkell <robin@mccorkell.me.uk> - * @author Thomas Müller <thomas.mueller@tmit.eu> - * - * @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 <http://www.gnu.org/licenses/> - * - */ - -namespace OC\AppFramework\Utility; - -use ReflectionClass; -use ReflectionException; -use Closure; -use Pimple\Container; -use OCP\AppFramework\QueryException; -use OCP\IContainer; - -/** - * Class SimpleContainer - * - * SimpleContainer is a simple implementation of IContainer on basis of Pimple - */ -class SimpleContainer extends Container implements IContainer { - - - /** - * @param ReflectionClass $class the class to instantiate - * @return \stdClass the created class - */ - private function buildClass(ReflectionClass $class) { - $constructor = $class->getConstructor(); - if ($constructor === null) { - return $class->newInstance(); - } else { - $parameters = []; - foreach ($constructor->getParameters() as $parameter) { - $parameterClass = $parameter->getClass(); - - // try to find out if it is a class or a simple parameter - if ($parameterClass === null) { - $resolveName = $parameter->getName(); - } else { - $resolveName = $parameterClass->name; - } - - $parameters[] = $this->query($resolveName); - } - return $class->newInstanceArgs($parameters); - } - } - - - /** - * If a parameter is not registered in the container try to instantiate it - * by using reflection to find out how to build the class - * @param string $name the class name to resolve - * @return \stdClass - * @throws QueryException if the class could not be found or instantiated - */ - public function resolve($name) { - $baseMsg = 'Could not resolve ' . $name . '!'; - try { - $class = new ReflectionClass($name); - if ($class->isInstantiable()) { - return $this->buildClass($class); - } else { - throw new QueryException($baseMsg . - ' Class can not be instantiated'); - } - } catch(ReflectionException $e) { - throw new QueryException($baseMsg . ' ' . $e->getMessage()); - } - } - - - /** - * @param string $name name of the service to query for - * @return mixed registered service for the given $name - * @throws QueryException if the query could not be resolved - */ - public function query($name) { - $name = $this->sanitizeName($name); - if ($this->offsetExists($name)) { - return $this->offsetGet($name); - } else { - $object = $this->resolve($name); - $this->registerService($name, function () use ($object) { - return $object; - }); - return $object; - } - } - - /** - * @param string $name - * @param mixed $value - */ - public function registerParameter($name, $value) { - $this[$name] = $value; - } - - /** - * The given closure is call the first time the given service is queried. - * The closure has to return the instance for the given service. - * Created instance will be cached in case $shared is true. - * - * @param string $name name of the service to register another backend for - * @param Closure $closure the closure to be called on service creation - * @param bool $shared - */ - public function registerService($name, Closure $closure, $shared = true) { - $name = $this->sanitizeName($name); - if (isset($this[$name])) { - unset($this[$name]); - } - if ($shared) { - $this[$name] = $closure; - } else { - $this[$name] = parent::factory($closure); - } - } - - /** - * Shortcut for returning a service from a service under a different key, - * e.g. to tell the container to return a class when queried for an - * interface - * @param string $alias the alias that should be registered - * @param string $target the target that should be resolved instead - */ - public function registerAlias($alias, $target) { - $this->registerService($alias, function (IContainer $container) use ($target) { - return $container->query($target); - }, false); - } - - /* - * @param string $name - * @return string - */ - protected function sanitizeName($name) { - return ltrim($name, '\\'); - } - -} diff --git a/lib/private/appframework/utility/timefactory.php b/lib/private/appframework/utility/timefactory.php deleted file mode 100644 index 5241b367069..00000000000 --- a/lib/private/appframework/utility/timefactory.php +++ /dev/null @@ -1,44 +0,0 @@ -<?php -/** - * @author Bernhard Posselt <dev@bernhard-posselt.com> - * @author Morris Jobke <hey@morrisjobke.de> - * @author Thomas Müller <thomas.mueller@tmit.eu> - * - * @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 <http://www.gnu.org/licenses/> - * - */ - - -namespace OC\AppFramework\Utility; - -use OCP\AppFramework\Utility\ITimeFactory; - - -/** - * Needed to mock calls to time() - */ -class TimeFactory implements ITimeFactory { - - - /** - * @return int the result of a call to time() - */ - public function getTime() { - return time(); - } - - -} |