diff options
Diffstat (limited to 'lib/private')
42 files changed, 1605 insertions, 272 deletions
diff --git a/lib/private/App/CodeChecker/InfoChecker.php b/lib/private/App/CodeChecker/InfoChecker.php index 3ee99dc6478..77bf7e8182d 100644 --- a/lib/private/App/CodeChecker/InfoChecker.php +++ b/lib/private/App/CodeChecker/InfoChecker.php @@ -80,7 +80,7 @@ class InfoChecker extends BasicEmitter { $info = $this->infoParser->parse($appPath . '/appinfo/info.xml'); - if (isset($info['dependencies']['owncloud']['@attributes']['min-version']) && ($info['requiremin'] || $info['require'])) { + if (isset($info['dependencies']['owncloud']['@attributes']['min-version']) && (isset($info['requiremin']) || isset($info['require']))) { $this->emit('InfoChecker', 'duplicateRequirement', ['min']); $errors[] = [ 'type' => 'duplicateRequirement', @@ -90,7 +90,7 @@ class InfoChecker extends BasicEmitter { $this->emit('InfoChecker', 'missingRequirement', ['min']); } - if (isset($info['dependencies']['owncloud']['@attributes']['max-version']) && $info['requiremax']) { + if (isset($info['dependencies']['owncloud']['@attributes']['max-version']) && isset($info['requiremax'])) { $this->emit('InfoChecker', 'duplicateRequirement', ['max']); $errors[] = [ 'type' => 'duplicateRequirement', diff --git a/lib/private/AppFramework/DependencyInjection/DIContainer.php b/lib/private/AppFramework/DependencyInjection/DIContainer.php index 66ca59d26e2..20351d1321c 100644 --- a/lib/private/AppFramework/DependencyInjection/DIContainer.php +++ b/lib/private/AppFramework/DependencyInjection/DIContainer.php @@ -124,6 +124,10 @@ class DIContainer extends SimpleContainer implements IAppContainer { return $this->getServer()->getDateTimeZone(); }); + $this->registerService('OCP\\IDateTimeFormatter', function($c) { + return $this->getServer()->getDateTimeFormatter(); + }); + $this->registerService('OCP\\IDb', function($c) { return $this->getServer()->getDb(); }); @@ -148,6 +152,10 @@ class DIContainer extends SimpleContainer implements IAppContainer { return $this->getServer()->getMountProviderCollection(); }); + $this->registerService('OCP\\Files\\Config\\IUserMountCache', function($c) { + return $this->getServer()->getUserMountCache(); + }); + $this->registerService('OCP\\Files\\IRootFolder', function($c) { return $this->getServer()->getRootFolder(); }); @@ -306,6 +314,10 @@ class DIContainer extends SimpleContainer implements IAppContainer { return $c->query('ServerContainer')->getWebRoot(); }); + $this->registerService('OCP\Encryption\IManager', function ($c) { + return $this->getServer()->getEncryptionManager(); + }); + /** * App Framework APIs @@ -396,6 +408,7 @@ class DIContainer extends SimpleContainer implements IAppContainer { $this->registerService('MiddlewareDispatcher', function($c) use (&$middleWares) { $dispatcher = new MiddlewareDispatcher(); $dispatcher->registerMiddleware($c['CORSMiddleware']); + $dispatcher->registerMiddleware($c['OCSMiddleware']); $dispatcher->registerMiddleware($c['SecurityMiddleware']); $dispatcher->registerMiddleWare($c['TwoFactorMiddleware']); @@ -404,7 +417,6 @@ class DIContainer extends SimpleContainer implements IAppContainer { } $dispatcher->registerMiddleware($c['SessionMiddleware']); - $dispatcher->registerMiddleware($c['OCSMiddleware']); return $dispatcher; }); diff --git a/lib/private/AppFramework/Http/Request.php b/lib/private/AppFramework/Http/Request.php index 8fb19f2d9b2..46122f880cc 100644 --- a/lib/private/AppFramework/Http/Request.php +++ b/lib/private/AppFramework/Http/Request.php @@ -56,7 +56,6 @@ use OCP\Security\ISecureRandom; 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 @@ -701,10 +700,6 @@ class Request implements \ArrayAccess, \Countable, IRequest { * @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); diff --git a/lib/private/AppFramework/Middleware/OCSMiddleware.php b/lib/private/AppFramework/Middleware/OCSMiddleware.php index e07d100d8ac..68445bbcc51 100644 --- a/lib/private/AppFramework/Middleware/OCSMiddleware.php +++ b/lib/private/AppFramework/Middleware/OCSMiddleware.php @@ -23,8 +23,14 @@ namespace OC\AppFramework\Middleware; use OC\AppFramework\Http; +use OCP\API; +use OCP\AppFramework\Http\DataResponse; +use OCP\AppFramework\Http\JSONResponse; use OCP\AppFramework\Http\OCSResponse; +use OCP\AppFramework\Http\Response; use OCP\AppFramework\OCS\OCSException; +use OCP\AppFramework\OCS\OCSForbiddenException; +use OCP\AppFramework\OCS\OCSNotFoundException; use OCP\AppFramework\OCSController; use OCP\IRequest; use OCP\AppFramework\Middleware; @@ -54,12 +60,35 @@ class OCSMiddleware extends Middleware { $code = $exception->getCode(); if ($code === 0) { - $code = Http::STATUS_INTERNAL_SERVER_ERROR; + $code = API::RESPOND_UNKNOWN_ERROR; } + + // Build the response $response = new OCSResponse($format, $code, $exception->getMessage()); + // Forbidden always sets 401 (even on v1.php) + if ($exception instanceof OCSForbiddenException || $code === API::RESPOND_UNAUTHORISED) { + $response->setStatus(Http::STATUS_UNAUTHORIZED); + } + + // On v2.php we set actual HTTP error codes if (substr_compare($this->request->getScriptName(), '/ocs/v2.php', -strlen('/ocs/v2.php')) === 0) { - $response->setStatus($code); + if ($code === API::RESPOND_NOT_FOUND) { + $response->setStatus(Http::STATUS_NOT_FOUND); + } else if ($code === API::RESPOND_SERVER_ERROR) { + $response->setStatus(Http::STATUS_INTERNAL_SERVER_ERROR); + } else if ($code === API::RESPOND_UNKNOWN_ERROR) { + $response->setStatus(Http::STATUS_INTERNAL_SERVER_ERROR); + } else if ($code === API::RESPOND_UNAUTHORISED) { + // Already set + } + // 4xx and 5xx codes are forwarded as is. + else if ($code >= 400 && $code < 600) { + $response->setStatus($code); + } else { + // All other codes get a bad request + $response->setStatus(Http::STATUS_BAD_REQUEST); + } } return $response; } @@ -69,6 +98,35 @@ class OCSMiddleware extends Middleware { /** * @param \OCP\AppFramework\Controller $controller + * @param string $methodName + * @param Response $response + * @return \OCP\AppFramework\Http\Response + */ + public function afterController($controller, $methodName, Response $response) { + /* + * If a different middleware has detected that a request unauthorized or forbidden + * we need to catch the response and convert it to a proper OCS response. + */ + if ($controller instanceof OCSController && !($response instanceof OCSResponse)) { + if ($response->getStatus() === Http::STATUS_UNAUTHORIZED || + $response->getStatus() === Http::STATUS_FORBIDDEN) { + $format = $this->getFormat($controller); + + $message = ''; + if ($response instanceof JSONResponse) { + /** @var DataResponse $response */ + $message = $response->getData()['message']; + } + $response = new OCSResponse($format, \OCP\API::RESPOND_UNAUTHORISED, $message); + $response->setStatus(Http::STATUS_UNAUTHORIZED); + } + } + + return $response; + } + + /** + * @param \OCP\AppFramework\Controller $controller * @return string */ private function getFormat($controller) { diff --git a/lib/private/Authentication/TwoFactorAuth/Manager.php b/lib/private/Authentication/TwoFactorAuth/Manager.php index 66bcafbce71..143fe7dc927 100644 --- a/lib/private/Authentication/TwoFactorAuth/Manager.php +++ b/lib/private/Authentication/TwoFactorAuth/Manager.php @@ -165,10 +165,24 @@ class Manager { /** * Check if the currently logged in user needs to pass 2FA * + * @param IUser $user the currently logged in user * @return boolean */ - public function needsSecondFactor() { - return $this->session->exists(self::SESSION_UID_KEY); + public function needsSecondFactor(IUser $user = null) { + if (is_null($user) || !$this->session->exists(self::SESSION_UID_KEY)) { + return false; + } + + if (!$this->isTwoFactorAuthenticated($user)) { + // There is no second factor any more -> let the user pass + // This prevents infinite redirect loops when a user is about + // to solve the 2FA challenge, and the provider app is + // disabled the same time + $this->session->remove(self::SESSION_UID_KEY); + return false; + } + + return true; } /** diff --git a/lib/private/CapabilitiesManager.php b/lib/private/CapabilitiesManager.php index 99a37d652a1..159fa97c708 100644 --- a/lib/private/CapabilitiesManager.php +++ b/lib/private/CapabilitiesManager.php @@ -22,15 +22,22 @@ namespace OC; +use OCP\AppFramework\QueryException; use OCP\Capabilities\ICapability; +use OCP\ILogger; class CapabilitiesManager { - /** - * @var \Closure[] - */ + /** @var \Closure[] */ private $capabilities = array(); + /** @var ILogger */ + private $logger; + + public function __construct(ILogger $logger) { + $this->logger = $logger; + } + /** * Get an array of al the capabilities that are registered at this manager * @@ -40,7 +47,13 @@ class CapabilitiesManager { public function getCapabilities() { $capabilities = []; foreach($this->capabilities as $capability) { - $c = $capability(); + try { + $c = $capability(); + } catch (QueryException $e) { + $this->logger->error('CapabilitiesManager: {message}', ['app' => 'core', 'message' => $e->getMessage()]); + continue; + } + if ($c instanceof ICapability) { $capabilities = array_replace_recursive($capabilities, $c->getCapabilities()); } else { diff --git a/lib/private/Comments/Comment.php b/lib/private/Comments/Comment.php index d640c606f8e..f6f0801c683 100644 --- a/lib/private/Comments/Comment.php +++ b/lib/private/Comments/Comment.php @@ -47,8 +47,8 @@ class Comment implements IComment { /** * Comment constructor. * - * @param [] $data optional, array with keys according to column names from - * the comments database scheme + * @param array $data optional, array with keys according to column names from + * the comments database scheme */ public function __construct(array $data = null) { if(is_array($data)) { @@ -358,7 +358,7 @@ class Comment implements IComment { * sets the comment data based on an array with keys as taken from the * database. * - * @param [] $data + * @param array $data * @return IComment */ protected function fromArray($data) { diff --git a/lib/private/Diagnostics/Query.php b/lib/private/Diagnostics/Query.php index 908ad17f9db..8ac2cc0eeac 100644 --- a/lib/private/Diagnostics/Query.php +++ b/lib/private/Diagnostics/Query.php @@ -34,15 +34,18 @@ class Query implements IQuery { private $end; + private $stack; + /** * @param string $sql * @param array $params * @param int $start */ - public function __construct($sql, $params, $start) { + public function __construct($sql, $params, $start, array $stack) { $this->sql = $sql; $this->params = $params; $this->start = $start; + $this->stack = $stack; } public function end($time) { @@ -69,4 +72,12 @@ class Query implements IQuery { public function getDuration() { return $this->end - $this->start; } + + public function getStartTime() { + return $this->start; + } + + public function getStacktrace() { + return $this->stack; + } } diff --git a/lib/private/Diagnostics/QueryLogger.php b/lib/private/Diagnostics/QueryLogger.php index 5cf7e0689f8..a30f8c7b02a 100644 --- a/lib/private/Diagnostics/QueryLogger.php +++ b/lib/private/Diagnostics/QueryLogger.php @@ -42,7 +42,15 @@ class QueryLogger implements IQueryLogger { * @param array $types */ public function startQuery($sql, array $params = null, array $types = null) { - $this->activeQuery = new Query($sql, $params, microtime(true)); + $this->activeQuery = new Query($sql, $params, microtime(true), $this->getStack()); + } + + private function getStack() { + $stack = debug_backtrace(); + array_shift($stack); + array_shift($stack); + array_shift($stack); + return $stack; } public function stopQuery() { diff --git a/lib/private/Files/Mount/MountPoint.php b/lib/private/Files/Mount/MountPoint.php index 8b8f0574ae0..42b79596c98 100644 --- a/lib/private/Files/Mount/MountPoint.php +++ b/lib/private/Files/Mount/MountPoint.php @@ -41,6 +41,7 @@ class MountPoint implements IMountPoint { protected $storage = null; protected $class; protected $storageId; + protected $rootId = null; /** * Configuration options for the storage backend @@ -70,7 +71,7 @@ class MountPoint implements IMountPoint { */ private $invalidStorage = false; - /** @var int|null */ + /** @var int|null */ protected $mountId; /** @@ -132,18 +133,20 @@ class MountPoint implements IMountPoint { /** * create the storage that is mounted - * - * @return \OC\Files\Storage\Storage */ private function createStorage() { if ($this->invalidStorage) { - return null; + return; } if (class_exists($this->class)) { try { - return $this->loader->getInstance($this, $this->class, $this->arguments); + $class = $this->class; + // prevent recursion by setting the storage before applying wrappers + $this->storage = new $class($this->arguments); + $this->storage = $this->loader->wrap($this, $this->storage); } catch (\Exception $exception) { + $this->storage = null; $this->invalidStorage = true; if ($this->mountPoint === '/') { // the root storage could not be initialized, show the user! @@ -151,12 +154,12 @@ class MountPoint implements IMountPoint { } else { \OCP\Util::writeLog('core', $exception->getMessage(), \OCP\Util::ERROR); } - return null; + return; } } else { \OCP\Util::writeLog('core', 'storage backend ' . $this->class . ' not found', \OCP\Util::ERROR); $this->invalidStorage = true; - return null; + return; } } @@ -165,7 +168,7 @@ class MountPoint implements IMountPoint { */ public function getStorage() { if (is_null($this->storage)) { - $this->storage = $this->createStorage(); + $this->createStorage(); } return $this->storage; } @@ -262,7 +265,10 @@ class MountPoint implements IMountPoint { * @return int */ public function getStorageRootId() { - return (int)$this->getStorage()->getCache()->getId(''); + if (is_null($this->rootId)) { + $this->rootId = (int)$this->getStorage()->getCache()->getId(''); + } + return $this->rootId; } public function getMountId() { diff --git a/lib/private/Files/Node/LazyRoot.php b/lib/private/Files/Node/LazyRoot.php index 317b8144653..1fb3f6448bc 100644 --- a/lib/private/Files/Node/LazyRoot.php +++ b/lib/private/Files/Node/LazyRoot.php @@ -139,7 +139,7 @@ class LazyRoot implements IRootFolder { * @inheritDoc */ public function get($path) { - $this->__call(__FUNCTION__, func_get_args()); + return $this->__call(__FUNCTION__, func_get_args()); } /** diff --git a/lib/private/Files/Node/Root.php b/lib/private/Files/Node/Root.php index bad865a7987..007847fb513 100644 --- a/lib/private/Files/Node/Root.php +++ b/lib/private/Files/Node/Root.php @@ -28,6 +28,7 @@ namespace OC\Files\Node; +use OC\Cache\CappedMemoryCache; use OC\Files\Mount\Manager; use OC\Files\Mount\MountPoint; use OCP\Files\NotFoundException; @@ -71,6 +72,8 @@ class Root extends Folder implements IRootFolder { */ private $user; + private $userFolderCache; + /** * @param \OC\Files\Mount\Manager $manager * @param \OC\Files\View $view @@ -81,6 +84,7 @@ class Root extends Folder implements IRootFolder { $this->mountManager = $manager; $this->user = $user; $this->emitter = new PublicEmitter(); + $this->userFolderCache = new CappedMemoryCache(); } /** @@ -335,25 +339,26 @@ class Root extends Folder implements IRootFolder { * @return \OCP\Files\Folder */ public function getUserFolder($userId) { - \OC\Files\Filesystem::initMountPoints($userId); - $dir = '/' . $userId; - $folder = null; - - try { - $folder = $this->get($dir); - } catch (NotFoundException $e) { - $folder = $this->newFolder($dir); - } + if (!$this->userFolderCache->hasKey($userId)) { + \OC\Files\Filesystem::initMountPoints($userId); + + try { + $folder = $this->get('/' . $userId . '/files'); + } catch (NotFoundException $e) { + if (!$this->nodeExists('/' . $userId)) { + $this->newFolder('/' . $userId); + } + $folder = $this->newFolder('/' . $userId . '/files'); + \OC_Util::copySkeleton($userId, $folder); + } - $dir = '/files'; - try { - $folder = $folder->get($dir); - } catch (NotFoundException $e) { - $folder = $folder->newFolder($dir); - \OC_Util::copySkeleton($userId, $folder); + $this->userFolderCache->set($userId, $folder); } - return $folder; + return $this->userFolderCache->get($userId); + } + public function clearCache() { + $this->userFolderCache = new CappedMemoryCache(); } } diff --git a/lib/private/Files/Storage/Wrapper/Jail.php b/lib/private/Files/Storage/Wrapper/Jail.php index 5b9085799b9..8615d73f346 100644 --- a/lib/private/Files/Storage/Wrapper/Jail.php +++ b/lib/private/Files/Storage/Wrapper/Jail.php @@ -68,7 +68,7 @@ class Jail extends Wrapper { * @return bool */ public function mkdir($path) { - return $this->storage->mkdir($this->getSourcePath($path)); + return $this->getWrapperStorage()->mkdir($this->getSourcePath($path)); } /** @@ -78,7 +78,7 @@ class Jail extends Wrapper { * @return bool */ public function rmdir($path) { - return $this->storage->rmdir($this->getSourcePath($path)); + return $this->getWrapperStorage()->rmdir($this->getSourcePath($path)); } /** @@ -88,7 +88,7 @@ class Jail extends Wrapper { * @return resource */ public function opendir($path) { - return $this->storage->opendir($this->getSourcePath($path)); + return $this->getWrapperStorage()->opendir($this->getSourcePath($path)); } /** @@ -98,7 +98,7 @@ class Jail extends Wrapper { * @return bool */ public function is_dir($path) { - return $this->storage->is_dir($this->getSourcePath($path)); + return $this->getWrapperStorage()->is_dir($this->getSourcePath($path)); } /** @@ -108,7 +108,7 @@ class Jail extends Wrapper { * @return bool */ public function is_file($path) { - return $this->storage->is_file($this->getSourcePath($path)); + return $this->getWrapperStorage()->is_file($this->getSourcePath($path)); } /** @@ -119,7 +119,7 @@ class Jail extends Wrapper { * @return array */ public function stat($path) { - return $this->storage->stat($this->getSourcePath($path)); + return $this->getWrapperStorage()->stat($this->getSourcePath($path)); } /** @@ -129,7 +129,7 @@ class Jail extends Wrapper { * @return bool */ public function filetype($path) { - return $this->storage->filetype($this->getSourcePath($path)); + return $this->getWrapperStorage()->filetype($this->getSourcePath($path)); } /** @@ -140,7 +140,7 @@ class Jail extends Wrapper { * @return int */ public function filesize($path) { - return $this->storage->filesize($this->getSourcePath($path)); + return $this->getWrapperStorage()->filesize($this->getSourcePath($path)); } /** @@ -150,7 +150,7 @@ class Jail extends Wrapper { * @return bool */ public function isCreatable($path) { - return $this->storage->isCreatable($this->getSourcePath($path)); + return $this->getWrapperStorage()->isCreatable($this->getSourcePath($path)); } /** @@ -160,7 +160,7 @@ class Jail extends Wrapper { * @return bool */ public function isReadable($path) { - return $this->storage->isReadable($this->getSourcePath($path)); + return $this->getWrapperStorage()->isReadable($this->getSourcePath($path)); } /** @@ -170,7 +170,7 @@ class Jail extends Wrapper { * @return bool */ public function isUpdatable($path) { - return $this->storage->isUpdatable($this->getSourcePath($path)); + return $this->getWrapperStorage()->isUpdatable($this->getSourcePath($path)); } /** @@ -180,7 +180,7 @@ class Jail extends Wrapper { * @return bool */ public function isDeletable($path) { - return $this->storage->isDeletable($this->getSourcePath($path)); + return $this->getWrapperStorage()->isDeletable($this->getSourcePath($path)); } /** @@ -190,7 +190,7 @@ class Jail extends Wrapper { * @return bool */ public function isSharable($path) { - return $this->storage->isSharable($this->getSourcePath($path)); + return $this->getWrapperStorage()->isSharable($this->getSourcePath($path)); } /** @@ -201,7 +201,7 @@ class Jail extends Wrapper { * @return int */ public function getPermissions($path) { - return $this->storage->getPermissions($this->getSourcePath($path)); + return $this->getWrapperStorage()->getPermissions($this->getSourcePath($path)); } /** @@ -211,7 +211,7 @@ class Jail extends Wrapper { * @return bool */ public function file_exists($path) { - return $this->storage->file_exists($this->getSourcePath($path)); + return $this->getWrapperStorage()->file_exists($this->getSourcePath($path)); } /** @@ -221,7 +221,7 @@ class Jail extends Wrapper { * @return int */ public function filemtime($path) { - return $this->storage->filemtime($this->getSourcePath($path)); + return $this->getWrapperStorage()->filemtime($this->getSourcePath($path)); } /** @@ -231,7 +231,7 @@ class Jail extends Wrapper { * @return string */ public function file_get_contents($path) { - return $this->storage->file_get_contents($this->getSourcePath($path)); + return $this->getWrapperStorage()->file_get_contents($this->getSourcePath($path)); } /** @@ -242,7 +242,7 @@ class Jail extends Wrapper { * @return bool */ public function file_put_contents($path, $data) { - return $this->storage->file_put_contents($this->getSourcePath($path), $data); + return $this->getWrapperStorage()->file_put_contents($this->getSourcePath($path), $data); } /** @@ -252,7 +252,7 @@ class Jail extends Wrapper { * @return bool */ public function unlink($path) { - return $this->storage->unlink($this->getSourcePath($path)); + return $this->getWrapperStorage()->unlink($this->getSourcePath($path)); } /** @@ -263,7 +263,7 @@ class Jail extends Wrapper { * @return bool */ public function rename($path1, $path2) { - return $this->storage->rename($this->getSourcePath($path1), $this->getSourcePath($path2)); + return $this->getWrapperStorage()->rename($this->getSourcePath($path1), $this->getSourcePath($path2)); } /** @@ -274,7 +274,7 @@ class Jail extends Wrapper { * @return bool */ public function copy($path1, $path2) { - return $this->storage->copy($this->getSourcePath($path1), $this->getSourcePath($path2)); + return $this->getWrapperStorage()->copy($this->getSourcePath($path1), $this->getSourcePath($path2)); } /** @@ -285,7 +285,7 @@ class Jail extends Wrapper { * @return resource */ public function fopen($path, $mode) { - return $this->storage->fopen($this->getSourcePath($path), $mode); + return $this->getWrapperStorage()->fopen($this->getSourcePath($path), $mode); } /** @@ -296,7 +296,7 @@ class Jail extends Wrapper { * @return string */ public function getMimeType($path) { - return $this->storage->getMimeType($this->getSourcePath($path)); + return $this->getWrapperStorage()->getMimeType($this->getSourcePath($path)); } /** @@ -308,7 +308,7 @@ class Jail extends Wrapper { * @return string */ public function hash($type, $path, $raw = false) { - return $this->storage->hash($type, $this->getSourcePath($path), $raw); + return $this->getWrapperStorage()->hash($type, $this->getSourcePath($path), $raw); } /** @@ -318,7 +318,7 @@ class Jail extends Wrapper { * @return int */ public function free_space($path) { - return $this->storage->free_space($this->getSourcePath($path)); + return $this->getWrapperStorage()->free_space($this->getSourcePath($path)); } /** @@ -328,7 +328,7 @@ class Jail extends Wrapper { * @return array */ public function search($query) { - return $this->storage->search($query); + return $this->getWrapperStorage()->search($query); } /** @@ -340,7 +340,7 @@ class Jail extends Wrapper { * @return bool */ public function touch($path, $mtime = null) { - return $this->storage->touch($this->getSourcePath($path), $mtime); + return $this->getWrapperStorage()->touch($this->getSourcePath($path), $mtime); } /** @@ -351,7 +351,7 @@ class Jail extends Wrapper { * @return string */ public function getLocalFile($path) { - return $this->storage->getLocalFile($this->getSourcePath($path)); + return $this->getWrapperStorage()->getLocalFile($this->getSourcePath($path)); } /** @@ -365,7 +365,7 @@ class Jail extends Wrapper { * returning true for other changes in the folder is optional */ public function hasUpdated($path, $time) { - return $this->storage->hasUpdated($this->getSourcePath($path), $time); + return $this->getWrapperStorage()->hasUpdated($this->getSourcePath($path), $time); } /** @@ -377,9 +377,9 @@ class Jail extends Wrapper { */ public function getCache($path = '', $storage = null) { if (!$storage) { - $storage = $this->storage; + $storage = $this->getWrapperStorage(); } - $sourceCache = $this->storage->getCache($this->getSourcePath($path), $storage); + $sourceCache = $this->getWrapperStorage()->getCache($this->getSourcePath($path), $storage); return new CacheJail($sourceCache, $this->rootPath); } @@ -390,7 +390,7 @@ class Jail extends Wrapper { * @return string */ public function getOwner($path) { - return $this->storage->getOwner($this->getSourcePath($path)); + return $this->getWrapperStorage()->getOwner($this->getSourcePath($path)); } /** @@ -404,7 +404,7 @@ class Jail extends Wrapper { if (!$storage) { $storage = $this; } - return $this->storage->getWatcher($this->getSourcePath($path), $storage); + return $this->getWrapperStorage()->getWatcher($this->getSourcePath($path), $storage); } /** @@ -414,7 +414,7 @@ class Jail extends Wrapper { * @return string */ public function getETag($path) { - return $this->storage->getETag($this->getSourcePath($path)); + return $this->getWrapperStorage()->getETag($this->getSourcePath($path)); } /** @@ -422,7 +422,7 @@ class Jail extends Wrapper { * @return array */ public function getMetaData($path) { - return $this->storage->getMetaData($this->getSourcePath($path)); + return $this->getWrapperStorage()->getMetaData($this->getSourcePath($path)); } /** @@ -432,7 +432,7 @@ class Jail extends Wrapper { * @throws \OCP\Lock\LockedException */ public function acquireLock($path, $type, ILockingProvider $provider) { - $this->storage->acquireLock($this->getSourcePath($path), $type, $provider); + $this->getWrapperStorage()->acquireLock($this->getSourcePath($path), $type, $provider); } /** @@ -441,7 +441,7 @@ class Jail extends Wrapper { * @param \OCP\Lock\ILockingProvider $provider */ public function releaseLock($path, $type, ILockingProvider $provider) { - $this->storage->releaseLock($this->getSourcePath($path), $type, $provider); + $this->getWrapperStorage()->releaseLock($this->getSourcePath($path), $type, $provider); } /** @@ -450,7 +450,7 @@ class Jail extends Wrapper { * @param \OCP\Lock\ILockingProvider $provider */ public function changeLock($path, $type, ILockingProvider $provider) { - $this->storage->changeLock($this->getSourcePath($path), $type, $provider); + $this->getWrapperStorage()->changeLock($this->getSourcePath($path), $type, $provider); } /** @@ -460,7 +460,7 @@ class Jail extends Wrapper { * @return array */ public function resolvePath($path) { - return [$this->storage, $this->getSourcePath($path)]; + return [$this->getWrapperStorage(), $this->getSourcePath($path)]; } /** @@ -473,7 +473,7 @@ class Jail extends Wrapper { if ($sourceStorage === $this) { return $this->copy($sourceInternalPath, $targetInternalPath); } - return $this->storage->copyFromStorage($sourceStorage, $sourceInternalPath, $this->getSourcePath($targetInternalPath)); + return $this->getWrapperStorage()->copyFromStorage($sourceStorage, $sourceInternalPath, $this->getSourcePath($targetInternalPath)); } /** @@ -486,6 +486,6 @@ class Jail extends Wrapper { if ($sourceStorage === $this) { return $this->rename($sourceInternalPath, $targetInternalPath); } - return $this->storage->moveFromStorage($sourceStorage, $sourceInternalPath, $this->getSourcePath($targetInternalPath)); + return $this->getWrapperStorage()->moveFromStorage($sourceStorage, $sourceInternalPath, $this->getSourcePath($targetInternalPath)); } } diff --git a/lib/private/Files/Storage/Wrapper/Wrapper.php b/lib/private/Files/Storage/Wrapper/Wrapper.php index 706023a2893..c52b3394832 100644 --- a/lib/private/Files/Storage/Wrapper/Wrapper.php +++ b/lib/private/Files/Storage/Wrapper/Wrapper.php @@ -64,7 +64,7 @@ class Wrapper implements \OC\Files\Storage\Storage, ILockingStorage { * @return string */ public function getId() { - return $this->storage->getId(); + return $this->getWrapperStorage()->getId(); } /** @@ -74,7 +74,7 @@ class Wrapper implements \OC\Files\Storage\Storage, ILockingStorage { * @return bool */ public function mkdir($path) { - return $this->storage->mkdir($path); + return $this->getWrapperStorage()->mkdir($path); } /** @@ -84,7 +84,7 @@ class Wrapper implements \OC\Files\Storage\Storage, ILockingStorage { * @return bool */ public function rmdir($path) { - return $this->storage->rmdir($path); + return $this->getWrapperStorage()->rmdir($path); } /** @@ -94,7 +94,7 @@ class Wrapper implements \OC\Files\Storage\Storage, ILockingStorage { * @return resource */ public function opendir($path) { - return $this->storage->opendir($path); + return $this->getWrapperStorage()->opendir($path); } /** @@ -104,7 +104,7 @@ class Wrapper implements \OC\Files\Storage\Storage, ILockingStorage { * @return bool */ public function is_dir($path) { - return $this->storage->is_dir($path); + return $this->getWrapperStorage()->is_dir($path); } /** @@ -114,7 +114,7 @@ class Wrapper implements \OC\Files\Storage\Storage, ILockingStorage { * @return bool */ public function is_file($path) { - return $this->storage->is_file($path); + return $this->getWrapperStorage()->is_file($path); } /** @@ -125,7 +125,7 @@ class Wrapper implements \OC\Files\Storage\Storage, ILockingStorage { * @return array */ public function stat($path) { - return $this->storage->stat($path); + return $this->getWrapperStorage()->stat($path); } /** @@ -135,7 +135,7 @@ class Wrapper implements \OC\Files\Storage\Storage, ILockingStorage { * @return bool */ public function filetype($path) { - return $this->storage->filetype($path); + return $this->getWrapperStorage()->filetype($path); } /** @@ -146,7 +146,7 @@ class Wrapper implements \OC\Files\Storage\Storage, ILockingStorage { * @return int */ public function filesize($path) { - return $this->storage->filesize($path); + return $this->getWrapperStorage()->filesize($path); } /** @@ -156,7 +156,7 @@ class Wrapper implements \OC\Files\Storage\Storage, ILockingStorage { * @return bool */ public function isCreatable($path) { - return $this->storage->isCreatable($path); + return $this->getWrapperStorage()->isCreatable($path); } /** @@ -166,7 +166,7 @@ class Wrapper implements \OC\Files\Storage\Storage, ILockingStorage { * @return bool */ public function isReadable($path) { - return $this->storage->isReadable($path); + return $this->getWrapperStorage()->isReadable($path); } /** @@ -176,7 +176,7 @@ class Wrapper implements \OC\Files\Storage\Storage, ILockingStorage { * @return bool */ public function isUpdatable($path) { - return $this->storage->isUpdatable($path); + return $this->getWrapperStorage()->isUpdatable($path); } /** @@ -186,7 +186,7 @@ class Wrapper implements \OC\Files\Storage\Storage, ILockingStorage { * @return bool */ public function isDeletable($path) { - return $this->storage->isDeletable($path); + return $this->getWrapperStorage()->isDeletable($path); } /** @@ -196,7 +196,7 @@ class Wrapper implements \OC\Files\Storage\Storage, ILockingStorage { * @return bool */ public function isSharable($path) { - return $this->storage->isSharable($path); + return $this->getWrapperStorage()->isSharable($path); } /** @@ -207,7 +207,7 @@ class Wrapper implements \OC\Files\Storage\Storage, ILockingStorage { * @return int */ public function getPermissions($path) { - return $this->storage->getPermissions($path); + return $this->getWrapperStorage()->getPermissions($path); } /** @@ -217,7 +217,7 @@ class Wrapper implements \OC\Files\Storage\Storage, ILockingStorage { * @return bool */ public function file_exists($path) { - return $this->storage->file_exists($path); + return $this->getWrapperStorage()->file_exists($path); } /** @@ -227,7 +227,7 @@ class Wrapper implements \OC\Files\Storage\Storage, ILockingStorage { * @return int */ public function filemtime($path) { - return $this->storage->filemtime($path); + return $this->getWrapperStorage()->filemtime($path); } /** @@ -237,7 +237,7 @@ class Wrapper implements \OC\Files\Storage\Storage, ILockingStorage { * @return string */ public function file_get_contents($path) { - return $this->storage->file_get_contents($path); + return $this->getWrapperStorage()->file_get_contents($path); } /** @@ -248,7 +248,7 @@ class Wrapper implements \OC\Files\Storage\Storage, ILockingStorage { * @return bool */ public function file_put_contents($path, $data) { - return $this->storage->file_put_contents($path, $data); + return $this->getWrapperStorage()->file_put_contents($path, $data); } /** @@ -258,7 +258,7 @@ class Wrapper implements \OC\Files\Storage\Storage, ILockingStorage { * @return bool */ public function unlink($path) { - return $this->storage->unlink($path); + return $this->getWrapperStorage()->unlink($path); } /** @@ -269,7 +269,7 @@ class Wrapper implements \OC\Files\Storage\Storage, ILockingStorage { * @return bool */ public function rename($path1, $path2) { - return $this->storage->rename($path1, $path2); + return $this->getWrapperStorage()->rename($path1, $path2); } /** @@ -280,7 +280,7 @@ class Wrapper implements \OC\Files\Storage\Storage, ILockingStorage { * @return bool */ public function copy($path1, $path2) { - return $this->storage->copy($path1, $path2); + return $this->getWrapperStorage()->copy($path1, $path2); } /** @@ -291,7 +291,7 @@ class Wrapper implements \OC\Files\Storage\Storage, ILockingStorage { * @return resource */ public function fopen($path, $mode) { - return $this->storage->fopen($path, $mode); + return $this->getWrapperStorage()->fopen($path, $mode); } /** @@ -302,7 +302,7 @@ class Wrapper implements \OC\Files\Storage\Storage, ILockingStorage { * @return string */ public function getMimeType($path) { - return $this->storage->getMimeType($path); + return $this->getWrapperStorage()->getMimeType($path); } /** @@ -314,7 +314,7 @@ class Wrapper implements \OC\Files\Storage\Storage, ILockingStorage { * @return string */ public function hash($type, $path, $raw = false) { - return $this->storage->hash($type, $path, $raw); + return $this->getWrapperStorage()->hash($type, $path, $raw); } /** @@ -324,7 +324,7 @@ class Wrapper implements \OC\Files\Storage\Storage, ILockingStorage { * @return int */ public function free_space($path) { - return $this->storage->free_space($path); + return $this->getWrapperStorage()->free_space($path); } /** @@ -334,7 +334,7 @@ class Wrapper implements \OC\Files\Storage\Storage, ILockingStorage { * @return array */ public function search($query) { - return $this->storage->search($query); + return $this->getWrapperStorage()->search($query); } /** @@ -346,7 +346,7 @@ class Wrapper implements \OC\Files\Storage\Storage, ILockingStorage { * @return bool */ public function touch($path, $mtime = null) { - return $this->storage->touch($path, $mtime); + return $this->getWrapperStorage()->touch($path, $mtime); } /** @@ -357,7 +357,7 @@ class Wrapper implements \OC\Files\Storage\Storage, ILockingStorage { * @return string */ public function getLocalFile($path) { - return $this->storage->getLocalFile($path); + return $this->getWrapperStorage()->getLocalFile($path); } /** @@ -371,7 +371,7 @@ class Wrapper implements \OC\Files\Storage\Storage, ILockingStorage { * returning true for other changes in the folder is optional */ public function hasUpdated($path, $time) { - return $this->storage->hasUpdated($path, $time); + return $this->getWrapperStorage()->hasUpdated($path, $time); } /** @@ -385,7 +385,7 @@ class Wrapper implements \OC\Files\Storage\Storage, ILockingStorage { if (!$storage) { $storage = $this; } - return $this->storage->getCache($path, $storage); + return $this->getWrapperStorage()->getCache($path, $storage); } /** @@ -399,7 +399,7 @@ class Wrapper implements \OC\Files\Storage\Storage, ILockingStorage { if (!$storage) { $storage = $this; } - return $this->storage->getScanner($path, $storage); + return $this->getWrapperStorage()->getScanner($path, $storage); } @@ -410,7 +410,7 @@ class Wrapper implements \OC\Files\Storage\Storage, ILockingStorage { * @return string */ public function getOwner($path) { - return $this->storage->getOwner($path); + return $this->getWrapperStorage()->getOwner($path); } /** @@ -424,28 +424,28 @@ class Wrapper implements \OC\Files\Storage\Storage, ILockingStorage { if (!$storage) { $storage = $this; } - return $this->storage->getWatcher($path, $storage); + return $this->getWrapperStorage()->getWatcher($path, $storage); } public function getPropagator($storage = null) { if (!$storage) { $storage = $this; } - return $this->storage->getPropagator($storage); + return $this->getWrapperStorage()->getPropagator($storage); } public function getUpdater($storage = null) { if (!$storage) { $storage = $this; } - return $this->storage->getUpdater($storage); + return $this->getWrapperStorage()->getUpdater($storage); } /** * @return \OC\Files\Cache\Storage */ public function getStorageCache() { - return $this->storage->getStorageCache(); + return $this->getWrapperStorage()->getStorageCache(); } /** @@ -455,7 +455,7 @@ class Wrapper implements \OC\Files\Storage\Storage, ILockingStorage { * @return string */ public function getETag($path) { - return $this->storage->getETag($path); + return $this->getWrapperStorage()->getETag($path); } /** @@ -464,7 +464,7 @@ class Wrapper implements \OC\Files\Storage\Storage, ILockingStorage { * @return true */ public function test() { - return $this->storage->test(); + return $this->getWrapperStorage()->test(); } /** @@ -473,7 +473,7 @@ class Wrapper implements \OC\Files\Storage\Storage, ILockingStorage { * @return bool wrapped storage's isLocal() value */ public function isLocal() { - return $this->storage->isLocal(); + return $this->getWrapperStorage()->isLocal(); } /** @@ -483,7 +483,7 @@ class Wrapper implements \OC\Files\Storage\Storage, ILockingStorage { * @return bool */ public function instanceOfStorage($class) { - return is_a($this, $class) or $this->storage->instanceOfStorage($class); + return is_a($this, $class) or $this->getWrapperStorage()->instanceOfStorage($class); } /** @@ -494,7 +494,7 @@ class Wrapper implements \OC\Files\Storage\Storage, ILockingStorage { * @return mixed */ public function __call($method, $args) { - return call_user_func_array(array($this->storage, $method), $args); + return call_user_func_array(array($this->getWrapperStorage(), $method), $args); } /** @@ -506,7 +506,7 @@ class Wrapper implements \OC\Files\Storage\Storage, ILockingStorage { * @return array */ public function getDirectDownload($path) { - return $this->storage->getDirectDownload($path); + return $this->getWrapperStorage()->getDirectDownload($path); } /** @@ -515,7 +515,7 @@ class Wrapper implements \OC\Files\Storage\Storage, ILockingStorage { * @return array [ available, last_checked ] */ public function getAvailability() { - return $this->storage->getAvailability(); + return $this->getWrapperStorage()->getAvailability(); } /** @@ -524,7 +524,7 @@ class Wrapper implements \OC\Files\Storage\Storage, ILockingStorage { * @param bool $isAvailable */ public function setAvailability($isAvailable) { - $this->storage->setAvailability($isAvailable); + $this->getWrapperStorage()->setAvailability($isAvailable); } /** @@ -534,7 +534,7 @@ class Wrapper implements \OC\Files\Storage\Storage, ILockingStorage { * @throws InvalidPathException */ public function verifyPath($path, $fileName) { - $this->storage->verifyPath($path, $fileName); + $this->getWrapperStorage()->verifyPath($path, $fileName); } /** @@ -548,7 +548,7 @@ class Wrapper implements \OC\Files\Storage\Storage, ILockingStorage { return $this->copy($sourceInternalPath, $targetInternalPath); } - return $this->storage->copyFromStorage($sourceStorage, $sourceInternalPath, $targetInternalPath); + return $this->getWrapperStorage()->copyFromStorage($sourceStorage, $sourceInternalPath, $targetInternalPath); } /** @@ -562,7 +562,7 @@ class Wrapper implements \OC\Files\Storage\Storage, ILockingStorage { return $this->rename($sourceInternalPath, $targetInternalPath); } - return $this->storage->moveFromStorage($sourceStorage, $sourceInternalPath, $targetInternalPath); + return $this->getWrapperStorage()->moveFromStorage($sourceStorage, $sourceInternalPath, $targetInternalPath); } /** @@ -570,7 +570,7 @@ class Wrapper implements \OC\Files\Storage\Storage, ILockingStorage { * @return array */ public function getMetaData($path) { - return $this->storage->getMetaData($path); + return $this->getWrapperStorage()->getMetaData($path); } /** @@ -580,8 +580,8 @@ class Wrapper implements \OC\Files\Storage\Storage, ILockingStorage { * @throws \OCP\Lock\LockedException */ public function acquireLock($path, $type, ILockingProvider $provider) { - if ($this->storage->instanceOfStorage('\OCP\Files\Storage\ILockingStorage')) { - $this->storage->acquireLock($path, $type, $provider); + if ($this->getWrapperStorage()->instanceOfStorage('\OCP\Files\Storage\ILockingStorage')) { + $this->getWrapperStorage()->acquireLock($path, $type, $provider); } } @@ -591,8 +591,8 @@ class Wrapper implements \OC\Files\Storage\Storage, ILockingStorage { * @param \OCP\Lock\ILockingProvider $provider */ public function releaseLock($path, $type, ILockingProvider $provider) { - if ($this->storage->instanceOfStorage('\OCP\Files\Storage\ILockingStorage')) { - $this->storage->releaseLock($path, $type, $provider); + if ($this->getWrapperStorage()->instanceOfStorage('\OCP\Files\Storage\ILockingStorage')) { + $this->getWrapperStorage()->releaseLock($path, $type, $provider); } } @@ -602,8 +602,8 @@ class Wrapper implements \OC\Files\Storage\Storage, ILockingStorage { * @param \OCP\Lock\ILockingProvider $provider */ public function changeLock($path, $type, ILockingProvider $provider) { - if ($this->storage->instanceOfStorage('\OCP\Files\Storage\ILockingStorage')) { - $this->storage->changeLock($path, $type, $provider); + if ($this->getWrapperStorage()->instanceOfStorage('\OCP\Files\Storage\ILockingStorage')) { + $this->getWrapperStorage()->changeLock($path, $type, $provider); } } } diff --git a/lib/private/Installer.php b/lib/private/Installer.php index eed97e18d94..3d8a923417a 100644 --- a/lib/private/Installer.php +++ b/lib/private/Installer.php @@ -593,6 +593,12 @@ class Installer { OC_App::setAppTypes($info['id']); + if(isset($info['settings']) && is_array($info['settings'])) { + // requires that autoloading was registered for the app, + // as happens before running the install.php some lines above + \OC::$server->getSettingsManager()->setupSettings($info['settings']); + } + return $info['id']; } diff --git a/lib/private/Log.php b/lib/private/Log.php index 0a707f3d4ea..3e0734965b0 100644 --- a/lib/private/Log.php +++ b/lib/private/Log.php @@ -86,6 +86,9 @@ class Log implements ILogger { 'calculateHMAC', 'encrypt', 'decrypt', + + //LoginController + 'tryLogin' ]; /** diff --git a/lib/private/Notification/Manager.php b/lib/private/Notification/Manager.php index 240cb1e11ff..a079561f5c9 100644 --- a/lib/private/Notification/Manager.php +++ b/lib/private/Notification/Manager.php @@ -33,7 +33,7 @@ class Manager implements IManager { /** @var IApp[] */ protected $apps; - /** @var INotifier */ + /** @var INotifier[] */ protected $notifiers; /** @var array[] */ diff --git a/lib/private/Notification/Notification.php b/lib/private/Notification/Notification.php index 62a48f434fe..9b5877a3058 100644 --- a/lib/private/Notification/Notification.php +++ b/lib/private/Notification/Notification.php @@ -397,9 +397,13 @@ class Notification implements INotification { } $this->hasPrimaryParsedAction = true; + + // Make sure the primary action is always the first one + array_unshift($this->actionsParsed, $action); + } else { + $this->actionsParsed[] = $action; } - $this->actionsParsed[] = $action; return $this; } diff --git a/lib/private/OCS/Config.php b/lib/private/OCS/Config.php deleted file mode 100644 index a8bf8c325c3..00000000000 --- a/lib/private/OCS/Config.php +++ /dev/null @@ -1,39 +0,0 @@ -<?php -/** - * @copyright Copyright (c) 2016, ownCloud, Inc. - * - * @author Bart Visscher <bartv@thisnet.nl> - * @author Morris Jobke <hey@morrisjobke.de> - * @author Roeland Jago Douma <roeland@famdouma.nl> - * @author Tom Needham <tom@owncloud.com> - * - * @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\OCS; - -class Config { - - public static function apiConfig() { - $xml['version'] = '1.7'; - $xml['website'] = 'ownCloud'; - $xml['host'] = \OCP\Util::getServerHost(); - $xml['contact'] = ''; - $xml['ssl'] = 'false'; - return new Result($xml); - } - -} diff --git a/lib/private/Server.php b/lib/private/Server.php index d5808d7f17c..6f6d403210d 100644 --- a/lib/private/Server.php +++ b/lib/private/Server.php @@ -82,7 +82,7 @@ use OC\Security\SecureRandom; use OC\Security\TrustedDomainHelper; use OC\Session\CryptoWrapper; use OC\Tagging\TagMapper; -use OCA\Theming\Template; +use OCA\Theming\ThemingDefaults; use OCP\IL10N; use OCP\IServerContainer; use OCP\Security\IContentSecurityPolicyManager; @@ -185,7 +185,7 @@ class Server extends ServerContainer implements IServerContainer { }); $this->registerService('LazyRootFolder', function(Server $c) { return new LazyRoot(function() use ($c) { - return $c->getRootFolder(); + return $c->query('RootFolder'); }); }); $this->registerService('UserManager', function (Server $c) { @@ -629,7 +629,7 @@ class Server extends ServerContainer implements IServerContainer { return new Manager(); }); $this->registerService('CapabilitiesManager', function (Server $c) { - $manager = new \OC\CapabilitiesManager(); + $manager = new \OC\CapabilitiesManager($c->getLogger()); $manager->registerCapability(function () use ($c) { return new \OC\OCS\CoreCapabilities($c->getConfig()); }); @@ -643,19 +643,26 @@ class Server extends ServerContainer implements IServerContainer { return $factory->getManager(); }); $this->registerService('ThemingDefaults', function(Server $c) { - try { - $classExists = class_exists('OCA\Theming\Template'); - } catch (\OCP\AutoloadNotAllowedException $e) { - // App disabled or in maintenance mode + /* + * Dark magic for autoloader. + * If we do a class_exists it will try to load the class which will + * make composer cache the result. Resulting in errors when enabling + * the theming app. + */ + $prefixes = \OC::$composerAutoloader->getPrefixesPsr4(); + if (isset($prefixes['OCA\\Theming\\'])) { + $classExists = true; + } else { $classExists = false; } - if ($classExists && $this->getConfig()->getSystemValue('installed', false) && $this->getAppManager()->isInstalled('theming')) { - return new Template( - $this->getConfig(), - $this->getL10N('theming'), - $this->getURLGenerator(), - new \OC_Defaults() + if ($classExists && $c->getConfig()->getSystemValue('installed', false) && $c->getAppManager()->isInstalled('theming')) { + return new ThemingDefaults( + $c->getConfig(), + $c->getL10N('theming'), + $c->getURLGenerator(), + new \OC_Defaults(), + $c->getLazyRootFolder() ); } return new \OC_Defaults(); @@ -722,6 +729,18 @@ class Server extends ServerContainer implements IServerContainer { return $manager; }); + $this->registerService('SettingsManager', function(Server $c) { + $manager = new \OC\Settings\Manager( + $c->getLogger(), + $c->getDatabaseConnection(), + $c->getL10N('core'), + $c->getConfig(), + $c->getEncryptionManager(), + $c->getUserManager(), + $c->getLockingProvider() + ); + return $manager; + }); } /** @@ -820,7 +839,7 @@ class Server extends ServerContainer implements IServerContainer { * @return \OCP\Files\IRootFolder */ public function getRootFolder() { - return $this->query('RootFolder'); + return $this->query('LazyRootFolder'); } /** @@ -1277,6 +1296,11 @@ class Server extends ServerContainer implements IServerContainer { return $this->query('MountManager'); } + /** @return \OCP\Files\Config\IUserMountCache */ + function getUserMountCache() { + return $this->query('UserMountCache'); + } + /** * Get the MimeTypeDetector * @@ -1332,7 +1356,6 @@ class Server extends ServerContainer implements IServerContainer { } /** - * @internal Not public by intention. * @return \OC_Defaults */ public function getThemingDefaults() { @@ -1380,7 +1403,7 @@ class Server extends ServerContainer implements IServerContainer { * @return \OCA\Files_External\Service\BackendService */ public function getStoragesBackendService() { - return \OC_Mount_Config::$app->getContainer()->query('OCA\\Files_External\\Service\\BackendService'); + return $this->query('OCA\\Files_External\\Service\\BackendService'); } /** @@ -1389,7 +1412,7 @@ class Server extends ServerContainer implements IServerContainer { * @return \OCA\Files_External\Service\GlobalStoragesService */ public function getGlobalStoragesService() { - return \OC_Mount_Config::$app->getContainer()->query('OCA\\Files_External\\Service\\GlobalStoragesService'); + return $this->query('OCA\\Files_External\\Service\\GlobalStoragesService'); } /** @@ -1398,7 +1421,7 @@ class Server extends ServerContainer implements IServerContainer { * @return \OCA\Files_External\Service\UserGlobalStoragesService */ public function getUserGlobalStoragesService() { - return \OC_Mount_Config::$app->getContainer()->query('OCA\\Files_External\\Service\\UserGlobalStoragesService'); + return $this->query('OCA\\Files_External\\Service\\UserGlobalStoragesService'); } /** @@ -1407,7 +1430,7 @@ class Server extends ServerContainer implements IServerContainer { * @return \OCA\Files_External\Service\UserStoragesService */ public function getUserStoragesService() { - return \OC_Mount_Config::$app->getContainer()->query('OCA\\Files_External\\Service\\UserStoragesService'); + return $this->query('OCA\\Files_External\\Service\\UserStoragesService'); } /** @@ -1425,4 +1448,11 @@ class Server extends ServerContainer implements IServerContainer { public function getLDAPProvider() { return $this->query('LDAPProvider'); } + + /** + * @return \OCP\Settings\IManager + */ + public function getSettingsManager() { + return $this->query('SettingsManager'); + } } diff --git a/lib/private/ServerContainer.php b/lib/private/ServerContainer.php index 1bab2587e8d..df0293addf7 100644 --- a/lib/private/ServerContainer.php +++ b/lib/private/ServerContainer.php @@ -23,6 +23,7 @@ namespace OC; +use OC\AppFramework\App; use OC\AppFramework\DependencyInjection\DIContainer; use OC\AppFramework\Utility\SimpleContainer; use OCP\AppFramework\QueryException; @@ -49,7 +50,7 @@ class ServerContainer extends SimpleContainer { * @param DIContainer $container */ public function registerAppContainer($appName, DIContainer $container) { - $this->appContainers[$appName] = $container; + $this->appContainers[strtolower(App::buildAppNamespace($appName, ''))] = $container; } /** diff --git a/lib/private/Settings/Admin/Additional.php b/lib/private/Settings/Admin/Additional.php new file mode 100644 index 00000000000..d133e4737a7 --- /dev/null +++ b/lib/private/Settings/Admin/Additional.php @@ -0,0 +1,88 @@ +<?php +/** + * @copyright Copyright (c) 2016 Arthur Schiwon <blizzz@arthur-schiwon.de> + * + * @author Arthur Schiwon <blizzz@arthur-schiwon.de> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +namespace OC\Settings\Admin; + +use Doctrine\DBAL\Connection; +use Doctrine\DBAL\DBALException; +use Doctrine\DBAL\Platforms\SqlitePlatform; +use OC\Lock\DBLockingProvider; +use OC\Lock\NoopLockingProvider; +use OCP\AppFramework\Http\TemplateResponse; +use OCP\IConfig; +use OCP\IDBConnection; +use OCP\IL10N; +use OCP\Lock\ILockingProvider; +use OCP\Settings\ISettings; + +class Additional implements ISettings { + /** @var IConfig */ + private $config; + + /** + * @param IConfig $config + */ + public function __construct(IConfig $config) { + $this->config = $config; + } + + /** + * @return TemplateResponse + */ + public function getForm() { + $parameters = [ + // Mail + 'sendmail_is_available' => (bool) \OC_Helper::findBinaryPath('sendmail'), + 'mail_domain' => $this->config->getSystemValue('mail_domain', ''), + 'mail_from_address' => $this->config->getSystemValue('mail_from_address', ''), + 'mail_smtpmode' => $this->config->getSystemValue('mail_smtpmode', ''), + 'mail_smtpsecure' => $this->config->getSystemValue('mail_smtpsecure', ''), + 'mail_smtphost' => $this->config->getSystemValue('mail_smtphost', ''), + 'mail_smtpport' => $this->config->getSystemValue('mail_smtpport', ''), + 'mail_smtpauthtype' => $this->config->getSystemValue('mail_smtpauthtype', ''), + 'mail_smtpauth' => $this->config->getSystemValue('mail_smtpauth', false), + 'mail_smtpname' => $this->config->getSystemValue('mail_smtpname', ''), + 'mail_smtppassword' => $this->config->getSystemValue('mail_smtppassword', ''), + ]; + + return new TemplateResponse('settings', 'admin/additional-mail', $parameters, ''); + } + + /** + * @return string the section ID, e.g. 'sharing' + */ + public function getSection() { + return 'additional'; + } + + /** + * @return int whether the form should be rather on the top or bottom of + * the admin section. The forms are arranged in ascending order of the + * priority values. It is required to return a value between 0 and 100. + * + * E.g.: 70 + */ + public function getPriority() { + return 0; + } +} diff --git a/lib/private/Settings/Admin/Encryption.php b/lib/private/Settings/Admin/Encryption.php new file mode 100644 index 00000000000..6e93407f1a3 --- /dev/null +++ b/lib/private/Settings/Admin/Encryption.php @@ -0,0 +1,91 @@ +<?php +/** + * @copyright Copyright (c) 2016 Arthur Schiwon <blizzz@arthur-schiwon.de> + * + * @author Arthur Schiwon <blizzz@arthur-schiwon.de> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +namespace OC\Settings\Admin; + +use OC\Encryption\Manager; +use OCP\AppFramework\Http\TemplateResponse; +use OCP\IUserManager; +use OCP\Settings\ISettings; + +class Encryption implements ISettings { + /** @var Manager */ + private $manager; + + /** @var IUserManager */ + private $userManager; + + /** + * @param Manager $manager + * @param IUserManager $userManager + */ + public function __construct(Manager $manager, IUserManager $userManager) { + $this->manager = $manager; + $this->userManager = $userManager; + } + + /** + * @return TemplateResponse + */ + public function getForm() { + $encryptionModules = $this->manager->getEncryptionModules(); + $defaultEncryptionModuleId = $this->manager->getDefaultEncryptionModuleId(); + $encryptionModuleList = []; + foreach ($encryptionModules as $module) { + $encryptionModuleList[$module['id']]['displayName'] = $module['displayName']; + $encryptionModuleList[$module['id']]['default'] = false; + if ($module['id'] === $defaultEncryptionModuleId) { + $encryptionModuleList[$module['id']]['default'] = true; + } + } + + $parameters = [ + // Encryption API + 'encryptionEnabled' => $this->manager->isEnabled(), + 'encryptionReady' => $this->manager->isReady(), + 'externalBackendsEnabled' => count($this->userManager->getBackends()) > 1, + // Modules + 'encryptionModules' => $encryptionModuleList, + ]; + + return new TemplateResponse('settings', 'admin/encryption', $parameters, ''); + } + + /** + * @return string the section ID, e.g. 'sharing' + */ + public function getSection() { + return 'encryption'; + } + + /** + * @return int whether the form should be rather on the top or bottom of + * the admin section. The forms are arranged in ascending order of the + * priority values. It is required to return a value between 0 and 100. + * + * E.g.: 70 + */ + public function getPriority() { + return 0; + } +} diff --git a/lib/private/Settings/Admin/Logging.php b/lib/private/Settings/Admin/Logging.php new file mode 100644 index 00000000000..407248ac4b1 --- /dev/null +++ b/lib/private/Settings/Admin/Logging.php @@ -0,0 +1,86 @@ +<?php +/** + * @copyright Copyright (c) 2016 Arthur Schiwon <blizzz@arthur-schiwon.de> + * + * @author Arthur Schiwon <blizzz@arthur-schiwon.de> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +namespace OC\Settings\Admin; + +use OC\Log\File as LogFile; +use OCP\AppFramework\Http\TemplateResponse; +use OCP\IConfig; +use OCP\Settings\ISettings; + +class Logging implements ISettings { + /** @var IConfig */ + private $config; + + /** + * @param IConfig $config + */ + public function __construct(IConfig $config) { + $this->config = $config; + } + + /** + * @return TemplateResponse + */ + public function getForm() { + $logType = $this->config->getSystemValue('log_type', 'file'); + $showLog = ($logType === 'file' || $logType === 'owncloud'); + + $numEntriesToLoad = 5; + $entries = LogFile::getEntries($numEntriesToLoad + 1); + $entriesRemaining = count($entries) > $numEntriesToLoad; + $entries = array_slice($entries, 0, $numEntriesToLoad); + + $logFileExists = file_exists(LogFile::getLogFilePath()) ; + $logFileSize = $logFileExists ? filesize(LogFile::getLogFilePath()) : 0; + + $parameters = [ + 'loglevel' => $this->config->getSystemValue('loglevel', 2), + 'entries' => $entries, + 'entriesremain' => $entriesRemaining, + 'doesLogFileExist' => $logFileExists, + 'logFileSize' => $logFileSize, + 'showLog' => $showLog, + ]; + + return new TemplateResponse('settings', 'admin/logging', $parameters, ''); + } + + /** + * @return string the section ID, e.g. 'sharing' + */ + public function getSection() { + return 'logging'; + } + + /** + * @return int whether the form should be rather on the top or bottom of + * the admin section. The forms are arranged in ascending order of the + * priority values. It is required to return a value between 0 and 100. + * + * E.g.: 70 + */ + public function getPriority() { + return 0; + } +} diff --git a/lib/private/Settings/Admin/Server.php b/lib/private/Settings/Admin/Server.php new file mode 100644 index 00000000000..6b381ab48ed --- /dev/null +++ b/lib/private/Settings/Admin/Server.php @@ -0,0 +1,149 @@ +<?php +/** + * @copyright Copyright (c) 2016 Arthur Schiwon <blizzz@arthur-schiwon.de> + * + * @author Arthur Schiwon <blizzz@arthur-schiwon.de> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +namespace OC\Settings\Admin; + +use Doctrine\DBAL\Connection; +use Doctrine\DBAL\DBALException; +use Doctrine\DBAL\Platforms\SqlitePlatform; +use OC\Lock\DBLockingProvider; +use OC\Lock\NoopLockingProvider; +use OCP\AppFramework\Http\TemplateResponse; +use OCP\IConfig; +use OCP\IDBConnection; +use OCP\IL10N; +use OCP\Lock\ILockingProvider; +use OCP\Settings\ISettings; + +class Server implements ISettings { + /** @var IDBConnection|Connection */ + private $db; + /** @var IConfig */ + private $config; + /** @var ILockingProvider */ + private $lockingProvider; + /** @var IL10N */ + private $l; + + /** + * @param IDBConnection $db + * @param IConfig $config + * @param ILockingProvider $lockingProvider + * @param IL10N $l + */ + public function __construct(IDBConnection $db, + IConfig $config, + ILockingProvider $lockingProvider, + IL10N $l) { + $this->db = $db; + $this->config = $config; + $this->lockingProvider = $lockingProvider; + $this->l = $l; + } + + /** + * @return TemplateResponse + */ + public function getForm() { + try { + if ($this->db->getDatabasePlatform() instanceof SqlitePlatform) { + $invalidTransactionIsolationLevel = false; + } else { + $invalidTransactionIsolationLevel = $this->db->getTransactionIsolation() !== Connection::TRANSACTION_READ_COMMITTED; + } + } catch (DBALException $e) { + // ignore + $invalidTransactionIsolationLevel = false; + } + + $envPath = getenv('PATH'); + + // warn if outdated version of a memcache module is used + $caches = [ + 'apcu' => ['name' => $this->l->t('APCu'), 'version' => '4.0.6'], + 'redis' => ['name' => $this->l->t('Redis'), 'version' => '2.2.5'], + ]; + $outdatedCaches = []; + foreach ($caches as $php_module => $data) { + $isOutdated = extension_loaded($php_module) && version_compare(phpversion($php_module), $data['version'], '<'); + if ($isOutdated) { + $outdatedCaches[$php_module] = $data; + } + } + + if ($this->lockingProvider instanceof NoopLockingProvider) { + $fileLockingType = 'none'; + } else if ($this->lockingProvider instanceof DBLockingProvider) { + $fileLockingType = 'db'; + } else { + $fileLockingType = 'cache'; + } + + // If the current web root is non-empty but the web root from the config is, + // and system cron is used, the URL generator fails to build valid URLs. + $shouldSuggestOverwriteCliUrl = $this->config->getAppValue('core', 'backgroundjobs_mode', 'ajax') === 'cron' + && \OC::$WEBROOT && \OC::$WEBROOT !== '/' + && !$this->config->getSystemValue('overwrite.cli.url', ''); + $suggestedOverwriteCliUrl = ($shouldSuggestOverwriteCliUrl) ? \OC::$WEBROOT : ''; + + $parameters = [ + // Diagnosis + 'readOnlyConfigEnabled' => \OC_Helper::isReadOnlyConfigEnabled(), + 'isLocaleWorking' => \OC_Util::isSetLocaleWorking(), + 'isAnnotationsWorking' => \OC_Util::isAnnotationsWorking(), + 'checkForWorkingWellKnownSetup' => $this->config->getSystemValue('check_for_working_wellknown_setup', true), + 'has_fileinfo' => \OC_Util::fileInfoLoaded(), + 'invalidTransactionIsolationLevel' => $invalidTransactionIsolationLevel, + 'getenvServerNotWorking' => empty($envPath), + 'OutdatedCacheWarning' => $outdatedCaches, + 'fileLockingType' => $fileLockingType, + 'suggestedOverwriteCliUrl' => $suggestedOverwriteCliUrl, + + // Background jobs + 'backgroundjobs_mode' => $this->config->getAppValue('core', 'backgroundjobs_mode', 'ajax'), + 'cron_log' => $this->config->getSystemValue('cron_log', true), + 'lastcron' => $this->config->getAppValue('core', 'lastcron', false), + 'cronErrors' => $this->config->getAppValue('core', 'cronErrors'), + ]; + + return new TemplateResponse('settings', 'admin/server', $parameters, ''); + } + + /** + * @return string the section ID, e.g. 'sharing' + */ + public function getSection() { + return 'server'; + } + + /** + * @return int whether the form should be rather on the top or bottom of + * the admin section. The forms are arranged in ascending order of the + * priority values. It is required to return a value between 0 and 100. + * + * E.g.: 70 + */ + public function getPriority() { + return 0; + } +} diff --git a/lib/private/Settings/Admin/Sharing.php b/lib/private/Settings/Admin/Sharing.php new file mode 100644 index 00000000000..8d3ddc9b3b5 --- /dev/null +++ b/lib/private/Settings/Admin/Sharing.php @@ -0,0 +1,90 @@ +<?php +/** + * @copyright Copyright (c) 2016 Arthur Schiwon <blizzz@arthur-schiwon.de> + * + * @author Arthur Schiwon <blizzz@arthur-schiwon.de> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +namespace OC\Settings\Admin; + +use OC\Share\Share; +use OCP\AppFramework\Http\TemplateResponse; +use OCP\IConfig; +use OCP\Settings\ISettings; +use OCP\Util; + +class Sharing implements ISettings { + /** @var IConfig */ + private $config; + + /** + * @param IConfig $config + */ + public function __construct(IConfig $config) { + $this->config = $config; + } + + /** + * @return TemplateResponse + */ + public function getForm() { + $excludedGroups = $this->config->getAppValue('core', 'shareapi_exclude_groups_list', ''); + $excludeGroupsList = !is_null(json_decode($excludedGroups)) + ? implode('|', json_decode($excludedGroups, true)) : ''; + + $parameters = [ + // Built-In Sharing + 'allowGroupSharing' => $this->config->getAppValue('core', 'shareapi_allow_group_sharing', 'yes'), + 'allowLinks' => $this->config->getAppValue('core', 'shareapi_allow_links', 'yes'), + 'allowMailNotification' => $this->config->getAppValue('core', 'shareapi_allow_mail_notification', 'no'), + 'allowPublicMailNotification' => $this->config->getAppValue('core', 'shareapi_allow_public_notification', 'no'), + 'allowPublicUpload' => $this->config->getAppValue('core', 'shareapi_allow_public_upload', 'yes'), + 'allowResharing' => $this->config->getAppValue('core', 'shareapi_allow_resharing', 'yes'), + 'allowShareDialogUserEnumeration' => $this->config->getAppValue('core', 'shareapi_allow_share_dialog_user_enumeration', 'yes'), + 'enforceLinkPassword' => Util::isPublicLinkPasswordRequired(), + 'onlyShareWithGroupMembers' => Share::shareWithGroupMembersOnly(), + 'shareAPIEnabled' => $this->config->getAppValue('core', 'shareapi_enabled', 'yes'), + 'shareDefaultExpireDateSet' => $this->config->getAppValue('core', 'shareapi_default_expire_date', 'no'), + 'shareExpireAfterNDays' => $this->config->getAppValue('core', 'shareapi_expire_after_n_days', '7'), + 'shareEnforceExpireDate' => $this->config->getAppValue('core', 'shareapi_enforce_expire_date', 'no'), + 'shareExcludeGroups' => $this->config->getAppValue('core', 'shareapi_exclude_groups', 'no') === 'yes' ? true : false, + 'shareExcludedGroupsList' => $excludeGroupsList, + ]; + + return new TemplateResponse('settings', 'admin/sharing', $parameters, ''); + } + + /** + * @return string the section ID, e.g. 'sharing' + */ + public function getSection() { + return 'sharing'; + } + + /** + * @return int whether the form should be rather on the top or bottom of + * the admin section. The forms are arranged in ascending order of the + * priority values. It is required to return a value between 0 and 100. + * + * E.g.: 70 + */ + public function getPriority() { + return 0; + } +} diff --git a/lib/private/Settings/Admin/TipsTricks.php b/lib/private/Settings/Admin/TipsTricks.php new file mode 100644 index 00000000000..fd0fd595844 --- /dev/null +++ b/lib/private/Settings/Admin/TipsTricks.php @@ -0,0 +1,71 @@ +<?php +/** + * @copyright Copyright (c) 2016 Arthur Schiwon <blizzz@arthur-schiwon.de> + * + * @author Arthur Schiwon <blizzz@arthur-schiwon.de> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +namespace OC\Settings\Admin; + +use OCP\AppFramework\Http\TemplateResponse; +use OCP\IConfig; +use OCP\Settings\ISettings; + +class TipsTricks implements ISettings { + /** @var IConfig */ + private $config; + + /** + * @param IConfig $config + */ + public function __construct(IConfig $config) { + $this->config = $config; + } + + /** + * @return TemplateResponse + */ + public function getForm() { + $databaseOverload = (strpos($this->config->getSystemValue('dbtype'), 'sqlite') !== false); + + $parameters = [ + 'databaseOverload' => $databaseOverload, + ]; + + return new TemplateResponse('settings', 'admin/tipstricks', $parameters, ''); + } + + /** + * @return string the section ID, e.g. 'sharing' + */ + public function getSection() { + return 'tips-tricks'; + } + + /** + * @return int whether the form should be rather on the top or bottom of + * the admin section. The forms are arranged in ascending order of the + * priority values. It is required to return a value between 0 and 100. + * + * E.g.: 70 + */ + public function getPriority() { + return 0; + } +} diff --git a/lib/private/Settings/Manager.php b/lib/private/Settings/Manager.php new file mode 100644 index 00000000000..df2f52f816d --- /dev/null +++ b/lib/private/Settings/Manager.php @@ -0,0 +1,435 @@ +<?php +/** + * @copyright Copyright (c) 2016 Arthur Schiwon <blizzz@arthur-schiwon.de> + * + * @author Arthur Schiwon <blizzz@arthur-schiwon.de> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +namespace OC\Settings; + +use OCP\AppFramework\QueryException; +use OCP\Encryption\IManager as EncryptionManager; +use OCP\IConfig; +use OCP\IDBConnection; +use OCP\IL10N; +use OCP\ILogger; +use OCP\IUserManager; +use OCP\Lock\ILockingProvider; +use OCP\Settings\ISettings; +use OCP\Settings\IManager; +use OCP\Settings\ISection; + +class Manager implements IManager { + const TABLE_ADMIN_SETTINGS = 'admin_settings'; + const TABLE_ADMIN_SECTIONS = 'admin_sections'; + + /** @var ILogger */ + private $log; + /** @var IDBConnection */ + private $dbc; + /** @var IL10N */ + private $l; + /** @var IConfig */ + private $config; + /** @var EncryptionManager */ + private $encryptionManager; + /** @var IUserManager */ + private $userManager; + /** @var ILockingProvider */ + private $lockingProvider; + + /** + * @param ILogger $log + * @param IDBConnection $dbc + * @param IL10N $l + * @param IConfig $config + * @param EncryptionManager $encryptionManager + * @param IUserManager $userManager + * @param ILockingProvider $lockingProvider + */ + public function __construct( + ILogger $log, + IDBConnection $dbc, + IL10N $l, + IConfig $config, + EncryptionManager $encryptionManager, + IUserManager $userManager, + ILockingProvider $lockingProvider + ) { + $this->log = $log; + $this->dbc = $dbc; + $this->l = $l; + $this->config = $config; + $this->encryptionManager = $encryptionManager; + $this->userManager = $userManager; + $this->lockingProvider = $lockingProvider; + } + + /** + * @inheritdoc + */ + public function setupSettings(array $settings) { + if(isset($settings[IManager::KEY_ADMIN_SECTION])) { + $this->setupAdminSection($settings[IManager::KEY_ADMIN_SECTION]); + } + if(isset($settings[IManager::KEY_ADMIN_SETTINGS])) { + $this->setupAdminSettings($settings[IManager::KEY_ADMIN_SETTINGS]); + } + } + + /** + * attempts to remove an apps section and/or settings entry. A listener is + * added centrally making sure that this method is called ones an app was + * disabled. + * + * @param string $appId + * @since 9.1.0 + */ + public function onAppDisabled($appId) { + $appInfo = \OC_App::getAppInfo($appId); // hello static legacy + + if(isset($appInfo['settings'][IManager::KEY_ADMIN_SECTION])) { + $this->remove(self::TABLE_ADMIN_SECTIONS, $appInfo['settings'][IManager::KEY_ADMIN_SECTION]); + } + if(isset($appInfo['settings'][IManager::KEY_ADMIN_SETTINGS])) { + $this->remove(self::TABLE_ADMIN_SETTINGS, $appInfo['settings'][IManager::KEY_ADMIN_SETTINGS]); + } + } + + public function checkForOrphanedClassNames() { + $tables = [ self::TABLE_ADMIN_SECTIONS, self::TABLE_ADMIN_SETTINGS ]; + foreach ($tables as $table) { + $classes = $this->getClasses($table); + foreach($classes as $className) { + try { + \OC::$server->query($className); + } catch (QueryException $e) { + $this->remove($table, $className); + } + } + } + } + + /** + * returns the registerd classes in the given table + * + * @param $table + * @return string[] + */ + private function getClasses($table) { + $q = $this->dbc->getQueryBuilder(); + $resultStatement = $q->select('class') + ->from($table) + ->execute(); + $data = $resultStatement->fetchAll(); + $resultStatement->closeCursor(); + + return array_map(function($row) { return $row['class']; }, $data); + } + + /** + * @param string $sectionClassName + */ + private function setupAdminSection($sectionClassName) { + if(!class_exists($sectionClassName)) { + $this->log->debug('Could not find admin section class ' . $sectionClassName); + return; + } + try { + $section = $this->query($sectionClassName); + } catch (QueryException $e) { + // cancel + return; + } + + if(!$section instanceof ISection) { + $this->log->error( + 'Admin section instance must implement \OCP\ISection. Invalid class: {class}', + ['class' => $sectionClassName] + ); + return; + } + if(!$this->hasAdminSection(get_class($section))) { + $this->addAdminSection($section); + } else { + $this->updateAdminSection($section); + } + } + + private function addAdminSection(ISection $section) { + $this->add(self::TABLE_ADMIN_SECTIONS, [ + 'id' => $section->getID(), + 'class' => get_class($section), + 'priority' => $section->getPriority(), + ]); + } + + private function addAdminSettings(ISettings $settings) { + $this->add(self::TABLE_ADMIN_SETTINGS, [ + 'class' => get_class($settings), + 'section' => $settings->getSection(), + 'priority' => $settings->getPriority(), + ]); + } + + /** + * @param string $table + * @param array $values + */ + private function add($table, array $values) { + $query = $this->dbc->getQueryBuilder(); + $values = array_map(function($value) use ($query) { + return $query->createNamedParameter($value); + }, $values); + $query->insert($table)->values($values); + $query->execute(); + } + + private function updateAdminSettings(ISettings $settings) { + $this->update( + self::TABLE_ADMIN_SETTINGS, + 'class', + get_class($settings), + [ + 'section' => $settings->getSection(), + 'priority' => $settings->getPriority(), + ] + ); + } + + private function updateAdminSection(ISection $section) { + $this->update( + self::TABLE_ADMIN_SECTIONS, + 'class', + get_class($section), + [ + 'id' => $section->getID(), + 'priority' => $section->getPriority(), + ] + ); + } + + private function update($table, $idCol, $id, $values) { + $query = $this->dbc->getQueryBuilder(); + $query->update($table); + foreach($values as $key => $value) { + $query->set($key, $query->createNamedParameter($value)); + } + $query + ->where($query->expr()->eq($idCol, $query->createParameter($idCol))) + ->setParameter($idCol, $id) + ->execute(); + } + + /** + * @param string $className + * @return bool + */ + private function hasAdminSection($className) { + return $this->has(self::TABLE_ADMIN_SECTIONS, $className); + } + + /** + * @param string $className + * @return bool + */ + private function hasAdminSettings($className) { + return $this->has(self::TABLE_ADMIN_SETTINGS, $className); + } + + /** + * @param string $table + * @param string $className + * @return bool + */ + private function has($table, $className) { + $query = $this->dbc->getQueryBuilder(); + $query->select('class') + ->from($table) + ->where($query->expr()->eq('class', $query->createNamedParameter($className))) + ->setMaxResults(1); + + $result = $query->execute(); + $row = $result->fetch(); + $result->closeCursor(); + + return (bool) $row; + } + + /** + * deletes an settings or admin entry from the given table + * + * @param $table + * @param $className + */ + private function remove($table, $className) { + $query = $this->dbc->getQueryBuilder(); + $query->delete($table) + ->where($query->expr()->eq('class', $query->createNamedParameter($className))); + + $query->execute(); + } + + private function setupAdminSettings($settingsClassName) { + if(!class_exists($settingsClassName)) { + $this->log->debug('Could not find admin section class ' . $settingsClassName); + return; + } + + try { + /** @var ISettings $settings */ + $settings = $this->query($settingsClassName); + } catch (QueryException $e) { + // cancel + return; + } + + if(!$settings instanceof ISettings) { + $this->log->error( + 'Admin section instance must implement \OCP\ISection. Invalid class: {class}', + ['class' => $settingsClassName] + ); + return; + } + if(!$this->hasAdminSettings(get_class($settings))) { + $this->addAdminSettings($settings); + } else { + $this->updateAdminSettings($settings); + } + } + + private function query($className) { + try { + return \OC::$server->query($className); + } catch (QueryException $e) { + $this->log->logException($e); + throw $e; + } + } + + /** + * @inheritdoc + */ + public function getAdminSections() { + // built-in sections + $sections = [ + 0 => [new Section('server', $this->l->t('Server settings'), 0)], + 5 => [new Section('sharing', $this->l->t('Sharing'), 0)], + 45 => [new Section('encryption', $this->l->t('Encryption'), 0)], + 90 => [new Section('logging', $this->l->t('Logging'), 0)], + 98 => [new Section('additional', $this->l->t('Additional settings'), 0)], + 99 => [new Section('tips-tricks', $this->l->t('Tips & tricks'), 0)], + ]; + + $query = $this->dbc->getQueryBuilder(); + $query->selectDistinct('s.class') + ->addSelect('s.priority') + ->from(self::TABLE_ADMIN_SECTIONS, 's') + ->from(self::TABLE_ADMIN_SETTINGS, 'f') + ->where($query->expr()->eq('s.id', 'f.section')) + ; + $result = $query->execute(); + + while($row = $result->fetch()) { + if(!isset($sections[$row['priority']])) { + $sections[$row['priority']] = []; + } + try { + $sections[$row['priority']][] = $this->query($row['class']); + } catch (QueryException $e) { + // skip + } + } + $result->closeCursor(); + + ksort($sections); + return $sections; + } + + private function getBuiltInAdminSettings($section) { + $forms = []; + try { + if($section === 'server') { + /** @var ISettings $form */ + $form = new Admin\Server($this->dbc, $this->config, $this->lockingProvider, $this->l); + $forms[$form->getPriority()] = [$form]; + } + if($section === 'encryption') { + /** @var ISettings $form */ + $form = new Admin\Encryption($this->encryptionManager, $this->userManager); + $forms[$form->getPriority()] = [$form]; + } + if($section === 'sharing') { + /** @var ISettings $form */ + $form = new Admin\Sharing($this->config); + $forms[$form->getPriority()] = [$form]; + } + if($section === 'logging') { + /** @var ISettings $form */ + $form = new Admin\Logging($this->config); + $forms[$form->getPriority()] = [$form]; + } + if($section === 'additional') { + /** @var ISettings $form */ + $form = new Admin\Additional($this->config); + $forms[$form->getPriority()] = [$form]; + } + if($section === 'tips-tricks') { + /** @var ISettings $form */ + $form = new Admin\TipsTricks($this->config); + $forms[$form->getPriority()] = [$form]; + } + } catch (QueryException $e) { + // skip + } + return $forms; + } + + private function getAdminSettingsFromDB($section, &$settings) { + $query = $this->dbc->getQueryBuilder(); + $query->select(['class', 'priority']) + ->from(self::TABLE_ADMIN_SETTINGS) + ->where($query->expr()->eq('section', $this->dbc->getQueryBuilder()->createParameter('section'))) + ->setParameter('section', $section); + + $result = $query->execute(); + while($row = $result->fetch()) { + if(!isset($settings[$row['priority']])) { + $settings[$row['priority']] = []; + } + try { + $settings[$row['priority']][] = $this->query($row['class']); + } catch (QueryException $e) { + // skip + } + } + $result->closeCursor(); + + ksort($settings); + } + + /** + * @inheritdoc + */ + public function getAdminSettings($section) { + $settings = $this->getBuiltInAdminSettings($section); + $this->getAdminSettingsFromDB($section, $settings); + return $settings; + } +} diff --git a/lib/private/Settings/RemoveOrphaned.php b/lib/private/Settings/RemoveOrphaned.php new file mode 100644 index 00000000000..fbee95c8879 --- /dev/null +++ b/lib/private/Settings/RemoveOrphaned.php @@ -0,0 +1,91 @@ +<?php +/** + * @copyright Copyright (c) 2016 Arthur Schiwon <blizzz@arthur-schiwon.de> + * + * @author Arthur Schiwon <blizzz@arthur-schiwon.de> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +namespace OC\Settings; + +use OC\BackgroundJob\JobList; +use OC\BackgroundJob\TimedJob; +use OC\NeedsUpdateException; +use OCP\BackgroundJob\IJobList; +use OCP\ILogger; + +/** + * Class RemoveOrphaned + * + * @package OC\Settings + */ +class RemoveOrphaned extends TimedJob { + + /** @var IJobList */ + private $jobList; + + /** @var ILogger */ + private $logger; + + /** @var Manager */ + private $manager; + + public function __construct(Manager $manager = null) { + if($manager !== null) { + $this->manager = $manager; + } else { + // fix DI for Jobs + $this->manager = \OC::$server->getSettingsManager(); + } + } + + /** + * run the job, then remove it from the job list + * + * @param JobList $jobList + * @param ILogger $logger + */ + public function execute($jobList, ILogger $logger = null) { + // add an interval of 15 mins + $this->setInterval(15*60); + + $this->jobList = $jobList; + $this->logger = $logger; + parent::execute($jobList, $logger); + } + + /** + * @param array $argument + * @throws \Exception + * @throws \OC\NeedsUpdateException + */ + protected function run($argument) { + try { + \OC_App::loadApps(); + } catch (NeedsUpdateException $ex) { + // only run when apps are up to date + return; + } + + $this->manager->checkForOrphanedClassNames(); + + // remove the job once executed successfully + $this->jobList->remove($this); + } + +} diff --git a/lib/private/Settings/Section.php b/lib/private/Settings/Section.php new file mode 100644 index 00000000000..b3cf242279f --- /dev/null +++ b/lib/private/Settings/Section.php @@ -0,0 +1,77 @@ +<?php +/** + * @copyright Copyright (c) 2016 Arthur Schiwon <blizzz@arthur-schiwon.de> + * + * @author Arthur Schiwon <blizzz@arthur-schiwon.de> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +namespace OC\Settings; + +use OCP\Settings\ISection; + +class Section implements ISection { + /** @var string */ + private $id; + /** @var string */ + private $name; + /** @var int */ + private $priority; + + /** + * @param string $id + * @param string $name + * @param int $priority + */ + public function __construct($id, $name, $priority) { + $this->id = $id; + $this->name = $name; + $this->priority = $priority; + } + + /** + * returns the ID of the section. It is supposed to be a lower case string, + * e.g. 'ldap' + * + * @returns string + */ + public function getID() { + return $this->id; + } + + /** + * returns the translated name as it should be displayed, e.g. 'LDAP / AD + * integration'. Use the L10N service to translate it. + * + * @return string + */ + public function getName() { + return $this->name; + } + + /** + * @return int whether the form should be rather on the top or bottom of + * the settings navigation. The sections are arranged in ascending order of + * the priority values. It is required to return a value between 0 and 99. + * + * E.g.: 70 + */ + public function getPriority() { + return $this->priority; + } +} diff --git a/lib/private/TemplateLayout.php b/lib/private/TemplateLayout.php index 9e3bbf88470..7e5c120717f 100644 --- a/lib/private/TemplateLayout.php +++ b/lib/private/TemplateLayout.php @@ -153,6 +153,7 @@ class TemplateLayout extends \OC_Template { $cssFiles = self::findStylesheetFiles(\OC_Util::$styles); $this->assign('cssfiles', array()); $this->assign('printcssfiles', []); + $this->assign('versionHash', self::$versionHash); foreach($cssFiles as $info) { $web = $info[1]; $file = $info[2]; diff --git a/lib/private/User/Backend.php b/lib/private/User/Backend.php index da86a4b0534..374ec5876e1 100644 --- a/lib/private/User/Backend.php +++ b/lib/private/User/Backend.php @@ -22,11 +22,13 @@ namespace OC\User; +use \OCP\UserInterface; + /** * Abstract base class for user management. Provides methods for querying backend * capabilities. */ -abstract class Backend implements \OCP\UserInterface { +abstract class Backend implements UserInterface { /** * error code for functions not provided by the user backend */ diff --git a/lib/private/User/Database.php b/lib/private/User/Database.php index e2cbebab2e4..eba7beffeae 100644 --- a/lib/private/User/Database.php +++ b/lib/private/User/Database.php @@ -53,19 +53,25 @@ namespace OC\User; use OC\Cache\CappedMemoryCache; +use OCP\IUserBackend; +use OCP\Util; use Symfony\Component\EventDispatcher\EventDispatcher; use Symfony\Component\EventDispatcher\GenericEvent; /** * Class for user management in a SQL Database (e.g. MySQL, SQLite) */ -class Database extends \OC\User\Backend implements \OCP\IUserBackend { +class Database extends Backend implements IUserBackend { /** @var CappedMemoryCache */ private $cache; + /** @var EventDispatcher */ private $eventDispatcher; + /** - * OC_User_Database constructor. + * \OC\User\Database constructor. + * + * @param EventDispatcher $eventDispatcher */ public function __construct($eventDispatcher = null) { $this->cache = new CappedMemoryCache(); @@ -233,7 +239,7 @@ class Database extends \OC\User\Backend implements \OCP\IUserBackend { $result = $query->execute(array($uid)); if ($result === false) { - \OCP\Util::writeLog('core', \OC_DB::getErrorMessage(), \OCP\Util::ERROR); + Util::writeLog('core', \OC_DB::getErrorMessage(), Util::ERROR); return false; } @@ -310,7 +316,7 @@ class Database extends \OC\User\Backend implements \OCP\IUserBackend { $query = \OC_DB::prepare('SELECT COUNT(*) FROM `*PREFIX*users`'); $result = $query->execute(); if ($result === false) { - \OCP\Util::writeLog('core', \OC_DB::getErrorMessage(), \OCP\Util::ERROR); + Util::writeLog('core', \OC_DB::getErrorMessage(), Util::ERROR); return false; } return $result->fetchOne(); @@ -345,7 +351,7 @@ class Database extends \OC\User\Backend implements \OCP\IUserBackend { $backends = \OC::$server->getUserManager()->getBackends(); foreach ($backends as $backend) { - if ($backend instanceof \OC\User\Database) { + if ($backend instanceof Database) { /** @var \OC\User\Database $backend */ $uid = $backend->loginName2UserName($param['uid']); if ($uid !== false) { diff --git a/lib/private/User/Manager.php b/lib/private/User/Manager.php index eb2f1ce1da3..f41468d4926 100644 --- a/lib/private/User/Manager.php +++ b/lib/private/User/Manager.php @@ -187,7 +187,7 @@ class Manager extends PublicEmitter implements IUserManager { $password = str_replace("\0", '', $password); foreach ($this->backends as $backend) { - if ($backend->implementsActions(\OC\User\Backend::CHECK_PASSWORD)) { + if ($backend->implementsActions(Backend::CHECK_PASSWORD)) { $uid = $backend->checkPassword($loginName, $password); if ($uid !== false) { return $this->getUserObject($uid, $backend); @@ -291,7 +291,7 @@ class Manager extends PublicEmitter implements IUserManager { $this->emit('\OC\User', 'preCreateUser', array($uid, $password)); foreach ($this->backends as $backend) { - if ($backend->implementsActions(\OC\User\Backend::CREATE_USER)) { + if ($backend->implementsActions(Backend::CREATE_USER)) { $backend->createUser($uid, $password); $user = $this->getUserObject($uid, $backend); $this->emit('\OC\User', 'postCreateUser', array($user, $password)); @@ -309,7 +309,7 @@ class Manager extends PublicEmitter implements IUserManager { public function countUsers() { $userCountStatistics = array(); foreach ($this->backends as $backend) { - if ($backend->implementsActions(\OC\User\Backend::COUNT_USERS)) { + if ($backend->implementsActions(Backend::COUNT_USERS)) { $backendUsers = $backend->countUsers(); if($backendUsers !== false) { if($backend instanceof IUserBackend) { diff --git a/lib/private/User/Session.php b/lib/private/User/Session.php index 3db6cd1a11a..3b357b69bcf 100644 --- a/lib/private/User/Session.php +++ b/lib/private/User/Session.php @@ -167,7 +167,7 @@ class Session implements IUserSession, Emitter { /** * set the currently active user * - * @param User|null $user + * @param IUser|null $user */ public function setUser($user) { if (is_null($user)) { @@ -287,10 +287,8 @@ class Session implements IUserSession, Emitter { $this->session->regenerateId(); if ($this->validateToken($password, $uid)) { return $this->loginWithToken($password); - } else { - return $this->loginWithPassword($uid, $password); } - return false; + return $this->loginWithPassword($uid, $password); } /** @@ -464,7 +462,6 @@ class Session implements IUserSession, Emitter { $message = \OC::$server->getL10N('lib')->t('User disabled'); throw new LoginException($message); } - return false; } /** @@ -652,6 +649,7 @@ class Session implements IUserSession, Emitter { /** * Tries to login the user with auth token header * + * @param IRequest $request * @todo check remember me cookie * @return boolean */ diff --git a/lib/private/User/User.php b/lib/private/User/User.php index 4d403535bf3..94ac8c13621 100644 --- a/lib/private/User/User.php +++ b/lib/private/User/User.php @@ -30,6 +30,7 @@ namespace OC\User; +use OC\Files\Cache\Storage; use OC\Hooks\Emitter; use OC_Helper; use OCP\IAvatarManager; @@ -38,6 +39,7 @@ use OCP\IURLGenerator; use OCP\IUser; use OCP\IConfig; use OCP\UserInterface; +use \OCP\IUserBackend; class User implements IUser { /** @var string $uid */ @@ -111,7 +113,7 @@ class User implements IUser { public function getDisplayName() { if (!isset($this->displayName)) { $displayName = ''; - if ($this->backend and $this->backend->implementsActions(\OC\User\Backend::GET_DISPLAYNAME)) { + if ($this->backend and $this->backend->implementsActions(Backend::GET_DISPLAYNAME)) { // get display name and strip whitespace from the beginning and end of it $backendDisplayName = $this->backend->getDisplayName($this->uid); if (is_string($backendDisplayName)) { @@ -136,7 +138,7 @@ class User implements IUser { */ public function setDisplayName($displayName) { $displayName = trim($displayName); - if ($this->backend->implementsActions(\OC\User\Backend::SET_DISPLAYNAME) && !empty($displayName)) { + if ($this->backend->implementsActions(Backend::SET_DISPLAYNAME) && !empty($displayName)) { $result = $this->backend->setDisplayName($this->uid, $displayName); if ($result) { $this->displayName = $displayName; @@ -198,17 +200,17 @@ class User implements IUser { // FIXME: Feels like an hack - suggestions? // We have to delete the user from all groups - foreach (\OC_Group::getUserGroups($this->uid) as $i) { - \OC_Group::removeFromGroup($this->uid, $i); + foreach (\OC::$server->getGroupManager()->getUserGroupIds($this) as $groupId) { + \OC_Group::removeFromGroup($this->uid, $groupId); } // Delete the user's keys in preferences \OC::$server->getConfig()->deleteAllUserValues($this->uid); // Delete user files in /data/ - \OC_Helper::rmdirr(\OC_User::getHome($this->uid)); + \OC_Helper::rmdirr($this->getHome()); // Delete the users entry in the storage table - \OC\Files\Cache\Storage::remove('home::' . $this->uid); + Storage::remove('home::' . $this->uid); \OC::$server->getCommentsManager()->deleteReferencesOfActor('users', $this->uid); \OC::$server->getCommentsManager()->deleteReadMarksFromUser($this); @@ -231,7 +233,7 @@ class User implements IUser { if ($this->emitter) { $this->emitter->emit('\OC\User', 'preSetPassword', array($this, $password, $recoveryPassword)); } - if ($this->backend->implementsActions(\OC\User\Backend::SET_PASSWORD)) { + if ($this->backend->implementsActions(Backend::SET_PASSWORD)) { $result = $this->backend->setPassword($this->uid, $password); if ($this->emitter) { $this->emitter->emit('\OC\User', 'postSetPassword', array($this, $password, $recoveryPassword)); @@ -249,7 +251,7 @@ class User implements IUser { */ public function getHome() { if (!$this->home) { - if ($this->backend->implementsActions(\OC\User\Backend::GET_HOME) and $home = $this->backend->getHome($this->uid)) { + if ($this->backend->implementsActions(Backend::GET_HOME) and $home = $this->backend->getHome($this->uid)) { $this->home = $home; } elseif ($this->config) { $this->home = $this->config->getSystemValue('datadirectory') . '/' . $this->uid; @@ -266,7 +268,7 @@ class User implements IUser { * @return string */ public function getBackendClassName() { - if($this->backend instanceof \OCP\IUserBackend) { + if($this->backend instanceof IUserBackend) { return $this->backend->getBackendName(); } return get_class($this->backend); @@ -278,7 +280,7 @@ class User implements IUser { * @return bool */ public function canChangeAvatar() { - if ($this->backend->implementsActions(\OC\User\Backend::PROVIDE_AVATAR)) { + if ($this->backend->implementsActions(Backend::PROVIDE_AVATAR)) { return $this->backend->canChangeAvatar($this->uid); } return true; @@ -290,7 +292,7 @@ class User implements IUser { * @return bool */ public function canChangePassword() { - return $this->backend->implementsActions(\OC\User\Backend::SET_PASSWORD); + return $this->backend->implementsActions(Backend::SET_PASSWORD); } /** @@ -302,7 +304,7 @@ class User implements IUser { if ($this->config->getSystemValue('allow_user_to_change_display_name') === false) { return false; } - return $this->backend->implementsActions(\OC\User\Backend::SET_DISPLAYNAME); + return $this->backend->implementsActions(Backend::SET_DISPLAYNAME); } /** diff --git a/lib/private/legacy/api.php b/lib/private/legacy/api.php index 30083294861..17ee9c5d468 100644 --- a/lib/private/legacy/api.php +++ b/lib/private/legacy/api.php @@ -311,7 +311,7 @@ class OC_API { // reuse existing login $loggedIn = \OC::$server->getUserSession()->isLoggedIn(); if ($loggedIn === true) { - if (\OC::$server->getTwoFactorAuthManager()->needsSecondFactor()) { + if (\OC::$server->getTwoFactorAuthManager()->needsSecondFactor(\OC::$server->getUserSession()->getUser())) { // Do not allow access to OCS until the 2FA challenge was solved successfully return false; } diff --git a/lib/private/legacy/app.php b/lib/private/legacy/app.php index 2d5e5ba1932..0593f440eb0 100644 --- a/lib/private/legacy/app.php +++ b/lib/private/legacy/app.php @@ -51,6 +51,7 @@ use OC\App\Platform; use OC\Installer; use OC\OCSClient; use OC\Repair; +use OCP\App\ManagerEvent; /** * This class manages the apps. It allows them to register and integrate in the @@ -65,6 +66,7 @@ class OC_App { static private $appTypes = array(); static private $loadedApps = array(); static private $altLogin = array(); + static private $alreadyRegistered = []; const officialApp = 200; /** @@ -166,6 +168,11 @@ class OC_App { * @param string $path */ public static function registerAutoloading($app, $path) { + $key = $app . '-' . $path; + if(isset(self::$alreadyRegistered[$key])) { + return; + } + self::$alreadyRegistered[$key] = true; // Register on PSR-4 composer autoloader $appNamespace = \OC\AppFramework\App::buildAppNamespace($app); \OC::$composerAutoloader->addPsr4($appNamespace . '\\', $path . '/lib/', true); @@ -345,6 +352,13 @@ class OC_App { } else { $appManager->enableApp($app); } + + $info = self::getAppInfo($app); + if(isset($info['settings']) && is_array($info['settings'])) { + $appPath = self::getAppPath($app); + self::registerAutoloading($app, $appPath); + \OC::$server->getSettingsManager()->setupSettings($info['settings']); + } } /** @@ -429,7 +443,7 @@ class OC_App { $settings = array( array( "id" => "help", - "order" => 1000, + "order" => 4, "href" => $urlGenerator->linkToRoute('settings_help'), "name" => $l->t("Help"), "icon" => $urlGenerator->imagePath("settings", "help.svg") @@ -458,7 +472,7 @@ class OC_App { // admin users menu $settings[] = array( "id" => "core_users", - "order" => 2, + "order" => 3, "href" => $urlGenerator->linkToRoute('settings_users'), "name" => $l->t("Users"), "icon" => $urlGenerator->imagePath("settings", "users.svg") @@ -470,8 +484,8 @@ class OC_App { // admin settings $settings[] = array( "id" => "admin", - "order" => 1000, - "href" => $urlGenerator->linkToRoute('settings_admin'), + "order" => 2, + "href" => $urlGenerator->linkToRoute('settings.AdminSettings.index'), "name" => $l->t("Admin"), "icon" => $urlGenerator->imagePath("settings", "admin.svg") ); @@ -1162,6 +1176,13 @@ class OC_App { if (isset($appData['id'])) { $config->setAppValue($app, 'ocsid', $appData['id']); } + + if(isset($info['settings']) && is_array($info['settings'])) { + $appPath = self::getAppPath($app); + self::registerAutoloading($app, $appPath); + \OC::$server->getSettingsManager()->setupSettings($info['settings']); + } + \OC_Hook::emit('OC_App', 'post_enable', array('app' => $app)); } else { if(empty($appName) ) { @@ -1199,6 +1220,11 @@ class OC_App { include $appPath . '/appinfo/update.php'; } self::setupBackgroundJobs($appData['background-jobs']); + if(isset($appData['settings']) && is_array($appData['settings'])) { + $appPath = self::getAppPath($appId); + self::registerAutoloading($appId, $appPath); + \OC::$server->getSettingsManager()->setupSettings($appData['settings']); + } //set remote/public handlers if (array_key_exists('ocsid', $appData)) { @@ -1218,6 +1244,10 @@ class OC_App { $version = \OC_App::getAppVersion($appId); \OC::$server->getAppConfig()->setValue($appId, 'installed_version', $version); + \OC::$server->getEventDispatcher()->dispatch(ManagerEvent::EVENT_APP_UPDATE, new ManagerEvent( + ManagerEvent::EVENT_APP_UPDATE, $appId + )); + return true; } diff --git a/lib/private/legacy/helper.php b/lib/private/legacy/helper.php index da562034959..b19e58a9e6c 100644 --- a/lib/private/legacy/helper.php +++ b/lib/private/legacy/helper.php @@ -588,7 +588,19 @@ class OC_Helper { $sourceStorage = $storage->getSourceStorage(); } if ($includeExtStorage) { - $quota = OC_Util::getUserQuota(\OCP\User::getUser()); + if ($storage->instanceOfStorage('\OC\Files\Storage\Home') + || $storage->instanceOfStorage('\OC\Files\ObjectStore\HomeObjectStoreStorage') + ) { + /** @var \OC\Files\Storage\Home $storage */ + $user = $storage->getUser(); + } else { + $user = \OC::$server->getUserSession()->getUser()->getUID(); + } + if ($user) { + $quota = OC_Util::getUserQuota($user); + } else { + $quota = \OCP\Files\FileInfo::SPACE_UNLIMITED; + } if ($quota !== \OCP\Files\FileInfo::SPACE_UNLIMITED) { // always get free space / total space from root + mount points return self::getGlobalStorageInfo(); diff --git a/lib/private/legacy/json.php b/lib/private/legacy/json.php index 2882ac94ea9..f386d03ab1b 100644 --- a/lib/private/legacy/json.php +++ b/lib/private/legacy/json.php @@ -68,7 +68,7 @@ class OC_JSON{ public static function checkLoggedIn() { $twoFactorAuthManger = \OC::$server->getTwoFactorAuthManager(); if( !OC_User::isLoggedIn() - || $twoFactorAuthManger->needsSecondFactor()) { + || $twoFactorAuthManger->needsSecondFactor(\OC::$server->getUserSession()->getUser())) { $l = \OC::$server->getL10N('lib'); http_response_code(\OCP\AppFramework\Http::STATUS_UNAUTHORIZED); self::error(array( 'data' => array( 'message' => $l->t('Authentication error'), 'error' => 'authentication_error' ))); diff --git a/lib/private/legacy/ocs/config.php b/lib/private/legacy/ocs/config.php deleted file mode 100644 index dba9a061bb7..00000000000 --- a/lib/private/legacy/ocs/config.php +++ /dev/null @@ -1,28 +0,0 @@ -<?php -/** - * @copyright Copyright (c) 2016, ownCloud, Inc. - * - * @author Roeland Jago Douma <roeland@famdouma.nl> - * @author Thomas Müller <thomas.mueller@tmit.eu> - * - * @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/> - * - */ - -/** - * @deprecated Since 9.1.0 use \OC\OCS\Config - */ -class OC_OCS_Config extends \OC\OCS\Config { -} diff --git a/lib/private/legacy/util.php b/lib/private/legacy/util.php index 83274f82792..648be70cf0d 100644 --- a/lib/private/legacy/util.php +++ b/lib/private/legacy/util.php @@ -165,6 +165,7 @@ class OC_Util { // install storage availability wrapper, before most other wrappers \OC\Files\Filesystem::addStorageWrapper('oc_availability', function ($mountPoint, $storage) { + /** @var \OCP\Files\Storage $storage */ if (!$storage->instanceOfStorage('\OC\Files\Storage\Shared') && !$storage->isLocal()) { return new \OC\Files\Storage\Wrapper\Availability(['storage' => $storage]); } @@ -172,7 +173,7 @@ class OC_Util { }); \OC\Files\Filesystem::addStorageWrapper('oc_encoding', function ($mountPoint, \OCP\Files\Storage $storage, \OCP\Files\Mount\IMountPoint $mount) { - if ($mount->getOption('encoding_compatibility', true) && !$storage->instanceOfStorage('\OC\Files\Storage\Shared') && !$storage->isLocal()) { + if ($mount->getOption('encoding_compatibility', false) && !$storage->instanceOfStorage('\OC\Files\Storage\Shared') && !$storage->isLocal()) { return new \OC\Files\Storage\Wrapper\Encoding(['storage' => $storage]); } return $storage; @@ -290,16 +291,19 @@ class OC_Util { /** * Get the quota of a user * - * @param string $user + * @param string $userId * @return int Quota bytes */ - public static function getUserQuota($user) { - $userQuota = \OC::$server->getUserManager()->get($user)->getQuota(); + public static function getUserQuota($userId) { + $user = \OC::$server->getUserManager()->get($userId); + if (is_null($user)) { + return \OCP\Files\FileInfo::SPACE_UNLIMITED; + } + $userQuota = $user->getQuota(); if($userQuota === 'none') { return \OCP\Files\FileInfo::SPACE_UNLIMITED; - }else{ - return OC_Helper::computerFileSize($userQuota); } + return OC_Helper::computerFileSize($userQuota); } /** @@ -352,6 +356,7 @@ class OC_Util { */ public static function tearDownFS() { \OC\Files\Filesystem::tearDown(); + \OC::$server->getRootFolder()->clearCache(); self::$fsSetup = false; self::$rootMounted = false; } @@ -971,7 +976,7 @@ class OC_Util { exit(); } // Redirect to index page if 2FA challenge was not solved yet - if (\OC::$server->getTwoFactorAuthManager()->needsSecondFactor()) { + if (\OC::$server->getTwoFactorAuthManager()->needsSecondFactor(\OC::$server->getUserSession()->getUser())) { header('Location: ' . \OCP\Util::linkToAbsolute('', 'index.php')); exit(); } |