summaryrefslogtreecommitdiffstats
path: root/lib/private
diff options
context:
space:
mode:
Diffstat (limited to 'lib/private')
-rw-r--r--lib/private/App/InfoParser.php51
-rw-r--r--lib/private/AppFramework/App.php21
-rw-r--r--lib/private/AppFramework/DependencyInjection/DIContainer.php5
-rw-r--r--lib/private/Console/Application.php25
-rw-r--r--lib/private/Files/Config/CachedMountInfo.php18
-rw-r--r--lib/private/Files/Config/LazyStorageMountInfo.php9
-rw-r--r--lib/private/Files/Config/UserMountCache.php30
-rw-r--r--lib/private/Files/Node/Folder.php62
-rw-r--r--lib/private/Files/Node/Root.php14
-rw-r--r--lib/private/Installer.php2
-rw-r--r--lib/private/L10N/Factory.php30
-rw-r--r--lib/private/Log.php2
-rw-r--r--lib/private/Notification/Notification.php32
-rw-r--r--lib/private/Server.php4
-rw-r--r--lib/private/Share20/DefaultShareProvider.php79
-rw-r--r--lib/private/Share20/Manager.php3
-rw-r--r--lib/private/Share20/Share.php2
-rw-r--r--lib/private/User/Database.php9
-rw-r--r--lib/private/User/Session.php2
-rw-r--r--lib/private/legacy/app.php17
-rw-r--r--lib/private/legacy/helper.php26
21 files changed, 287 insertions, 156 deletions
diff --git a/lib/private/App/InfoParser.php b/lib/private/App/InfoParser.php
index e975ad6f096..44f495534c9 100644
--- a/lib/private/App/InfoParser.php
+++ b/lib/private/App/InfoParser.php
@@ -1,6 +1,7 @@
<?php
/**
* @copyright Copyright (c) 2016, ownCloud, Inc.
+ * @copyright Copyright (c) 2016, Lukas Reschke <lukas@statuscode.ch>
*
* @author Andreas Fischer <bantu@owncloud.com>
* @author Christoph Wurst <christoph@owncloud.com>
@@ -26,18 +27,17 @@
namespace OC\App;
-use OCP\IURLGenerator;
+use OCP\ICache;
class InfoParser {
-
- /** @var IURLGenerator */
- private $urlGenerator;
+ /** @var \OCP\ICache|null */
+ private $cache;
/**
- * @param IURLGenerator $urlGenerator
+ * @param ICache|null $cache
*/
- public function __construct(IURLGenerator $urlGenerator) {
- $this->urlGenerator = $urlGenerator;
+ public function __construct(ICache $cache = null) {
+ $this->cache = $cache;
}
/**
@@ -49,18 +49,28 @@ class InfoParser {
return null;
}
+ if(!is_null($this->cache)) {
+ $fileCacheKey = $file . filemtime($file);
+ if ($cachedValue = $this->cache->get($fileCacheKey)) {
+ return json_decode($cachedValue, true);
+ }
+ }
+
libxml_use_internal_errors(true);
$loadEntities = libxml_disable_entity_loader(false);
$xml = simplexml_load_file($file);
+
libxml_disable_entity_loader($loadEntities);
- if ($xml == false) {
+ if ($xml === false) {
libxml_clear_errors();
return null;
}
$array = $this->xmlToArray($xml);
+
if (is_null($array)) {
return null;
}
+
if (!array_key_exists('info', $array)) {
$array['info'] = [];
}
@@ -97,18 +107,10 @@ class InfoParser {
if (!array_key_exists('two-factor-providers', $array)) {
$array['two-factor-providers'] = [];
}
-
- if (array_key_exists('documentation', $array) && is_array($array['documentation'])) {
- foreach ($array['documentation'] as $key => $url) {
- // If it is not an absolute URL we assume it is a key
- // i.e. admin-ldap will get converted to go.php?to=admin-ldap
- if (!$this->isHTTPURL($url)) {
- $url = $this->urlGenerator->linkToDocs($url);
- }
-
- $array['documentation'][$key] = $url;
- }
+ if (!array_key_exists('commands', $array)) {
+ $array['commands'] = [];
}
+
if (array_key_exists('types', $array)) {
if (is_array($array['types'])) {
foreach ($array['types'] as $type => $v) {
@@ -139,6 +141,13 @@ class InfoParser {
if (isset($array['background-jobs']['job']) && is_array($array['background-jobs']['job'])) {
$array['background-jobs'] = $array['background-jobs']['job'];
}
+ if (isset($array['commands']['command']) && is_array($array['commands']['command'])) {
+ $array['commands'] = $array['commands']['command'];
+ }
+
+ if(!is_null($this->cache)) {
+ $this->cache->set($fileCacheKey, json_encode($array));
+ }
return $array;
}
@@ -193,8 +202,4 @@ class InfoParser {
return $array;
}
-
- private function isHTTPURL($url) {
- return stripos($url, 'https://') === 0 || stripos($url, 'http://') === 0;
- }
}
diff --git a/lib/private/AppFramework/App.php b/lib/private/AppFramework/App.php
index 427a850f396..e15e4a797ea 100644
--- a/lib/private/AppFramework/App.php
+++ b/lib/private/AppFramework/App.php
@@ -59,24 +59,11 @@ class App {
return $topNamespace . self::$nameSpaceCache[$appId];
}
- // first try to parse the app's appinfo/info.xml <namespace> tag
- $appPath = OC_App::getAppPath($appId);
- if ($appPath !== false) {
- $filePath = "$appPath/appinfo/info.xml";
- if (is_file($filePath)) {
- $loadEntities = libxml_disable_entity_loader(false);
- $xml = @simplexml_load_file($filePath);
- libxml_disable_entity_loader($loadEntities);
- if ($xml) {
- $result = $xml->xpath('/info/namespace');
- if ($result && count($result) > 0) {
- self::$nameSpaceCache[$appId] = trim((string) $result[0]);
- // take first namespace result
- return $topNamespace . self::$nameSpaceCache[$appId];
- }
- }
- }
+ $appInfo = \OC_App::getAppInfo($appId);
+ if (isset($appInfo['namespace'])) {
+ return $topNamespace . trim($appInfo['namespace']);
}
+
// if the tag is not found, fall back to uppercasing the first letter
self::$nameSpaceCache[$appId] = ucfirst($appId);
return $topNamespace . self::$nameSpaceCache[$appId];
diff --git a/lib/private/AppFramework/DependencyInjection/DIContainer.php b/lib/private/AppFramework/DependencyInjection/DIContainer.php
index 3f2212a7f24..21d5eaa9503 100644
--- a/lib/private/AppFramework/DependencyInjection/DIContainer.php
+++ b/lib/private/AppFramework/DependencyInjection/DIContainer.php
@@ -47,7 +47,7 @@ use OC\Core\Middleware\TwoFactorMiddleware;
use OCP\AppFramework\IApi;
use OCP\AppFramework\IAppContainer;
use OCP\Files\IAppData;
-
+use OCP\Files\Mount\IMountManager;
class DIContainer extends SimpleContainer implements IAppContainer {
@@ -313,6 +313,9 @@ class DIContainer extends SimpleContainer implements IAppContainer {
$this->registerService('OCP\\AppFramework\\IAppContainer', function ($c) {
return $c;
});
+ $this->registerService(IMountManager::class, function () {
+ return $this->getServer()->getMountManager();
+ });
// commonly used attributes
$this->registerService('UserId', function ($c) {
diff --git a/lib/private/Console/Application.php b/lib/private/Console/Application.php
index 3033d7beb86..299b23714b6 100644
--- a/lib/private/Console/Application.php
+++ b/lib/private/Console/Application.php
@@ -27,12 +27,11 @@
namespace OC\Console;
use OC_App;
+use OCP\AppFramework\QueryException;
use OCP\Console\ConsoleEvent;
-use OCP\Defaults;
use OCP\IConfig;
use OCP\IRequest;
use Symfony\Component\Console\Application as SymfonyApplication;
-use Symfony\Component\Console\Input\ArgvInput;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
@@ -103,6 +102,12 @@ class Application {
if($appPath === false) {
continue;
}
+ // load commands using info.xml
+ $info = \OC_App::getAppInfo($app);
+ if (isset($info['commands'])) {
+ $this->loadCommandsFromInfoXml($info['commands']);
+ }
+ // load from register_command.php
\OC_App::registerAutoloading($app, $appPath);
$file = $appPath . '/appinfo/register_command.php';
if (file_exists($file)) {
@@ -149,4 +154,20 @@ class Application {
));
return $this->application->run($input, $output);
}
+
+ private function loadCommandsFromInfoXml($commands) {
+ foreach ($commands as $command) {
+ try {
+ $c = \OC::$server->query($command);
+ } catch (QueryException $e) {
+ if (class_exists($command)) {
+ $c = new $command();
+ } else {
+ throw new \Exception("Console command '$command' is unknown and could not be loaded");
+ }
+ }
+
+ $this->application->add($c);
+ }
+ }
}
diff --git a/lib/private/Files/Config/CachedMountInfo.php b/lib/private/Files/Config/CachedMountInfo.php
index 74812b3ed8c..c4132a34431 100644
--- a/lib/private/Files/Config/CachedMountInfo.php
+++ b/lib/private/Files/Config/CachedMountInfo.php
@@ -54,6 +54,11 @@ class CachedMountInfo implements ICachedMountInfo {
protected $mountId;
/**
+ * @var string
+ */
+ protected $rootInternalPath;
+
+ /**
* CachedMountInfo constructor.
*
* @param IUser $user
@@ -61,13 +66,15 @@ class CachedMountInfo implements ICachedMountInfo {
* @param int $rootId
* @param string $mountPoint
* @param int|null $mountId
+ * @param string $rootInternalPath
*/
- public function __construct(IUser $user, $storageId, $rootId, $mountPoint, $mountId = null) {
+ public function __construct(IUser $user, $storageId, $rootId, $mountPoint, $mountId = null, $rootInternalPath = '') {
$this->user = $user;
$this->storageId = $storageId;
$this->rootId = $rootId;
$this->mountPoint = $mountPoint;
$this->mountId = $mountId;
+ $this->rootInternalPath = $rootInternalPath;
}
/**
@@ -122,4 +129,13 @@ class CachedMountInfo implements ICachedMountInfo {
public function getMountId() {
return $this->mountId;
}
+
+ /**
+ * Get the internal path (within the storage) of the root of the mount
+ *
+ * @return string
+ */
+ public function getRootInternalPath() {
+ return $this->rootInternalPath;
+ }
}
diff --git a/lib/private/Files/Config/LazyStorageMountInfo.php b/lib/private/Files/Config/LazyStorageMountInfo.php
index 4df813d57d0..40d463c5103 100644
--- a/lib/private/Files/Config/LazyStorageMountInfo.php
+++ b/lib/private/Files/Config/LazyStorageMountInfo.php
@@ -76,4 +76,13 @@ class LazyStorageMountInfo extends CachedMountInfo {
public function getMountId() {
return $this->mount->getMountId();
}
+
+ /**
+ * Get the internal path (within the storage) of the root of the mount
+ *
+ * @return string
+ */
+ public function getRootInternalPath() {
+ return $this->mount->getInternalPath($this->mount->getMountPoint());
+ }
}
diff --git a/lib/private/Files/Config/UserMountCache.php b/lib/private/Files/Config/UserMountCache.php
index bd8343fa440..e9e142d0d4b 100644
--- a/lib/private/Files/Config/UserMountCache.php
+++ b/lib/private/Files/Config/UserMountCache.php
@@ -31,6 +31,7 @@ use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\Files\Config\ICachedMountInfo;
use OCP\Files\Config\IUserMountCache;
use OCP\Files\Mount\IMountPoint;
+use OCP\Files\Node;
use OCP\Files\NotFoundException;
use OCP\ICache;
use OCP\IDBConnection;
@@ -187,7 +188,7 @@ class UserMountCache implements IUserMountCache {
private function dbRowToMountInfo(array $row) {
$user = $this->userManager->get($row['user_id']);
- return new CachedMountInfo($user, (int)$row['storage_id'], (int)$row['root_id'], $row['mount_point'], $row['mount_id']);
+ return new CachedMountInfo($user, (int)$row['storage_id'], (int)$row['root_id'], $row['mount_point'], $row['mount_id'], isset($row['path'])? $row['path']:'');
}
/**
@@ -197,8 +198,9 @@ class UserMountCache implements IUserMountCache {
public function getMountsForUser(IUser $user) {
if (!isset($this->mountsForUsers[$user->getUID()])) {
$builder = $this->connection->getQueryBuilder();
- $query = $builder->select('storage_id', 'root_id', 'user_id', 'mount_point', 'mount_id')
- ->from('mounts')
+ $query = $builder->select('storage_id', 'root_id', 'user_id', 'mount_point', 'mount_id', 'f.path')
+ ->from('mounts', 'm')
+ ->innerJoin('m', 'filecache', 'f', $builder->expr()->eq('m.root_id', 'f.fileid'))
->where($builder->expr()->eq('user_id', $builder->createPositionalParameter($user->getUID())));
$rows = $query->execute()->fetchAll();
@@ -214,8 +216,9 @@ class UserMountCache implements IUserMountCache {
*/
public function getMountsForStorageId($numericStorageId) {
$builder = $this->connection->getQueryBuilder();
- $query = $builder->select('storage_id', 'root_id', 'user_id', 'mount_point', 'mount_id')
- ->from('mounts')
+ $query = $builder->select('storage_id', 'root_id', 'user_id', 'mount_point', 'mount_id', 'f.path')
+ ->from('mounts', 'm')
+ ->innerJoin('m', 'filecache', 'f' , $builder->expr()->eq('m.root_id', 'f.fileid'))
->where($builder->expr()->eq('storage_id', $builder->createPositionalParameter($numericStorageId, IQueryBuilder::PARAM_INT)));
$rows = $query->execute()->fetchAll();
@@ -229,8 +232,9 @@ class UserMountCache implements IUserMountCache {
*/
public function getMountsForRootId($rootFileId) {
$builder = $this->connection->getQueryBuilder();
- $query = $builder->select('storage_id', 'root_id', 'user_id', 'mount_point', 'mount_id')
- ->from('mounts')
+ $query = $builder->select('storage_id', 'root_id', 'user_id', 'mount_point', 'mount_id', 'f.path')
+ ->from('mounts', 'm')
+ ->innerJoin('m', 'filecache', 'f', $builder->expr()->eq('m.root_id', 'f.fileid'))
->where($builder->expr()->eq('root_id', $builder->createPositionalParameter($rootFileId, IQueryBuilder::PARAM_INT)));
$rows = $query->execute()->fetchAll();
@@ -246,7 +250,7 @@ class UserMountCache implements IUserMountCache {
private function getCacheInfoFromFileId($fileId) {
if (!isset($this->cacheInfoCache[$fileId])) {
$builder = $this->connection->getQueryBuilder();
- $query = $builder->select('storage', 'path')
+ $query = $builder->select('storage', 'path', 'mimetype')
->from('filecache')
->where($builder->expr()->eq('fileid', $builder->createNamedParameter($fileId, IQueryBuilder::PARAM_INT)));
@@ -254,7 +258,8 @@ class UserMountCache implements IUserMountCache {
if (is_array($row)) {
$this->cacheInfoCache[$fileId] = [
(int)$row['storage'],
- $row['path']
+ $row['path'],
+ (int)$row['mimetype']
];
} else {
throw new NotFoundException('File with id "' . $fileId . '" not found');
@@ -281,15 +286,10 @@ class UserMountCache implements IUserMountCache {
if ($fileId === $mount->getRootId()) {
return true;
}
- try {
- list(, $internalMountPath) = $this->getCacheInfoFromFileId($mount->getRootId());
- } catch (NotFoundException $e) {
- return false;
- }
+ $internalMountPath = $mount->getRootInternalPath();
return $internalMountPath === '' || substr($internalPath, 0, strlen($internalMountPath) + 1) === $internalMountPath . '/';
});
-
}
/**
diff --git a/lib/private/Files/Node/Folder.php b/lib/private/Files/Node/Folder.php
index e67e4817e2a..353b89068cb 100644
--- a/lib/private/Files/Node/Folder.php
+++ b/lib/private/Files/Node/Folder.php
@@ -28,6 +28,7 @@ namespace OC\Files\Node;
use OC\DB\QueryBuilder\Literal;
use OCP\DB\QueryBuilder\IQueryBuilder;
+use OCP\Files\Config\ICachedMountInfo;
use OCP\Files\FileInfo;
use OCP\Files\Mount\IMountPoint;
use OCP\Files\NotFoundException;
@@ -83,7 +84,7 @@ class Folder extends Node implements \OCP\Files\Folder {
public function getDirectoryListing() {
$folderContent = $this->view->getDirectoryContent($this->path);
- return array_map(function(FileInfo $info) {
+ return array_map(function (FileInfo $info) {
if ($info->getMimetype() === 'httpd/unix-directory') {
return new Folder($this->root, $this->view, $info->getPath(), $info);
} else {
@@ -253,7 +254,7 @@ class Folder extends Node implements \OCP\Files\Folder {
}
}
- return array_map(function(FileInfo $file) {
+ return array_map(function (FileInfo $file) {
return $this->createNode($file->getPath(), $file);
}, $files);
}
@@ -263,29 +264,48 @@ class Folder extends Node implements \OCP\Files\Folder {
* @return \OC\Files\Node\Node[]
*/
public function getById($id) {
+ $mountCache = $this->root->getUserMountCache();
+ $mountsContainingFile = $mountCache->getMountsForFileId((int)$id);
$mounts = $this->root->getMountsIn($this->path);
$mounts[] = $this->root->getMount($this->path);
- // reverse the array so we start with the storage this view is in
- // which is the most likely to contain the file we're looking for
- $mounts = array_reverse($mounts);
+ /** @var IMountPoint[] $folderMounts */
+ $folderMounts = array_combine(array_map(function (IMountPoint $mountPoint) {
+ return $mountPoint->getMountPoint();
+ }, $mounts), $mounts);
+
+ /** @var ICachedMountInfo[] $mountsContainingFile */
+ $mountsContainingFile = array_values(array_filter($mountsContainingFile, function (ICachedMountInfo $cachedMountInfo) use ($folderMounts) {
+ return isset($folderMounts[$cachedMountInfo->getMountPoint()]);
+ }));
- $nodes = array();
- foreach ($mounts as $mount) {
- /**
- * @var \OC\Files\Mount\MountPoint $mount
- */
- if ($mount->getStorage()) {
- $cache = $mount->getStorage()->getCache();
- $internalPath = $cache->getPathById($id);
- if (is_string($internalPath)) {
- $fullPath = $mount->getMountPoint() . $internalPath;
- if (!is_null($path = $this->getRelativePath($fullPath))) {
- $nodes[] = $this->get($path);
- }
- }
- }
+ if (count($mountsContainingFile) === 0) {
+ return [];
}
- return $nodes;
+
+ // we only need to get the cache info once, since all mounts we found point to the same storage
+
+ $mount = $folderMounts[$mountsContainingFile[0]->getMountPoint()];
+ $cacheEntry = $mount->getStorage()->getCache()->get((int)$id);
+ if (!$cacheEntry) {
+ return [];
+ }
+ // cache jails will hide the "true" internal path
+ $internalPath = ltrim($mountsContainingFile[0]->getRootInternalPath() . '/' . $cacheEntry->getPath(), '/');
+
+ $nodes = array_map(function (ICachedMountInfo $cachedMountInfo) use ($cacheEntry, $folderMounts, $internalPath) {
+ $mount = $folderMounts[$cachedMountInfo->getMountPoint()];
+ $pathRelativeToMount = substr($internalPath, strlen($cachedMountInfo->getRootInternalPath()));
+ $pathRelativeToMount = ltrim($pathRelativeToMount, '/');
+ $absolutePath = $cachedMountInfo->getMountPoint() . $pathRelativeToMount;
+ return $this->root->createNode($absolutePath, new \OC\Files\FileInfo(
+ $absolutePath, $mount->getStorage(), $cacheEntry->getPath(), $cacheEntry, $mount,
+ \OC::$server->getUserManager()->get($mount->getStorage()->getOwner($pathRelativeToMount))
+ ));
+ }, $mountsContainingFile);
+
+ return array_filter($nodes, function (Node $node) {
+ return $this->getRelativePath($node->getPath());
+ });
}
public function getFreeSpace() {
diff --git a/lib/private/Files/Node/Root.php b/lib/private/Files/Node/Root.php
index 007847fb513..0cda2c8b822 100644
--- a/lib/private/Files/Node/Root.php
+++ b/lib/private/Files/Node/Root.php
@@ -31,6 +31,7 @@ namespace OC\Files\Node;
use OC\Cache\CappedMemoryCache;
use OC\Files\Mount\Manager;
use OC\Files\Mount\MountPoint;
+use OCP\Files\Config\IUserMountCache;
use OCP\Files\NotFoundException;
use OCP\Files\NotPermittedException;
use OC\Hooks\PublicEmitter;
@@ -75,16 +76,23 @@ class Root extends Folder implements IRootFolder {
private $userFolderCache;
/**
+ * @var IUserMountCache
+ */
+ private $userMountCache;
+
+ /**
* @param \OC\Files\Mount\Manager $manager
* @param \OC\Files\View $view
* @param \OC\User\User|null $user
+ * @param IUserMountCache $userMountCache
*/
- public function __construct($manager, $view, $user) {
+ public function __construct($manager, $view, $user, IUserMountCache $userMountCache) {
parent::__construct($this, $view, '');
$this->mountManager = $manager;
$this->user = $user;
$this->emitter = new PublicEmitter();
$this->userFolderCache = new CappedMemoryCache();
+ $this->userMountCache = $userMountCache;
}
/**
@@ -361,4 +369,8 @@ class Root extends Folder implements IRootFolder {
public function clearCache() {
$this->userFolderCache = new CappedMemoryCache();
}
+
+ public function getUserMountCache() {
+ return $this->userMountCache;
+ }
}
diff --git a/lib/private/Installer.php b/lib/private/Installer.php
index 3d8a923417a..009df790585 100644
--- a/lib/private/Installer.php
+++ b/lib/private/Installer.php
@@ -614,7 +614,7 @@ class Installer {
}
$codeChecker = new CodeChecker(new PrivateCheck(new EmptyCheck()));
- $errors = $codeChecker->analyseFolder($folder);
+ $errors = $codeChecker->analyseFolder(basename($folder), $folder);
return empty($errors);
}
diff --git a/lib/private/L10N/Factory.php b/lib/private/L10N/Factory.php
index 91233a0c4a7..8aad395065c 100644
--- a/lib/private/L10N/Factory.php
+++ b/lib/private/L10N/Factory.php
@@ -2,6 +2,7 @@
/**
* @copyright Copyright (c) 2016, ownCloud, Inc.
* @copyright 2016 Roeland Jago Douma <roeland@famdouma.nl>
+ * @copyright 2016 Lukas Reschke <lukas@statuscode.ch>
*
* @author Bart Visscher <bartv@thisnet.nl>
* @author Joas Schilling <coding@schilljs.com>
@@ -288,6 +289,27 @@ class Factory implements IFactory {
}
/**
+ * Checks if $sub is a subdirectory of $parent
+ *
+ * @param string $sub
+ * @param string $parent
+ * @return bool
+ */
+ private function isSubDirectory($sub, $parent) {
+ // Check whether $sub contains no ".."
+ if(strpos($sub, '..') !== false) {
+ return false;
+ }
+
+ // Check whether $sub is a subdirectory of $parent
+ if (strpos($sub, $parent) === 0) {
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
* Get a list of language files that should be loaded
*
* @param string $app
@@ -302,10 +324,10 @@ class Factory implements IFactory {
$i18nDir = $this->findL10nDir($app);
$transFile = strip_tags($i18nDir) . strip_tags($lang) . '.json';
- if ((\OC_Helper::isSubDirectory($transFile, $this->serverRoot . '/core/l10n/')
- || \OC_Helper::isSubDirectory($transFile, $this->serverRoot . '/lib/l10n/')
- || \OC_Helper::isSubDirectory($transFile, $this->serverRoot . '/settings/l10n/')
- || \OC_Helper::isSubDirectory($transFile, \OC_App::getAppPath($app) . '/l10n/')
+ if (($this->isSubDirectory($transFile, $this->serverRoot . '/core/l10n/')
+ || $this->isSubDirectory($transFile, $this->serverRoot . '/lib/l10n/')
+ || $this->isSubDirectory($transFile, $this->serverRoot . '/settings/l10n/')
+ || $this->isSubDirectory($transFile, \OC_App::getAppPath($app) . '/l10n/')
)
&& file_exists($transFile)) {
// load the translations file
diff --git a/lib/private/Log.php b/lib/private/Log.php
index b76cb4f8c28..ef1b70d3cb9 100644
--- a/lib/private/Log.php
+++ b/lib/private/Log.php
@@ -277,7 +277,7 @@ class Log implements ILogger {
$request = \OC::$server->getRequest();
// if token is found in the request change set the log condition to satisfied
- if($request && hash_equals($logCondition['shared_secret'], $request->getParam('log_secret'))) {
+ if($request && hash_equals($logCondition['shared_secret'], $request->getParam('log_secret', ''))) {
$this->logConditionSatisfied = true;
}
}
diff --git a/lib/private/Notification/Notification.php b/lib/private/Notification/Notification.php
index 9b5877a3058..7bf4b9a74cf 100644
--- a/lib/private/Notification/Notification.php
+++ b/lib/private/Notification/Notification.php
@@ -242,7 +242,7 @@ class Notification implements INotification {
/**
* @param string $subject
* @return $this
- * @throws \InvalidArgumentException if the subject are invalid
+ * @throws \InvalidArgumentException if the subject is invalid
* @since 8.2.0
*/
public function setParsedSubject($subject) {
@@ -300,7 +300,7 @@ class Notification implements INotification {
/**
* @param string $message
* @return $this
- * @throws \InvalidArgumentException if the message are invalid
+ * @throws \InvalidArgumentException if the message is invalid
* @since 8.2.0
*/
public function setParsedMessage($message) {
@@ -322,7 +322,7 @@ class Notification implements INotification {
/**
* @param string $link
* @return $this
- * @throws \InvalidArgumentException if the link are invalid
+ * @throws \InvalidArgumentException if the link is invalid
* @since 8.2.0
*/
public function setLink($link) {
@@ -342,6 +342,28 @@ class Notification implements INotification {
}
/**
+ * @param string $icon
+ * @return $this
+ * @throws \InvalidArgumentException if the icon is invalid
+ * @since 9.2.0
+ */
+ public function setIcon($icon) {
+ if (!is_string($icon) || $icon === '' || isset($icon[4000])) {
+ throw new \InvalidArgumentException('The given icon is invalid');
+ }
+ $this->icon = $icon;
+ return $this;
+ }
+
+ /**
+ * @return string
+ * @since 9.2.0
+ */
+ public function getIcon() {
+ return $this->icon;
+ }
+
+ /**
* @return IAction
* @since 8.2.0
*/
@@ -352,7 +374,7 @@ class Notification implements INotification {
/**
* @param IAction $action
* @return $this
- * @throws \InvalidArgumentException if the action are invalid
+ * @throws \InvalidArgumentException if the action is invalid
* @since 8.2.0
*/
public function addAction(IAction $action) {
@@ -383,7 +405,7 @@ class Notification implements INotification {
/**
* @param IAction $action
* @return $this
- * @throws \InvalidArgumentException if the action are invalid
+ * @throws \InvalidArgumentException if the action is invalid
* @since 8.2.0
*/
public function addParsedAction(IAction $action) {
diff --git a/lib/private/Server.php b/lib/private/Server.php
index b49e94b554e..291714b23d1 100644
--- a/lib/private/Server.php
+++ b/lib/private/Server.php
@@ -175,10 +175,10 @@ class Server extends ServerContainer implements IServerContainer {
$this->registerService('SystemTagObjectMapper', function (Server $c) {
return $c->query('SystemTagManagerFactory')->getObjectMapper();
});
- $this->registerService('RootFolder', function () {
+ $this->registerService('RootFolder', function (Server $c) {
$manager = \OC\Files\Filesystem::getMountManager(null);
$view = new View();
- $root = new Root($manager, $view, null);
+ $root = new Root($manager, $view, null, $c->getUserMountCache());
$connector = new HookConnector($root, $view);
$connector->viewToNode();
return $root;
diff --git a/lib/private/Share20/DefaultShareProvider.php b/lib/private/Share20/DefaultShareProvider.php
index d6afcf99912..56b9d5b1ee8 100644
--- a/lib/private/Share20/DefaultShareProvider.php
+++ b/lib/private/Share20/DefaultShareProvider.php
@@ -543,7 +543,7 @@ class DefaultShareProvider implements IShareProvider {
// If the recipient is set for a group share resolve to that user
if ($recipientId !== null && $share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
- $share = $this->resolveGroupShare($share, $recipientId);
+ $share = $this->resolveGroupShares([$share], $recipientId)[0];
}
return $share;
@@ -709,11 +709,8 @@ class DefaultShareProvider implements IShareProvider {
/*
* Resolve all group shares to user specific shares
- * TODO: Optmize this!
*/
- foreach($shares2 as $share) {
- $shares[] = $this->resolveGroupShare($share, $userId);
- }
+ $shares = $this->resolveGroupShares($shares2, $userId);
} else {
throw new BackendError('Invalid backend');
}
@@ -802,37 +799,59 @@ class DefaultShareProvider implements IShareProvider {
}
/**
- * Resolve a group share to a user specific share
- * Thus if the user moved their group share make sure this is properly reflected here.
- *
- * @param \OCP\Share\IShare $share
- * @param string $userId
- * @return Share Returns the updated share if one was found else return the original share.
+ * @param Share[] $shares
+ * @param $userId
+ * @return Share[] The updates shares if no update is found for a share return the original
*/
- private function resolveGroupShare(\OCP\Share\IShare $share, $userId) {
- $qb = $this->dbConn->getQueryBuilder();
+ private function resolveGroupShares($shares, $userId) {
+ $result = [];
- $stmt = $qb->select('*')
- ->from('share')
- ->where($qb->expr()->eq('parent', $qb->createNamedParameter($share->getId())))
- ->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_USERGROUP)))
- ->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($userId)))
- ->andWhere($qb->expr()->orX(
- $qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
- $qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
- ))
- ->setMaxResults(1)
- ->execute();
+ $start = 0;
+ while(true) {
+ /** @var Share[] $shareSlice */
+ $shareSlice = array_slice($shares, $start, 100);
+ $start += 100;
+
+ if ($shareSlice === []) {
+ break;
+ }
+
+ /** @var int[] $ids */
+ $ids = [];
+ /** @var Share[] $shareMap */
+ $shareMap = [];
+
+ foreach ($shareSlice as $share) {
+ $ids[] = (int)$share->getId();
+ $shareMap[$share->getId()] = $share;
+ }
- $data = $stmt->fetch();
- $stmt->closeCursor();
+ $qb = $this->dbConn->getQueryBuilder();
+
+ $query = $qb->select('*')
+ ->from('share')
+ ->where($qb->expr()->in('parent', $qb->createNamedParameter($ids, IQueryBuilder::PARAM_INT_ARRAY)))
+ ->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($userId)))
+ ->andWhere($qb->expr()->orX(
+ $qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
+ $qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
+ ));
- if ($data !== false) {
- $share->setPermissions((int)$data['permissions']);
- $share->setTarget($data['file_target']);
+ $stmt = $query->execute();
+
+ while($data = $stmt->fetch()) {
+ $shareMap[$data['parent']]->setPermissions((int)$data['permissions']);
+ $shareMap[$data['parent']]->setTarget($data['file_target']);
+ }
+
+ $stmt->closeCursor();
+
+ foreach ($shareMap as $share) {
+ $result[] = $share;
+ }
}
- return $share;
+ return $result;
}
/**
diff --git a/lib/private/Share20/Manager.php b/lib/private/Share20/Manager.php
index b4fe69a83e2..22cf5a3f65a 100644
--- a/lib/private/Share20/Manager.php
+++ b/lib/private/Share20/Manager.php
@@ -614,8 +614,11 @@ class Manager implements IManager {
throw new \Exception($error);
}
+ $oldShare = $share;
$provider = $this->factory->getProviderForType($share->getShareType());
$share = $provider->create($share);
+ //reuse the node we already have
+ $share->setNode($oldShare->getNode());
// Post share hook
$postHookData = [
diff --git a/lib/private/Share20/Share.php b/lib/private/Share20/Share.php
index c565809c078..e3e8482f4e1 100644
--- a/lib/private/Share20/Share.php
+++ b/lib/private/Share20/Share.php
@@ -160,7 +160,7 @@ class Share implements \OCP\Share\IShare {
$nodes = $userFolder->getById($this->fileId);
if (empty($nodes)) {
- throw new NotFoundException();
+ throw new NotFoundException('Node for share not found, fileid: ' . $this->fileId);
}
$this->node = $nodes[0];
diff --git a/lib/private/User/Database.php b/lib/private/User/Database.php
index eba7beffeae..28cb3302858 100644
--- a/lib/private/User/Database.php
+++ b/lib/private/User/Database.php
@@ -94,6 +94,9 @@ class Database extends Backend implements IUserBackend {
$query = \OC_DB::prepare('INSERT INTO `*PREFIX*users` ( `uid`, `password` ) VALUES( ?, ? )');
$result = $query->execute(array($uid, \OC::$server->getHasher()->hash($password)));
+ // Clear cache
+ unset($this->cache[$uid]);
+
return $result ? true : false;
}
@@ -234,7 +237,7 @@ class Database extends Backend implements IUserBackend {
* @return boolean
*/
private function loadUser($uid) {
- if (empty($this->cache[$uid])) {
+ if (!isset($this->cache[$uid])) {
$query = \OC_DB::prepare('SELECT `uid`, `displayname` FROM `*PREFIX*users` WHERE LOWER(`uid`) = LOWER(?)');
$result = $query->execute(array($uid));
@@ -243,6 +246,8 @@ class Database extends Backend implements IUserBackend {
return false;
}
+ $this->cache[$uid] = false;
+
while ($row = $result->fetchRow()) {
$this->cache[$uid]['uid'] = $row['uid'];
$this->cache[$uid]['displayname'] = $row['displayname'];
@@ -284,7 +289,7 @@ class Database extends Backend implements IUserBackend {
*/
public function userExists($uid) {
$this->loadUser($uid);
- return !empty($this->cache[$uid]);
+ return $this->cache[$uid] !== false;
}
/**
diff --git a/lib/private/User/Session.php b/lib/private/User/Session.php
index dec959820f8..4b56609ccfc 100644
--- a/lib/private/User/Session.php
+++ b/lib/private/User/Session.php
@@ -597,7 +597,6 @@ class Session implements IUserSession, Emitter {
}
$dbToken->setLastCheck($now);
- $this->tokenProvider->updateToken($dbToken);
return true;
}
@@ -608,7 +607,6 @@ class Session implements IUserSession, Emitter {
return false;
}
$dbToken->setLastCheck($now);
- $this->tokenProvider->updateToken($dbToken);
return true;
}
diff --git a/lib/private/legacy/app.php b/lib/private/legacy/app.php
index c3d2d1d6ad4..5e05884f5c0 100644
--- a/lib/private/legacy/app.php
+++ b/lib/private/legacy/app.php
@@ -47,6 +47,7 @@
*
*/
use OC\App\DependencyAnalyzer;
+use OC\App\InfoParser;
use OC\App\Platform;
use OC\Installer;
use OC\OCSClient;
@@ -681,7 +682,7 @@ class OC_App {
$file = $appPath . '/appinfo/info.xml';
}
- $parser = new \OC\App\InfoParser(\OC::$server->getURLGenerator());
+ $parser = new InfoParser(\OC::$server->getMemCacheFactory()->create('core.appinfo'));
$data = $parser->parse($file);
if (is_array($data)) {
@@ -847,6 +848,7 @@ class OC_App {
$blacklist = \OC::$server->getAppManager()->getAlwaysEnabledApps();
$appList = array();
$langCode = \OC::$server->getL10N('core')->getLanguageCode();
+ $urlGenerator = \OC::$server->getURLGenerator();
foreach ($installedApps as $app) {
if (array_search($app, $blacklist) === false) {
@@ -900,6 +902,19 @@ class OC_App {
}
}
}
+ // fix documentation
+ if (isset($info['documentation']) && is_array($info['documentation'])) {
+ foreach ($info['documentation'] as $key => $url) {
+ // If it is not an absolute URL we assume it is a key
+ // i.e. admin-ldap will get converted to go.php?to=admin-ldap
+ if (stripos($url, 'https://') !== 0 && stripos($url, 'http://') !== 0) {
+ $url = $urlGenerator->linkToDocs($url);
+ }
+
+ $info['documentation'][$key] = $url;
+ }
+ }
+
$info['version'] = OC_App::getAppVersion($app);
$appList[] = $info;
}
diff --git a/lib/private/legacy/helper.php b/lib/private/legacy/helper.php
index b19e58a9e6c..0b9477dacd4 100644
--- a/lib/private/legacy/helper.php
+++ b/lib/private/legacy/helper.php
@@ -378,32 +378,6 @@ class OC_Helper {
}
/**
- * Checks if $sub is a subdirectory of $parent
- *
- * @param string $sub
- * @param string $parent
- * @return bool
- */
- public static function isSubDirectory($sub, $parent) {
- $realpathSub = realpath($sub);
- $realpathParent = realpath($parent);
-
- // realpath() may return false in case the directory does not exist
- // since we can not be sure how different PHP versions may behave here
- // we do an additional check whether realpath returned false
- if($realpathSub === false || $realpathParent === false) {
- return false;
- }
-
- // Check whether $sub is a subdirectory of $parent
- if (strpos($realpathSub, $realpathParent) === 0) {
- return true;
- }
-
- return false;
- }
-
- /**
* Returns an array with all keys from input lowercased or uppercased. Numbered indices are left as is.
*
* @param array $input The array to work on