summaryrefslogtreecommitdiffstats
path: root/lib/private
diff options
context:
space:
mode:
Diffstat (limited to 'lib/private')
-rw-r--r--lib/private/Activity/Manager.php (renamed from lib/private/ActivityManager.php)5
-rw-r--r--lib/private/App/InfoParser.php23
-rw-r--r--lib/private/AppFramework/Db/Db.php17
-rw-r--r--lib/private/AppFramework/DependencyInjection/DIContainer.php4
-rw-r--r--lib/private/Archive/Archive.php (renamed from lib/private/archive.php)12
-rw-r--r--lib/private/Archive/TAR.php (renamed from lib/private/archive/tar.php)24
-rw-r--r--lib/private/Archive/ZIP.php (renamed from lib/private/archive/zip.php)14
-rw-r--r--lib/private/Authentication/Exceptions/InvalidTokenException.php29
-rw-r--r--lib/private/Authentication/Token/DefaultToken.php90
-rw-r--r--lib/private/Authentication/Token/DefaultTokenCleanupJob.php36
-rw-r--r--lib/private/Authentication/Token/DefaultTokenMapper.php114
-rw-r--r--lib/private/Authentication/Token/DefaultTokenProvider.php219
-rw-r--r--lib/private/Authentication/Token/IProvider.php91
-rw-r--r--lib/private/Authentication/Token/IToken.php50
-rw-r--r--lib/private/BackgroundJob/JobList.php86
-rw-r--r--lib/private/Cache/File.php4
-rw-r--r--lib/private/Console/Application.php2
-rw-r--r--lib/private/DB/Adapter.php20
-rw-r--r--lib/private/DB/AdapterMySQL.php12
-rw-r--r--lib/private/DB/AdapterSqlite.php12
-rw-r--r--lib/private/DB/Connection.php38
-rw-r--r--lib/private/DateTimeFormatter.php (renamed from lib/private/datetimeformatter.php)0
-rw-r--r--lib/private/DateTimeZone.php (renamed from lib/private/datetimezone.php)0
-rw-r--r--lib/private/Files/Cache/Wrapper/CacheJail.php2
-rw-r--r--lib/private/Files/Config/MountProviderCollection.php36
-rw-r--r--lib/private/Files/Filesystem.php106
-rw-r--r--lib/private/Files/Mount/CacheMountProvider.php69
-rw-r--r--lib/private/Files/Mount/LocalHomeMountProvider.php46
-rw-r--r--lib/private/Files/Mount/ObjectHomeMountProvider.php73
-rw-r--r--lib/private/Files/Storage/Wrapper/Availability.php4
-rw-r--r--lib/private/ForbiddenException.php (renamed from lib/private/forbiddenexception.php)0
-rw-r--r--lib/private/Group/Backend.php (renamed from lib/private/group/backend.php)28
-rw-r--r--lib/private/Group/Database.php (renamed from lib/private/group/database.php)12
-rw-r--r--lib/private/Group/Group.php (renamed from lib/private/group/group.php)12
-rw-r--r--lib/private/Group/Manager.php (renamed from lib/private/group/manager.php)2
-rw-r--r--lib/private/Group/MetaData.php (renamed from lib/private/group/metadata.php)0
-rw-r--r--lib/private/HTTPHelper.php (renamed from lib/private/httphelper.php)0
-rw-r--r--lib/private/HintException.php (renamed from lib/private/hintexception.php)0
-rw-r--r--lib/private/Http/Client/Client.php29
-rw-r--r--lib/private/Installer.php (renamed from lib/private/installer.php)91
-rw-r--r--lib/private/L10N/Factory.php2
-rw-r--r--lib/private/LargeFileHelper.php (renamed from lib/private/largefilehelper.php)0
-rw-r--r--lib/private/Lock/AbstractLockingProvider.php7
-rw-r--r--lib/private/Lock/MemcacheLockingProvider.php9
-rw-r--r--lib/private/Log.php (renamed from lib/private/log.php)4
-rw-r--r--lib/private/Log/ErrorHandler.php (renamed from lib/private/log/errorhandler.php)0
-rw-r--r--lib/private/Log/Errorlog.php (renamed from lib/private/log/errorlog.php)4
-rw-r--r--lib/private/Log/Owncloud.php (renamed from lib/private/log/owncloud.php)16
-rw-r--r--lib/private/Log/Rotate.php (renamed from lib/private/log/rotate.php)0
-rw-r--r--lib/private/Log/Syslog.php (renamed from lib/private/log/syslog.php)4
-rw-r--r--lib/private/Memcache/Memcached.php30
-rw-r--r--lib/private/Memcache/Redis.php31
-rw-r--r--lib/private/NaturalSort.php (renamed from lib/private/naturalsort.php)0
-rw-r--r--lib/private/NaturalSort_DefaultCollator.php (renamed from lib/private/naturalsort_defaultcollator.php)0
-rw-r--r--lib/private/NavigationManager.php (renamed from lib/private/navigationmanager.php)0
-rw-r--r--lib/private/NeedsUpdateException.php (renamed from lib/private/needsupdateexception.php)0
-rw-r--r--lib/private/NotSquareException.php (renamed from lib/private/notsquareexception.php)0
-rw-r--r--lib/private/OCS/Cloud.php (renamed from lib/private/ocs/cloud.php)14
-rw-r--r--lib/private/OCS/Config.php (renamed from lib/private/ocs/config.php)8
-rw-r--r--lib/private/OCS/CoreCapabilities.php (renamed from lib/private/ocs/corecapabilities.php)0
-rw-r--r--lib/private/OCS/Exception.php (renamed from lib/private/ocs/exception.php)2
-rw-r--r--lib/private/OCS/Person.php (renamed from lib/private/ocs/person.php)12
-rw-r--r--lib/private/OCS/PrivateData.php (renamed from lib/private/ocs/privatedata.php)17
-rw-r--r--lib/private/OCS/Provider.php96
-rw-r--r--lib/private/OCS/Result.php (renamed from lib/private/ocs/result.php)4
-rw-r--r--lib/private/OCSClient.php (renamed from lib/private/ocsclient.php)8
-rw-r--r--lib/private/Preview.php (renamed from lib/private/preview.php)0
-rw-r--r--lib/private/PreviewManager.php (renamed from lib/private/previewmanager.php)0
-rw-r--r--lib/private/RedisFactory.php85
-rw-r--r--lib/private/Repair.php (renamed from lib/private/repair.php)50
-rw-r--r--lib/private/Repair/DropOldTables.php5
-rw-r--r--lib/private/RepairException.php (renamed from lib/private/repairexception.php)0
-rw-r--r--lib/private/Route/CachingRouter.php5
-rw-r--r--lib/private/Search.php (renamed from lib/private/search.php)0
-rw-r--r--lib/private/Server.php71
-rw-r--r--lib/private/ServerContainer.php (renamed from lib/private/servercontainer.php)0
-rw-r--r--lib/private/ServerNotAvailableException.php (renamed from lib/private/servernotavailableexception.php)0
-rw-r--r--lib/private/ServiceUnavailableException.php (renamed from lib/private/serviceunavailableexception.php)0
-rw-r--r--lib/private/Session/CryptoSessionData.php12
-rw-r--r--lib/private/Session/Internal.php17
-rw-r--r--lib/private/Session/Memory.php18
-rw-r--r--lib/private/Setup.php (renamed from lib/private/setup.php)67
-rw-r--r--lib/private/Share/Constants.php (renamed from lib/private/share/constants.php)0
-rw-r--r--lib/private/Share/Helper.php (renamed from lib/private/share/helper.php)0
-rw-r--r--lib/private/Share/MailNotifications.php (renamed from lib/private/share/mailnotifications.php)22
-rw-r--r--lib/private/Share/SearchResultSorter.php (renamed from lib/private/share/searchresultsorter.php)0
-rw-r--r--lib/private/Share/Share.php (renamed from lib/private/share/share.php)0
-rw-r--r--lib/private/Streamer.php (renamed from lib/private/streamer.php)0
-rw-r--r--lib/private/SubAdmin.php (renamed from lib/private/subadmin.php)0
-rw-r--r--lib/private/SystemConfig.php (renamed from lib/private/systemconfig.php)0
-rw-r--r--lib/private/SystemTag/ManagerFactory.php1
-rw-r--r--lib/private/SystemTag/SystemTagManager.php113
-rw-r--r--lib/private/TagManager.php (renamed from lib/private/tagmanager.php)0
-rw-r--r--lib/private/Tags.php (renamed from lib/private/tags.php)0
-rw-r--r--lib/private/TempManager.php (renamed from lib/private/tempmanager.php)0
-rw-r--r--lib/private/Template/Base.php (renamed from lib/private/template/base.php)0
-rw-r--r--lib/private/Template/CSSResourceLocator.php (renamed from lib/private/template/cssresourcelocator.php)0
-rw-r--r--lib/private/Template/JSResourceLocator.php (renamed from lib/private/template/jsresourcelocator.php)0
-rw-r--r--lib/private/Template/ResourceLocator.php (renamed from lib/private/template/resourcelocator.php)0
-rw-r--r--lib/private/Template/ResourceNotFoundException.php (renamed from lib/private/template/resourcenotfoundexception.php)0
-rw-r--r--lib/private/Template/TemplateFileLocator.php (renamed from lib/private/template/templatefilelocator.php)0
-rw-r--r--lib/private/TemplateLayout.php (renamed from lib/private/templatelayout.php)0
-rw-r--r--lib/private/URLGenerator.php (renamed from lib/private/urlgenerator.php)0
-rw-r--r--lib/private/Updater.php (renamed from lib/private/updater.php)38
-rw-r--r--lib/private/Updater/VersionCheck.php8
-rw-r--r--lib/private/User/Backend.php (renamed from lib/private/user/backend.php)28
-rw-r--r--lib/private/User/Database.php (renamed from lib/private/user/database.php)44
-rw-r--r--lib/private/User/LoginException.php (renamed from lib/private/user/loginexception.php)0
-rw-r--r--lib/private/User/Manager.php (renamed from lib/private/user/manager.php)37
-rw-r--r--lib/private/User/NoUserException.php (renamed from lib/private/user/nouserexception.php)0
-rw-r--r--lib/private/User/Session.php545
-rw-r--r--lib/private/User/User.php (renamed from lib/private/user/user.php)15
-rw-r--r--lib/private/legacy/api.php (renamed from lib/private/api.php)42
-rw-r--r--lib/private/legacy/app.php (renamed from lib/private/app.php)59
-rw-r--r--lib/private/legacy/db.php (renamed from lib/private/db.php)0
-rw-r--r--lib/private/legacy/defaults.php (renamed from lib/private/defaults.php)0
-rw-r--r--lib/private/legacy/eventsource.php (renamed from lib/private/eventsource.php)0
-rw-r--r--lib/private/legacy/filechunking.php (renamed from lib/private/filechunking.php)0
-rw-r--r--lib/private/legacy/files.php (renamed from lib/private/files.php)0
-rw-r--r--lib/private/legacy/group.php (renamed from lib/private/group.php)2
-rw-r--r--lib/private/legacy/group/backend.php59
-rw-r--r--lib/private/legacy/group/database.php30
-rw-r--r--lib/private/legacy/group/example.php (renamed from lib/private/group/example.php)0
-rw-r--r--lib/private/legacy/group/interface.php (renamed from lib/private/group/interface.php)0
-rw-r--r--lib/private/legacy/helper.php (renamed from lib/private/helper.php)31
-rw-r--r--lib/private/legacy/hook.php (renamed from lib/private/hook.php)0
-rw-r--r--lib/private/legacy/image.php (renamed from lib/private/image.php)0
-rw-r--r--lib/private/legacy/json.php (renamed from lib/private/json.php)0
-rw-r--r--lib/private/legacy/ocs.php (renamed from lib/private/ocs.php)0
-rw-r--r--lib/private/legacy/ocs/cloud.php27
-rw-r--r--lib/private/legacy/ocs/config.php27
-rw-r--r--lib/private/legacy/ocs/person.php27
-rw-r--r--lib/private/legacy/ocs/privatedata.php27
-rw-r--r--lib/private/legacy/ocs/result.php27
-rw-r--r--lib/private/legacy/response.php (renamed from lib/private/response.php)0
-rw-r--r--lib/private/legacy/template.php (renamed from lib/private/template.php)0
-rw-r--r--lib/private/legacy/template/functions.php (renamed from lib/private/template/functions.php)6
-rw-r--r--lib/private/legacy/user.php (renamed from lib/private/user.php)70
-rw-r--r--lib/private/legacy/user/backend.php67
-rw-r--r--lib/private/legacy/user/interface.php (renamed from lib/private/user/interface.php)0
-rw-r--r--lib/private/legacy/util.php (renamed from lib/private/util.php)5
-rw-r--r--lib/private/user/session.php318
142 files changed, 2758 insertions, 927 deletions
diff --git a/lib/private/ActivityManager.php b/lib/private/Activity/Manager.php
index e522dca9e3b..e68802b2abb 100644
--- a/lib/private/ActivityManager.php
+++ b/lib/private/Activity/Manager.php
@@ -20,10 +20,9 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
-namespace OC;
+namespace OC\Activity;
-use OC\Activity\Event;
use OCP\Activity\IConsumer;
use OCP\Activity\IEvent;
use OCP\Activity\IExtension;
@@ -33,7 +32,7 @@ use OCP\IRequest;
use OCP\IUser;
use OCP\IUserSession;
-class ActivityManager implements IManager {
+class Manager implements IManager {
/** @var IRequest */
protected $request;
diff --git a/lib/private/App/InfoParser.php b/lib/private/App/InfoParser.php
index b7540c04248..e9456550206 100644
--- a/lib/private/App/InfoParser.php
+++ b/lib/private/App/InfoParser.php
@@ -74,6 +74,9 @@ class InfoParser {
if (!array_key_exists('repair-steps', $array)) {
$array['repair-steps'] = [];
}
+ if (!array_key_exists('install', $array['repair-steps'])) {
+ $array['repair-steps']['install'] = [];
+ }
if (!array_key_exists('pre-migration', $array['repair-steps'])) {
$array['repair-steps']['pre-migration'] = [];
}
@@ -83,6 +86,12 @@ class InfoParser {
if (!array_key_exists('live-migration', $array['repair-steps'])) {
$array['repair-steps']['live-migration'] = [];
}
+ if (!array_key_exists('uninstall', $array['repair-steps'])) {
+ $array['repair-steps']['uninstall'] = [];
+ }
+ if (!array_key_exists('background-jobs', $array)) {
+ $array['background-jobs'] = [];
+ }
if (array_key_exists('documentation', $array) && is_array($array['documentation'])) {
foreach ($array['documentation'] as $key => $url) {
@@ -107,6 +116,9 @@ class InfoParser {
$array['types'] = [];
}
}
+ if (isset($array['repair-steps']['install']['step']) && is_array($array['repair-steps']['install']['step'])) {
+ $array['repair-steps']['install'] = $array['repair-steps']['install']['step'];
+ }
if (isset($array['repair-steps']['pre-migration']['step']) && is_array($array['repair-steps']['pre-migration']['step'])) {
$array['repair-steps']['pre-migration'] = $array['repair-steps']['pre-migration']['step'];
}
@@ -116,6 +128,12 @@ class InfoParser {
if (isset($array['repair-steps']['live-migration']['step']) && is_array($array['repair-steps']['live-migration']['step'])) {
$array['repair-steps']['live-migration'] = $array['repair-steps']['live-migration']['step'];
}
+ if (isset($array['repair-steps']['uninstall']['step']) && is_array($array['repair-steps']['uninstall']['step'])) {
+ $array['repair-steps']['uninstall'] = $array['repair-steps']['uninstall']['step'];
+ }
+ if (isset($array['background-jobs']['job']) && is_array($array['background-jobs']['job'])) {
+ $array['background-jobs'] = $array['background-jobs']['job'];
+ }
return $array;
}
@@ -135,10 +153,7 @@ class InfoParser {
if (!isset($array[$element])) {
$array[$element] = "";
}
- /**
- * @var \SimpleXMLElement $node
- */
-
+ /** @var \SimpleXMLElement $node */
// Has attributes
if ($attributes = $node->attributes()) {
$data = [
diff --git a/lib/private/AppFramework/Db/Db.php b/lib/private/AppFramework/Db/Db.php
index 0d17d7bc225..ab06d56cfd1 100644
--- a/lib/private/AppFramework/Db/Db.php
+++ b/lib/private/AppFramework/Db/Db.php
@@ -29,6 +29,7 @@ namespace OC\AppFramework\Db;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\IDb;
use OCP\IDBConnection;
+use OCP\PreConditionNotMetException;
/**
* @deprecated use IDBConnection directly, will be removed in ownCloud 10
@@ -157,13 +158,27 @@ class Db implements IDb {
* @param array $updatePreconditionValues ensure values match preconditions (column name => value)
* @return int number of new rows
* @throws \Doctrine\DBAL\DBALException
- * @throws PreconditionNotMetException
+ * @throws PreConditionNotMetException
*/
public function setValues($table, array $keys, array $values, array $updatePreconditionValues = []) {
return $this->connection->setValues($table, $keys, $values, $updatePreconditionValues);
}
/**
+ * @inheritdoc
+ */
+ public function lockTable($tableName) {
+ $this->connection->lockTable($tableName);
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function unlockTable() {
+ $this->connection->unlockTable();
+ }
+
+ /**
* Start a transaction
*/
public function beginTransaction() {
diff --git a/lib/private/AppFramework/DependencyInjection/DIContainer.php b/lib/private/AppFramework/DependencyInjection/DIContainer.php
index 2951ee536d2..439b631b50f 100644
--- a/lib/private/AppFramework/DependencyInjection/DIContainer.php
+++ b/lib/private/AppFramework/DependencyInjection/DIContainer.php
@@ -148,6 +148,10 @@ class DIContainer extends SimpleContainer implements IAppContainer {
return $this->getServer()->getRootFolder();
});
+ $this->registerService('OCP\\Http\\Client\\IClientService', function($c) {
+ return $this->getServer()->getHTTPClientService();
+ });
+
$this->registerService('OCP\\IGroupManager', function($c) {
return $this->getServer()->getGroupManager();
});
diff --git a/lib/private/archive.php b/lib/private/Archive/Archive.php
index 62512d1448a..b5286968a2f 100644
--- a/lib/private/archive.php
+++ b/lib/private/Archive/Archive.php
@@ -28,23 +28,25 @@
*
*/
-abstract class OC_Archive{
+namespace OC\Archive;
+
+abstract class Archive{
/**
* Open any of the supported archive types
*
* @param string $path
- * @return OC_Archive|void
+ * @return Archive|void
*/
public static function open($path) {
$mime = \OC::$server->getMimeTypeDetector()->detect($path);
switch($mime) {
case 'application/zip':
- return new OC_Archive_ZIP($path);
+ return new ZIP($path);
case 'application/x-gzip':
- return new OC_Archive_TAR($path);
+ return new TAR($path);
case 'application/x-bzip2':
- return new OC_Archive_TAR($path);
+ return new TAR($path);
}
}
diff --git a/lib/private/archive/tar.php b/lib/private/Archive/TAR.php
index 20e2e05f238..d783e53d40c 100644
--- a/lib/private/archive/tar.php
+++ b/lib/private/Archive/TAR.php
@@ -30,7 +30,9 @@
*
*/
-class OC_Archive_TAR extends OC_Archive {
+namespace OC\Archive;
+
+class TAR extends Archive {
const PLAIN = 0;
const GZIP = 1;
const BZIP = 2;
@@ -39,7 +41,7 @@ class OC_Archive_TAR extends OC_Archive {
private $cachedHeaders;
/**
- * @var Archive_Tar tar
+ * @var \Archive_Tar tar
*/
private $tar = null;
private $path;
@@ -50,7 +52,7 @@ class OC_Archive_TAR extends OC_Archive {
function __construct($source) {
$types = array(null, 'gz', 'bz2');
$this->path = $source;
- $this->tar = new Archive_Tar($source, $types[self::getTarType($source)]);
+ $this->tar = new \Archive_Tar($source, $types[self::getTarType($source)]);
}
/**
@@ -137,13 +139,13 @@ class OC_Archive_TAR extends OC_Archive {
*/
function rename($source, $dest) {
//no proper way to delete, rename entire archive, rename file and remake archive
- $tmp = OCP\Files::tmpFolder();
+ $tmp = \OCP\Files::tmpFolder();
$this->tar->extract($tmp);
rename($tmp . $source, $tmp . $dest);
$this->tar = null;
unlink($this->path);
$types = array(null, 'gz', 'bz');
- $this->tar = new Archive_Tar($this->path, $types[self::getTarType($this->path)]);
+ $this->tar = new \Archive_Tar($this->path, $types[self::getTarType($this->path)]);
$this->tar->createModify(array($tmp), '', $tmp . '/');
$this->fileList = false;
$this->cachedHeaders = false;
@@ -256,7 +258,7 @@ class OC_Archive_TAR extends OC_Archive {
* @return bool
*/
function extractFile($path, $dest) {
- $tmp = OCP\Files::tmpFolder();
+ $tmp = \OCP\Files::tmpFolder();
if (!$this->fileExists($path)) {
return false;
}
@@ -268,7 +270,7 @@ class OC_Archive_TAR extends OC_Archive {
if ($success) {
rename($tmp . $path, $dest);
}
- OCP\Files::rmdirr($tmp);
+ \OCP\Files::rmdirr($tmp);
return $success;
}
@@ -324,9 +326,9 @@ class OC_Archive_TAR extends OC_Archive {
$this->fileList = false;
$this->cachedHeaders = false;
//no proper way to delete, extract entire archive, delete file and remake archive
- $tmp = OCP\Files::tmpFolder();
+ $tmp = \OCP\Files::tmpFolder();
$this->tar->extract($tmp);
- OCP\Files::rmdirr($tmp . $path);
+ \OCP\Files::rmdirr($tmp . $path);
$this->tar = null;
unlink($this->path);
$this->reopen();
@@ -347,7 +349,7 @@ class OC_Archive_TAR extends OC_Archive {
} else {
$ext = '';
}
- $tmpFile = OCP\Files::tmpFile($ext);
+ $tmpFile = \OCP\Files::tmpFile($ext);
if ($this->fileExists($path)) {
$this->extractFile($path, $tmpFile);
} elseif ($mode == 'r' or $mode == 'rb') {
@@ -383,6 +385,6 @@ class OC_Archive_TAR extends OC_Archive {
$this->tar = null;
}
$types = array(null, 'gz', 'bz');
- $this->tar = new Archive_Tar($this->path, $types[self::getTarType($this->path)]);
+ $this->tar = new \Archive_Tar($this->path, $types[self::getTarType($this->path)]);
}
}
diff --git a/lib/private/archive/zip.php b/lib/private/Archive/ZIP.php
index 0d8d3b7ce76..2bc17507d32 100644
--- a/lib/private/archive/zip.php
+++ b/lib/private/Archive/ZIP.php
@@ -27,9 +27,11 @@
*
*/
-class OC_Archive_ZIP extends OC_Archive{
+namespace OC\Archive;
+
+class ZIP extends Archive{
/**
- * @var ZipArchive zip
+ * @var \ZipArchive zip
*/
private $zip=null;
private $path;
@@ -39,10 +41,10 @@ class OC_Archive_ZIP extends OC_Archive{
*/
function __construct($source) {
$this->path=$source;
- $this->zip=new ZipArchive();
- if($this->zip->open($source, ZipArchive::CREATE)) {
+ $this->zip=new \ZipArchive();
+ if($this->zip->open($source, \ZipArchive::CREATE)) {
}else{
- OCP\Util::writeLog('files_archive', 'Error while opening archive '.$source, OCP\Util::WARN);
+ \OCP\Util::writeLog('files_archive', 'Error while opening archive '.$source, \OCP\Util::WARN);
}
}
/**
@@ -193,7 +195,7 @@ class OC_Archive_ZIP extends OC_Archive{
}else{
$ext='';
}
- $tmpFile=OCP\Files::tmpFile($ext);
+ $tmpFile=\OCP\Files::tmpFile($ext);
\OC\Files\Stream\Close::registerCallback($tmpFile, array($this, 'writeBack'));
if($this->fileExists($path)) {
$this->extractFile($path, $tmpFile);
diff --git a/lib/private/Authentication/Exceptions/InvalidTokenException.php b/lib/private/Authentication/Exceptions/InvalidTokenException.php
new file mode 100644
index 00000000000..3e52d3b78f0
--- /dev/null
+++ b/lib/private/Authentication/Exceptions/InvalidTokenException.php
@@ -0,0 +1,29 @@
+<?php
+
+/**
+ * @author Christoph Wurst <christoph@owncloud.com>
+ *
+ * @copyright Copyright (c) 2016, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OC\Authentication\Exceptions;
+
+use Exception;
+
+class InvalidTokenException extends Exception {
+
+}
diff --git a/lib/private/Authentication/Token/DefaultToken.php b/lib/private/Authentication/Token/DefaultToken.php
new file mode 100644
index 00000000000..08451a46151
--- /dev/null
+++ b/lib/private/Authentication/Token/DefaultToken.php
@@ -0,0 +1,90 @@
+<?php
+
+/**
+ * @author Christoph Wurst <christoph@owncloud.com>
+ *
+ * @copyright Copyright (c) 2016, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OC\Authentication\Token;
+
+use OCP\AppFramework\Db\Entity;
+
+/**
+ * @method void setId(int $id)
+ * @method void setUid(string $uid);
+ * @method void setPassword(string $password)
+ * @method string getPassword()
+ * @method void setName(string $name)
+ * @method string getName()
+ * @method void setToken(string $token)
+ * @method string getToken()
+ * @method void setType(string $type)
+ * @method int getType()
+ * @method void setLastActivity(int $lastActivity)
+ * @method int getLastActivity()
+ */
+class DefaultToken extends Entity implements IToken {
+
+ /**
+ * @var string user UID
+ */
+ protected $uid;
+
+ /**
+ * @var string encrypted user password
+ */
+ protected $password;
+
+ /**
+ * @var string token name (e.g. browser/OS)
+ */
+ protected $name;
+
+ /**
+ * @var string
+ */
+ protected $token;
+
+ /**
+ * @var int
+ */
+ protected $type;
+
+ /**
+ * @var int
+ */
+ protected $lastActivity;
+
+ public function getId() {
+ return $this->id;
+ }
+
+ public function getUID() {
+ return $this->uid;
+ }
+
+ /**
+ * Get the (encrypted) login password
+ *
+ * @return string
+ */
+ public function getPassword() {
+ return parent::getPassword();
+ }
+
+}
diff --git a/lib/private/Authentication/Token/DefaultTokenCleanupJob.php b/lib/private/Authentication/Token/DefaultTokenCleanupJob.php
new file mode 100644
index 00000000000..4d1290eb623
--- /dev/null
+++ b/lib/private/Authentication/Token/DefaultTokenCleanupJob.php
@@ -0,0 +1,36 @@
+<?php
+
+/**
+ * @author Christoph Wurst <christoph@owncloud.com>
+ *
+ * @copyright Copyright (c) 2016, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OC\Authentication\Token;
+
+use OC;
+use OC\BackgroundJob\Job;
+
+class DefaultTokenCleanupJob extends Job {
+
+ protected function run($argument) {
+ /* @var $provider DefaultTokenProvider */
+ $provider = OC::$server->query('OC\Authentication\Token\DefaultTokenProvider');
+ $provider->invalidateOldTokens();
+ }
+
+}
diff --git a/lib/private/Authentication/Token/DefaultTokenMapper.php b/lib/private/Authentication/Token/DefaultTokenMapper.php
new file mode 100644
index 00000000000..9f173571270
--- /dev/null
+++ b/lib/private/Authentication/Token/DefaultTokenMapper.php
@@ -0,0 +1,114 @@
+<?php
+
+/**
+ * @author Christoph Wurst <christoph@owncloud.com>
+ *
+ * @copyright Copyright (c) 2016, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OC\Authentication\Token;
+
+use OCP\AppFramework\Db\DoesNotExistException;
+use OCP\AppFramework\Db\Mapper;
+use OCP\DB\QueryBuilder\IQueryBuilder;
+use OCP\IDBConnection;
+use OCP\IUser;
+
+class DefaultTokenMapper extends Mapper {
+
+ public function __construct(IDBConnection $db) {
+ parent::__construct($db, 'authtoken');
+ }
+
+ /**
+ * Invalidate (delete) a given token
+ *
+ * @param string $token
+ */
+ public function invalidate($token) {
+ $qb = $this->db->getQueryBuilder();
+ $qb->delete('authtoken')
+ ->andWhere($qb->expr()->eq('token', $qb->createParameter('token')))
+ ->setParameter('token', $token)
+ ->execute();
+ }
+
+ /**
+ * @param int $olderThan
+ */
+ public function invalidateOld($olderThan) {
+ /* @var $qb IQueryBuilder */
+ $qb = $this->db->getQueryBuilder();
+ $qb->delete('authtoken')
+ ->where($qb->expr()->lt('last_activity', $qb->createParameter('last_activity')))
+ ->andWhere($qb->expr()->eq('type', $qb->createParameter('type')))
+ ->setParameter('last_activity', $olderThan, IQueryBuilder::PARAM_INT)
+ ->setParameter('type', IToken::TEMPORARY_TOKEN, IQueryBuilder::PARAM_INT)
+ ->execute();
+ }
+
+ /**
+ * Get the user UID for the given token
+ *
+ * @param string $token
+ * @throws DoesNotExistException
+ * @return DefaultToken
+ */
+ public function getToken($token) {
+ /* @var $qb IQueryBuilder */
+ $qb = $this->db->getQueryBuilder();
+ $result = $qb->select('id', 'uid', 'password', 'name', 'type', 'token', 'last_activity')
+ ->from('authtoken')
+ ->where($qb->expr()->eq('token', $qb->createParameter('token')))
+ ->setParameter('token', $token)
+ ->execute();
+
+ $data = $result->fetch();
+ if ($data === false) {
+ throw new DoesNotExistException('token does not exist');
+ }
+ return DefaultToken::fromRow($data);
+ }
+
+ /**
+ * Get all token of a user
+ *
+ * The provider may limit the number of result rows in case of an abuse
+ * where a high number of (session) tokens is generated
+ *
+ * @param IUser $user
+ * @return DefaultToken[]
+ */
+ public function getTokenByUser(IUser $user) {
+ /* @var $qb IQueryBuilder */
+ $qb = $this->db->getQueryBuilder();
+ $qb->select('id', 'uid', 'password', 'name', 'type', 'token', 'last_activity')
+ ->from('authtoken')
+ ->where($qb->expr()->eq('uid', $qb->createNamedParameter($user->getUID())))
+ ->setMaxResults(1000);
+ $result = $qb->execute();
+ $data = $result->fetchAll();
+ $result->closeCursor();
+
+ $entities = array_map(function ($row) {
+ return DefaultToken::fromRow($row);
+ }, $data);
+
+ return $entities;
+ }
+
+}
diff --git a/lib/private/Authentication/Token/DefaultTokenProvider.php b/lib/private/Authentication/Token/DefaultTokenProvider.php
new file mode 100644
index 00000000000..6c69d852d7b
--- /dev/null
+++ b/lib/private/Authentication/Token/DefaultTokenProvider.php
@@ -0,0 +1,219 @@
+<?php
+
+/**
+ * @author Christoph Wurst <christoph@owncloud.com>
+ *
+ * @copyright Copyright (c) 2016, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OC\Authentication\Token;
+
+use Exception;
+use OC\Authentication\Exceptions\InvalidTokenException;
+use OCP\AppFramework\Db\DoesNotExistException;
+use OCP\AppFramework\Utility\ITimeFactory;
+use OCP\IConfig;
+use OCP\ILogger;
+use OCP\IUser;
+use OCP\Security\ICrypto;
+
+class DefaultTokenProvider implements IProvider {
+
+ /** @var DefaultTokenMapper */
+ private $mapper;
+
+ /** @var ICrypto */
+ private $crypto;
+
+ /** @var IConfig */
+ private $config;
+
+ /** @var ILogger $logger */
+ private $logger;
+
+ /** @var ITimeFactory $time */
+ private $time;
+
+ /**
+ * @param DefaultTokenMapper $mapper
+ * @param ICrypto $crypto
+ * @param IConfig $config
+ * @param ILogger $logger
+ * @param ITimeFactory $time
+ */
+ public function __construct(DefaultTokenMapper $mapper, ICrypto $crypto, IConfig $config, ILogger $logger, ITimeFactory $time) {
+ $this->mapper = $mapper;
+ $this->crypto = $crypto;
+ $this->config = $config;
+ $this->logger = $logger;
+ $this->time = $time;
+ }
+
+ /**
+ * Create and persist a new token
+ *
+ * @param string $token
+ * @param string $uid
+ * @param string $password
+ * @param string $name
+ * @param int $type token type
+ * @return DefaultToken
+ */
+ public function generateToken($token, $uid, $password, $name, $type = IToken::TEMPORARY_TOKEN) {
+ $dbToken = new DefaultToken();
+ $dbToken->setUid($uid);
+ $dbToken->setPassword($this->encryptPassword($password, $token));
+ $dbToken->setName($name);
+ $dbToken->setToken($this->hashToken($token));
+ $dbToken->setType($type);
+ $dbToken->setLastActivity($this->time->getTime());
+
+ $this->mapper->insert($dbToken);
+
+ return $dbToken;
+ }
+
+ /**
+ * Update token activity timestamp
+ *
+ * @throws InvalidTokenException
+ * @param IToken $token
+ */
+ public function updateToken(IToken $token) {
+ if (!($token instanceof DefaultToken)) {
+ throw new InvalidTokenException();
+ }
+ /** @var DefaultToken $token */
+ $token->setLastActivity($this->time->getTime());
+
+ $this->mapper->update($token);
+ }
+
+ /**
+ * Get all token of a user
+ *
+ * The provider may limit the number of result rows in case of an abuse
+ * where a high number of (session) tokens is generated
+ *
+ * @param IUser $user
+ * @return IToken[]
+ */
+ public function getTokenByUser(IUser $user) {
+ return $this->mapper->getTokenByUser($user);
+ }
+
+ /**
+ * Get a token by token id
+ *
+ * @param string $tokenId
+ * @throws InvalidTokenException
+ * @return DefaultToken
+ */
+ public function getToken($tokenId) {
+ try {
+ return $this->mapper->getToken($this->hashToken($tokenId));
+ } catch (DoesNotExistException $ex) {
+ throw new InvalidTokenException();
+ }
+ }
+
+ /**
+ * @param IToken $savedToken
+ * @param string $tokenId session token
+ * @return string
+ */
+ public function getPassword(IToken $savedToken, $tokenId) {
+ return $this->decryptPassword($savedToken->getPassword(), $tokenId);
+ }
+
+ /**
+ * Invalidate (delete) the given session token
+ *
+ * @param string $token
+ */
+ public function invalidateToken($token) {
+ $this->mapper->invalidate($this->hashToken($token));
+ }
+
+ /**
+ * Invalidate (delete) old session tokens
+ */
+ public function invalidateOldTokens() {
+ $olderThan = $this->time->getTime() - (int) $this->config->getSystemValue('session_lifetime', 60 * 60 * 24);
+ $this->logger->info('Invalidating tokens older than ' . date('c', $olderThan));
+ $this->mapper->invalidateOld($olderThan);
+ }
+
+ /**
+ * @param string $token
+ * @throws InvalidTokenException
+ * @return DefaultToken user UID
+ */
+ public function validateToken($token) {
+ try {
+ $dbToken = $this->mapper->getToken($this->hashToken($token));
+ $this->logger->debug('valid default token for ' . $dbToken->getUID());
+ return $dbToken;
+ } catch (DoesNotExistException $ex) {
+ throw new InvalidTokenException();
+ }
+ }
+
+ /**
+ * @param string $token
+ * @return string
+ */
+ private function hashToken($token) {
+ $secret = $this->config->getSystemValue('secret');
+ return hash('sha512', $token . $secret);
+ }
+
+ /**
+ * Encrypt the given password
+ *
+ * The token is used as key
+ *
+ * @param string $password
+ * @param string $token
+ * @return string encrypted password
+ */
+ private function encryptPassword($password, $token) {
+ $secret = $this->config->getSystemValue('secret');
+ return $this->crypto->encrypt($password, $token . $secret);
+ }
+
+ /**
+ * Decrypt the given password
+ *
+ * The token is used as key
+ *
+ * @param string $password
+ * @param string $token
+ * @return string the decrypted key
+ */
+ private function decryptPassword($password, $token) {
+ $secret = $this->config->getSystemValue('secret');
+ try {
+ return $this->crypto->decrypt($password, $token . $secret);
+ } catch (Exception $ex) {
+ // Delete the invalid token
+ $this->invalidateToken($token);
+ throw new InvalidTokenException();
+ }
+ }
+
+}
diff --git a/lib/private/Authentication/Token/IProvider.php b/lib/private/Authentication/Token/IProvider.php
new file mode 100644
index 00000000000..a5c5faa5639
--- /dev/null
+++ b/lib/private/Authentication/Token/IProvider.php
@@ -0,0 +1,91 @@
+<?php
+
+/**
+ * @author Christoph Wurst <christoph@owncloud.com>
+ *
+ * @copyright Copyright (c) 2016, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OC\Authentication\Token;
+
+use OC\Authentication\Exceptions\InvalidTokenException;
+use OCP\IUser;
+
+interface IProvider {
+
+ /**
+ * Create and persist a new token
+ *
+ * @param string $token
+ * @param string $uid
+ * @param string $password
+ * @param string $name
+ * @param int $type token type
+ * @return DefaultToken
+ */
+ public function generateToken($token, $uid, $password, $name, $type = IToken::TEMPORARY_TOKEN);
+
+ /**
+ * Get a token by token id
+ *
+ * @param string $tokenId
+ * @throws InvalidTokenException
+ * @return IToken
+ */
+ public function getToken($tokenId) ;
+
+ /**
+ * @param string $token
+ * @throws InvalidTokenException
+ * @return IToken
+ */
+ public function validateToken($token);
+
+ /**
+ * Invalidate (delete) the given session token
+ *
+ * @param string $token
+ */
+ public function invalidateToken($token);
+
+ /**
+ * Update token activity timestamp
+ *
+ * @param IToken $token
+ */
+ public function updateToken(IToken $token);
+
+ /**
+ * Get all token of a user
+ *
+ * The provider may limit the number of result rows in case of an abuse
+ * where a high number of (session) tokens is generated
+ *
+ * @param IUser $user
+ * @return IToken[]
+ */
+ public function getTokenByUser(IUser $user);
+
+ /**
+ * Get the (unencrypted) password of the given token
+ *
+ * @param IToken $token
+ * @param string $tokenId
+ * @return string
+ */
+ public function getPassword(IToken $token, $tokenId);
+}
diff --git a/lib/private/Authentication/Token/IToken.php b/lib/private/Authentication/Token/IToken.php
new file mode 100644
index 00000000000..2a01ea75ea9
--- /dev/null
+++ b/lib/private/Authentication/Token/IToken.php
@@ -0,0 +1,50 @@
+<?php
+
+/**
+ * @author Christoph Wurst <christoph@owncloud.com>
+ *
+ * @copyright Copyright (c) 2016, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OC\Authentication\Token;
+
+interface IToken {
+
+ const TEMPORARY_TOKEN = 0;
+ const PERMANENT_TOKEN = 1;
+
+ /**
+ * Get the token ID
+ *
+ * @return string
+ */
+ public function getId();
+
+ /**
+ * Get the user UID
+ *
+ * @return string
+ */
+ public function getUID();
+
+ /**
+ * Get the (encrypted) login password
+ *
+ * @return string
+ */
+ public function getPassword();
+}
diff --git a/lib/private/BackgroundJob/JobList.php b/lib/private/BackgroundJob/JobList.php
index 2429b830446..c84969776c2 100644
--- a/lib/private/BackgroundJob/JobList.php
+++ b/lib/private/BackgroundJob/JobList.php
@@ -25,27 +25,34 @@
namespace OC\BackgroundJob;
use OCP\AppFramework\QueryException;
+use OCP\AppFramework\Utility\ITimeFactory;
use OCP\BackgroundJob\IJob;
use OCP\BackgroundJob\IJobList;
use OCP\AutoloadNotAllowedException;
use OCP\DB\QueryBuilder\IQueryBuilder;
+use OCP\IConfig;
+use OCP\IDBConnection;
class JobList implements IJobList {
- /** @var \OCP\IDBConnection */
+
+ /** @var IDBConnection */
protected $connection;
- /**
- * @var \OCP\IConfig $config
- */
+ /**@var IConfig */
protected $config;
+ /**@var ITimeFactory */
+ protected $timeFactory;
+
/**
- * @param \OCP\IDBConnection $connection
- * @param \OCP\IConfig $config
+ * @param IDBConnection $connection
+ * @param IConfig $config
+ * @param ITimeFactory $timeFactory
*/
- public function __construct($connection, $config) {
+ public function __construct(IDBConnection $connection, IConfig $config, ITimeFactory $timeFactory) {
$this->connection = $connection;
$this->config = $config;
+ $this->timeFactory = $timeFactory;
}
/**
@@ -71,6 +78,7 @@ class JobList implements IJobList {
'class' => $query->createNamedParameter($class),
'argument' => $query->createNamedParameter($argument),
'last_run' => $query->createNamedParameter(0, IQueryBuilder::PARAM_INT),
+ 'last_checked' => $query->createNamedParameter($this->timeFactory->getTime(), IQueryBuilder::PARAM_INT),
]);
$query->execute();
}
@@ -167,45 +175,40 @@ class JobList implements IJobList {
* @return IJob|null
*/
public function getNext() {
- $lastId = $this->getLastJob();
-
$query = $this->connection->getQueryBuilder();
$query->select('*')
->from('jobs')
- ->where($query->expr()->lt('id', $query->createNamedParameter($lastId, IQueryBuilder::PARAM_INT)))
- ->orderBy('id', 'DESC')
+ ->where($query->expr()->lte('reserved_at', $query->createNamedParameter($this->timeFactory->getTime() - 12 * 3600, IQueryBuilder::PARAM_INT)))
+ ->orderBy('last_checked', 'ASC')
->setMaxResults(1);
+
+ $update = $this->connection->getQueryBuilder();
+ $update->update('jobs')
+ ->set('reserved_at', $update->createNamedParameter($this->timeFactory->getTime()))
+ ->set('last_checked', $update->createNamedParameter($this->timeFactory->getTime()))
+ ->where($update->expr()->eq('id', $update->createParameter('jobid')));
+
+ $this->connection->lockTable('jobs');
$result = $query->execute();
$row = $result->fetch();
$result->closeCursor();
if ($row) {
- $jobId = $row['id'];
+ $update->setParameter('jobid', $row['id']);
+ $update->execute();
+ $this->connection->unlockTable();
+
$job = $this->buildJob($row);
- } else {
- //begin at the start of the queue
- $query = $this->connection->getQueryBuilder();
- $query->select('*')
- ->from('jobs')
- ->orderBy('id', 'DESC')
- ->setMaxResults(1);
- $result = $query->execute();
- $row = $result->fetch();
- $result->closeCursor();
-
- if ($row) {
- $jobId = $row['id'];
- $job = $this->buildJob($row);
- } else {
- return null; //empty job list
+
+ if ($job === null) {
+ // Background job from disabled app, try again.
+ return $this->getNext();
}
- }
- if (is_null($job)) {
- $this->removeById($jobId);
- return $this->getNext();
- } else {
return $job;
+ } else {
+ $this->connection->unlockTable();
+ return null;
}
}
@@ -267,13 +270,30 @@ class JobList implements IJobList {
* @param IJob $job
*/
public function setLastJob($job) {
+ $this->unlockJob($job);
$this->config->setAppValue('backgroundjob', 'lastjob', $job->getId());
}
/**
+ * Remove the reservation for a job
+ *
+ * @param IJob $job
+ */
+ public function unlockJob($job) {
+ $query = $this->connection->getQueryBuilder();
+ $query->update('jobs')
+ ->set('reserved_at', $query->expr()->literal(0, IQueryBuilder::PARAM_INT))
+ ->where($query->expr()->eq('id', $query->createNamedParameter($job->getId(), IQueryBuilder::PARAM_INT)));
+ $query->execute();
+ }
+
+ /**
* get the id of the last ran job
*
* @return int
+ * @deprecated 9.1.0 - The functionality behind the value is deprecated, it
+ * only tells you which job finished last, but since we now allow multiple
+ * executors to run in parallel, it's not used to calculate the next job.
*/
public function getLastJob() {
return (int) $this->config->getAppValue('backgroundjob', 'lastjob', 0);
diff --git a/lib/private/Cache/File.php b/lib/private/Cache/File.php
index 989e05275b7..38f88959bd7 100644
--- a/lib/private/Cache/File.php
+++ b/lib/private/Cache/File.php
@@ -172,7 +172,9 @@ class File implements ICache {
public function gc() {
$storage = $this->getStorage();
if ($storage and $storage->is_dir('/')) {
- $now = time();
+ // extra hour safety, in case of stray part chunks that take longer to write,
+ // because touch() is only called after the chunk was finished
+ $now = time() - 3600;
$dh = $storage->opendir('/');
if (!is_resource($dh)) {
return null;
diff --git a/lib/private/Console/Application.php b/lib/private/Console/Application.php
index 7f12db4eca6..dd5111743f1 100644
--- a/lib/private/Console/Application.php
+++ b/lib/private/Console/Application.php
@@ -98,7 +98,7 @@ class Application {
if($appPath === false) {
continue;
}
- \OC::$loader->addValidRoot($appPath);
+ \OC_App::registerAutoloading($app, $appPath);
$file = $appPath . '/appinfo/register_command.php';
if (file_exists($file)) {
require $file;
diff --git a/lib/private/DB/Adapter.php b/lib/private/DB/Adapter.php
index 9522f768c88..bcced395cb7 100644
--- a/lib/private/DB/Adapter.php
+++ b/lib/private/DB/Adapter.php
@@ -58,6 +58,26 @@ class Adapter {
}
/**
+ * Create an exclusive read+write lock on a table
+ *
+ * @param string $tableName
+ * @since 9.1.0
+ */
+ public function lockTable($tableName) {
+ $this->conn->beginTransaction();
+ $this->conn->executeUpdate('LOCK TABLE `' .$tableName . '` IN EXCLUSIVE MODE');
+ }
+
+ /**
+ * Release a previous acquired lock again
+ *
+ * @since 9.1.0
+ */
+ public function unlockTable() {
+ $this->conn->commit();
+ }
+
+ /**
* Insert a row if the matching row does not exists.
*
* @param string $table The table name (will replace *PREFIX* with the actual prefix)
diff --git a/lib/private/DB/AdapterMySQL.php b/lib/private/DB/AdapterMySQL.php
index ab87c589747..8504fc74e0f 100644
--- a/lib/private/DB/AdapterMySQL.php
+++ b/lib/private/DB/AdapterMySQL.php
@@ -24,6 +24,18 @@
namespace OC\DB;
class AdapterMySQL extends Adapter {
+
+ /**
+ * @param string $tableName
+ */
+ public function lockTable($tableName) {
+ $this->conn->executeUpdate('LOCK TABLES `' .$tableName . '` WRITE');
+ }
+
+ public function unlockTable() {
+ $this->conn->executeUpdate('UNLOCK TABLES');
+ }
+
public function fixupStatement($statement) {
$statement = str_replace(' ILIKE ', ' COLLATE utf8_general_ci LIKE ', $statement);
return $statement;
diff --git a/lib/private/DB/AdapterSqlite.php b/lib/private/DB/AdapterSqlite.php
index 3466e0e1aac..cefb06ffac6 100644
--- a/lib/private/DB/AdapterSqlite.php
+++ b/lib/private/DB/AdapterSqlite.php
@@ -27,6 +27,18 @@
namespace OC\DB;
class AdapterSqlite extends Adapter {
+
+ /**
+ * @param string $tableName
+ */
+ public function lockTable($tableName) {
+ $this->conn->executeUpdate('BEGIN EXCLUSIVE TRANSACTION');
+ }
+
+ public function unlockTable() {
+ $this->conn->executeUpdate('COMMIT TRANSACTION');
+ }
+
public function fixupStatement($statement) {
$statement = preg_replace('( I?LIKE \?)', '$0 ESCAPE \'\\\'', $statement);
$statement = preg_replace('/`(\w+)` ILIKE \?/', 'LOWER($1) LIKE LOWER(?)', $statement);
diff --git a/lib/private/DB/Connection.php b/lib/private/DB/Connection.php
index 7904fab0726..5b7026db2f3 100644
--- a/lib/private/DB/Connection.php
+++ b/lib/private/DB/Connection.php
@@ -25,6 +25,7 @@
*/
namespace OC\DB;
+
use Doctrine\DBAL\DBALException;
use Doctrine\DBAL\Driver;
use Doctrine\DBAL\Configuration;
@@ -33,7 +34,7 @@ use Doctrine\Common\EventManager;
use OC\DB\QueryBuilder\QueryBuilder;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\IDBConnection;
-use OCP\PreconditionNotMetException;
+use OCP\PreConditionNotMetException;
class Connection extends \Doctrine\DBAL\Connection implements IDBConnection {
/**
@@ -46,6 +47,8 @@ class Connection extends \Doctrine\DBAL\Connection implements IDBConnection {
*/
protected $adapter;
+ protected $lockedTable = null;
+
public function connect() {
try {
return parent::connect();
@@ -262,7 +265,7 @@ class Connection extends \Doctrine\DBAL\Connection implements IDBConnection {
* @param array $updatePreconditionValues ensure values match preconditions (column name => value)
* @return int number of new rows
* @throws \Doctrine\DBAL\DBALException
- * @throws PreconditionNotMetException
+ * @throws PreConditionNotMetException
*/
public function setValues($table, array $keys, array $values, array $updatePreconditionValues = []) {
try {
@@ -281,7 +284,7 @@ class Connection extends \Doctrine\DBAL\Connection implements IDBConnection {
foreach ($values as $name => $value) {
$updateQb->set($name, $updateQb->createNamedParameter($value, $this->getType($value)));
}
- $where = $updateQb->expr()->andx();
+ $where = $updateQb->expr()->andX();
$whereValues = array_merge($keys, $updatePreconditionValues);
foreach ($whereValues as $name => $value) {
$where->add($updateQb->expr()->eq(
@@ -294,7 +297,7 @@ class Connection extends \Doctrine\DBAL\Connection implements IDBConnection {
$affected = $updateQb->execute();
if ($affected === 0 && !empty($updatePreconditionValues)) {
- throw new PreconditionNotMetException();
+ throw new PreConditionNotMetException();
}
return 0;
@@ -302,6 +305,33 @@ class Connection extends \Doctrine\DBAL\Connection implements IDBConnection {
}
/**
+ * Create an exclusive read+write lock on a table
+ *
+ * @param string $tableName
+ * @throws \BadMethodCallException When trying to acquire a second lock
+ * @since 9.1.0
+ */
+ public function lockTable($tableName) {
+ if ($this->lockedTable !== null) {
+ throw new \BadMethodCallException('Can not lock a new table until the previous lock is released.');
+ }
+
+ $tableName = $this->tablePrefix . $tableName;
+ $this->lockedTable = $tableName;
+ $this->adapter->lockTable($tableName);
+ }
+
+ /**
+ * Release a previous acquired lock again
+ *
+ * @since 9.1.0
+ */
+ public function unlockTable() {
+ $this->adapter->unlockTable();
+ $this->lockedTable = null;
+ }
+
+ /**
* returns the error code and message as a string for logging
* works with DoctrineException
* @return string
diff --git a/lib/private/datetimeformatter.php b/lib/private/DateTimeFormatter.php
index 5639ab1cace..5639ab1cace 100644
--- a/lib/private/datetimeformatter.php
+++ b/lib/private/DateTimeFormatter.php
diff --git a/lib/private/datetimezone.php b/lib/private/DateTimeZone.php
index 5359cd6b391..5359cd6b391 100644
--- a/lib/private/datetimezone.php
+++ b/lib/private/DateTimeZone.php
diff --git a/lib/private/Files/Cache/Wrapper/CacheJail.php b/lib/private/Files/Cache/Wrapper/CacheJail.php
index 3148d1412f4..d737d28fc80 100644
--- a/lib/private/Files/Cache/Wrapper/CacheJail.php
+++ b/lib/private/Files/Cache/Wrapper/CacheJail.php
@@ -303,6 +303,6 @@ class CacheJail extends CacheWrapper {
if ($sourceCache === $this) {
return $this->move($sourcePath, $targetPath);
}
- return $this->cache->moveFromCache($sourceCache, $sourcePath, $targetPath);
+ return $this->cache->moveFromCache($sourceCache, $sourcePath, $this->getSourcePath($targetPath));
}
}
diff --git a/lib/private/Files/Config/MountProviderCollection.php b/lib/private/Files/Config/MountProviderCollection.php
index 499fa576fbc..60c90d7a019 100644
--- a/lib/private/Files/Config/MountProviderCollection.php
+++ b/lib/private/Files/Config/MountProviderCollection.php
@@ -24,6 +24,7 @@ namespace OC\Files\Config;
use OC\Hooks\Emitter;
use OC\Hooks\EmitterTrait;
+use OCP\Files\Config\IHomeMountProvider;
use OCP\Files\Config\IMountProviderCollection;
use OCP\Files\Config\IMountProvider;
use OCP\Files\Config\IUserMountCache;
@@ -35,6 +36,11 @@ class MountProviderCollection implements IMountProviderCollection, Emitter {
use EmitterTrait;
/**
+ * @var \OCP\Files\Config\IHomeMountProvider[]
+ */
+ private $homeProviders = [];
+
+ /**
* @var \OCP\Files\Config\IMountProvider[]
*/
private $providers = array();
@@ -78,6 +84,25 @@ class MountProviderCollection implements IMountProviderCollection, Emitter {
}
/**
+ * Get the configured home mount for this user
+ *
+ * @param \OCP\IUser $user
+ * @return \OCP\Files\Mount\IMountPoint
+ * @since 9.1.0
+ */
+ public function getHomeMountForUser(IUser $user) {
+ /** @var \OCP\Files\Config\IHomeMountProvider[] $providers */
+ $providers = array_reverse($this->homeProviders); // call the latest registered provider first to give apps an opportunity to overwrite builtin
+ foreach ($providers as $homeProvider) {
+ if ($mount = $homeProvider->getHomeMountForUser($user, $this->loader)) {
+ $mount->setMountPoint('/' . $user->getUID()); //make sure the mountpoint is what we expect
+ return $mount;
+ }
+ }
+ throw new \Exception('No home storage configured for user ' . $user);
+ }
+
+ /**
* Add a provider for mount points
*
* @param \OCP\Files\Config\IMountProvider $provider
@@ -88,6 +113,17 @@ class MountProviderCollection implements IMountProviderCollection, Emitter {
}
/**
+ * Add a provider for home mount points
+ *
+ * @param \OCP\Files\Config\IHomeMountProvider $provider
+ * @since 9.1.0
+ */
+ public function registerHomeProvider(IHomeMountProvider $provider) {
+ $this->homeProviders[] = $provider;
+ $this->emit('\OC\Files\Config', 'registerHomeMountProvider', [$provider]);
+ }
+
+ /**
* Cache mounts for user
*
* @param IUser $user
diff --git a/lib/private/Files/Filesystem.php b/lib/private/Files/Filesystem.php
index 7283c815c97..70236773448 100644
--- a/lib/private/Files/Filesystem.php
+++ b/lib/private/Files/Filesystem.php
@@ -58,6 +58,7 @@
namespace OC\Files;
+use OC\Cache\CappedMemoryCache;
use OC\Files\Config\MountProviderCollection;
use OC\Files\Mount\MountPoint;
use OC\Files\Storage\StorageFactory;
@@ -81,7 +82,7 @@ class Filesystem {
static private $usersSetup = array();
- static private $normalizedPathCache = array();
+ static private $normalizedPathCache = null;
static private $listeningForProviders = false;
@@ -207,12 +208,30 @@ class Filesystem {
*/
private static $loader;
+ /** @var bool */
+ private static $logWarningWhenAddingStorageWrapper = true;
+
+ /**
+ * @param bool $shouldLog
+ * @internal
+ */
+ public static function logWarningWhenAddingStorageWrapper($shouldLog) {
+ self::$logWarningWhenAddingStorageWrapper = (bool) $shouldLog;
+ }
+
/**
* @param string $wrapperName
* @param callable $wrapper
* @param int $priority
*/
public static function addStorageWrapper($wrapperName, $wrapper, $priority = 50) {
+ if (self::$logWarningWhenAddingStorageWrapper) {
+ \OC::$server->getLogger()->warning("Storage wrapper '{wrapper}' was not registered via the 'OC_Filesystem - preSetup' hook which could cause potential problems.", [
+ 'wrapper' => $wrapperName,
+ 'app' => 'filesystem',
+ ]);
+ }
+
$mounts = self::getMountManager()->getAll();
if (!self::getLoader()->addStorageWrapper($wrapperName, $wrapper, $priority, $mounts)) {
// do not re-wrap if storage with this name already existed
@@ -378,7 +397,6 @@ class Filesystem {
if (isset(self::$usersSetup[$user])) {
return;
}
- $root = \OC_User::getHome($user);
$userManager = \OC::$server->getUserManager();
$userObject = $userManager->get($user);
@@ -390,52 +408,26 @@ class Filesystem {
self::$usersSetup[$user] = true;
- $homeStorage = \OC::$server->getConfig()->getSystemValue('objectstore');
- if (!empty($homeStorage)) {
- // sanity checks
- if (empty($homeStorage['class'])) {
- \OCP\Util::writeLog('files', 'No class given for objectstore', \OCP\Util::ERROR);
- }
- if (!isset($homeStorage['arguments'])) {
- $homeStorage['arguments'] = array();
- }
- // instantiate object store implementation
- $homeStorage['arguments']['objectstore'] = new $homeStorage['class']($homeStorage['arguments']);
- // mount with home object store implementation
- $homeStorage['class'] = '\OC\Files\ObjectStore\HomeObjectStoreStorage';
- } else {
- $homeStorage = array(
- //default home storage configuration:
- 'class' => '\OC\Files\Storage\Home',
- 'arguments' => array()
- );
- }
- $homeStorage['arguments']['user'] = $userObject;
-
- // check for legacy home id (<= 5.0.12)
- if (\OC\Files\Cache\Storage::exists('local::' . $root . '/')) {
- $homeStorage['arguments']['legacy'] = true;
- }
+ /** @var \OC\Files\Config\MountProviderCollection $mountConfigManager */
+ $mountConfigManager = \OC::$server->getMountProviderCollection();
- $mount = new MountPoint($homeStorage['class'], '/' . $user, $homeStorage['arguments'], self::getLoader());
- self::getMountManager()->addMount($mount);
+ // home mounts are handled seperate since we need to ensure this is mounted before we call the other mount providers
+ $homeMount = $mountConfigManager->getHomeMountForUser($userObject);
- $home = \OC\Files\Filesystem::getStorage($user);
+ self::getMountManager()->addMount($homeMount);
- self::mountCacheDir($user);
+ \OC\Files\Filesystem::getStorage($user);
// Chance to mount for other storages
- /** @var \OC\Files\Config\MountProviderCollection $mountConfigManager */
- $mountConfigManager = \OC::$server->getMountProviderCollection();
if ($userObject) {
$mounts = $mountConfigManager->getMountsForUser($userObject);
array_walk($mounts, array(self::$mounts, 'addMount'));
- $mounts[] = $mount;
+ $mounts[] = $homeMount;
$mountConfigManager->registerMounts($userObject, $mounts);
}
self::listenForNewMountProviders($mountConfigManager, $userManager);
- \OC_Hook::emit('OC_Filesystem', 'post_initMountPoints', array('user' => $user, 'user_dir' => $root));
+ \OC_Hook::emit('OC_Filesystem', 'post_initMountPoints', array('user' => $user));
}
/**
@@ -460,23 +452,6 @@ class Filesystem {
}
/**
- * Mounts the cache directory
- *
- * @param string $user user name
- */
- private static function mountCacheDir($user) {
- $cacheBaseDir = \OC::$server->getConfig()->getSystemValue('cache_path', '');
- if ($cacheBaseDir !== '') {
- $cacheDir = rtrim($cacheBaseDir, '/') . '/' . $user;
- if (!file_exists($cacheDir)) {
- mkdir($cacheDir, 0770, true);
- }
- // mount external cache dir to "/$user/cache" mount point
- self::mount('\OC\Files\Storage\Local', array('datadir' => $cacheDir), '/' . $user . '/cache');
- }
- }
-
- /**
* get the default filesystem view
*
* @return View
@@ -789,11 +764,16 @@ class Filesystem {
* Fix common problems with a file path
*
* @param string $path
- * @param bool $stripTrailingSlash
- * @param bool $isAbsolutePath
+ * @param bool $stripTrailingSlash whether to strip the trailing slash
+ * @param bool $isAbsolutePath whether the given path is absolute
+ * @param bool $keepUnicode true to disable unicode normalization
* @return string
*/
- public static function normalizePath($path, $stripTrailingSlash = true, $isAbsolutePath = false) {
+ public static function normalizePath($path, $stripTrailingSlash = true, $isAbsolutePath = false, $keepUnicode = false) {
+ if (is_null(self::$normalizedPathCache)) {
+ self::$normalizedPathCache = new CappedMemoryCache();
+ }
+
/**
* FIXME: This is a workaround for existing classes and files which call
* this function with another type than a valid string. This
@@ -813,19 +793,13 @@ class Filesystem {
}
//normalize unicode if possible
- $path = \OC_Util::normalizeUnicode($path);
+ if (!$keepUnicode) {
+ $path = \OC_Util::normalizeUnicode($path);
+ }
//no windows style slashes
$path = str_replace('\\', '/', $path);
- // When normalizing an absolute path, we need to ensure that the drive-letter
- // is still at the beginning on windows
- $windows_drive_letter = '';
- if ($isAbsolutePath && \OC_Util::runningOnWindows() && preg_match('#^([a-zA-Z])$#', $path[0]) && $path[1] == ':' && $path[2] == '/') {
- $windows_drive_letter = substr($path, 0, 2);
- $path = substr($path, 2);
- }
-
//add leading slash
if ($path[0] !== '/') {
$path = '/' . $path;
@@ -851,7 +825,7 @@ class Filesystem {
$path = substr($path, 0, -2);
}
- $normalizedPath = $windows_drive_letter . $path;
+ $normalizedPath = $path;
self::$normalizedPathCache[$cacheKey] = $normalizedPath;
return $normalizedPath;
diff --git a/lib/private/Files/Mount/CacheMountProvider.php b/lib/private/Files/Mount/CacheMountProvider.php
new file mode 100644
index 00000000000..c8422c4a507
--- /dev/null
+++ b/lib/private/Files/Mount/CacheMountProvider.php
@@ -0,0 +1,69 @@
+<?php
+/**
+ * @author Robin Appelman <icewind@owncloud.com>
+ *
+ * @copyright Copyright (c) 2016, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OC\Files\Mount;
+
+use OCP\Files\Config\IMountProvider;
+use OCP\Files\Storage\IStorageFactory;
+use OCP\IConfig;
+use OCP\IUser;
+
+/**
+ * Mount provider for custom cache storages
+ */
+class CacheMountProvider implements IMountProvider {
+ /**
+ * @var IConfig
+ */
+ private $config;
+
+ /**
+ * ObjectStoreHomeMountProvider constructor.
+ *
+ * @param IConfig $config
+ */
+ public function __construct(IConfig $config) {
+ $this->config = $config;
+ }
+
+ /**
+ * Get the cache mount for a user
+ *
+ * @param IUser $user
+ * @param IStorageFactory $loader
+ * @return \OCP\Files\Mount\IMountPoint[]
+ */
+ public function getMountsForUser(IUser $user, IStorageFactory $loader) {
+ $cacheBaseDir = $this->config->getSystemValue('cache_path', '');
+ if ($cacheBaseDir !== '') {
+ $cacheDir = rtrim($cacheBaseDir, '/') . '/' . $user->getUID();
+ if (!file_exists($cacheDir)) {
+ mkdir($cacheDir, 0770, true);
+ }
+
+ return [
+ new MountPoint('\OC\Files\Storage\Local', '/' . $user->getUID() . '/cache', ['datadir' => $cacheDir, $loader])
+ ];
+ } else {
+ return [];
+ }
+ }
+}
diff --git a/lib/private/Files/Mount/LocalHomeMountProvider.php b/lib/private/Files/Mount/LocalHomeMountProvider.php
new file mode 100644
index 00000000000..102df59a536
--- /dev/null
+++ b/lib/private/Files/Mount/LocalHomeMountProvider.php
@@ -0,0 +1,46 @@
+<?php
+/**
+ * @author Robin Appelman <icewind@owncloud.com>
+ *
+ * @copyright Copyright (c) 2016, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OC\Files\Mount;
+
+use OCP\Files\Config\IHomeMountProvider;
+use OCP\Files\Storage\IStorageFactory;
+use OCP\IUser;
+
+/**
+ * Mount provider for regular posix home folders
+ */
+class LocalHomeMountProvider implements IHomeMountProvider {
+ /**
+ * Get the cache mount for a user
+ *
+ * @param IUser $user
+ * @param IStorageFactory $loader
+ * @return \OCP\Files\Mount\IMountPoint[]
+ */
+ public function getHomeMountForUser(IUser $user, IStorageFactory $loader) {
+ $arguments = ['user' => $user];
+ if (\OC\Files\Cache\Storage::exists('local::' . $user->getHome() . '/')) {
+ $arguments['legacy'] = true;
+ }
+ return new MountPoint('\OC\Files\Storage\Home', '/' . $user->getUID(), $arguments, $loader);
+ }
+}
diff --git a/lib/private/Files/Mount/ObjectHomeMountProvider.php b/lib/private/Files/Mount/ObjectHomeMountProvider.php
new file mode 100644
index 00000000000..c910cf6bd45
--- /dev/null
+++ b/lib/private/Files/Mount/ObjectHomeMountProvider.php
@@ -0,0 +1,73 @@
+<?php
+/**
+ * @author Robin Appelman <icewind@owncloud.com>
+ *
+ * @copyright Copyright (c) 2016, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OC\Files\Mount;
+
+use OCP\Files\Config\IHomeMountProvider;
+use OCP\Files\Storage\IStorageFactory;
+use OCP\IConfig;
+use OCP\IUser;
+
+/**
+ * Mount provider for object store home storages
+ */
+class ObjectHomeMountProvider implements IHomeMountProvider {
+ /**
+ * @var IConfig
+ */
+ private $config;
+
+ /**
+ * ObjectStoreHomeMountProvider constructor.
+ *
+ * @param IConfig $config
+ */
+ public function __construct(IConfig $config) {
+ $this->config = $config;
+ }
+
+ /**
+ * Get the cache mount for a user
+ *
+ * @param IUser $user
+ * @param IStorageFactory $loader
+ * @return \OCP\Files\Mount\IMountPoint[]
+ */
+ public function getHomeMountForUser(IUser $user, IStorageFactory $loader) {
+ $config = $this->config->getSystemValue('objectstore');
+ if (!is_array($config)) {
+ return null; //fall back to local home provider
+ }
+
+ // sanity checks
+ if (empty($config['class'])) {
+ \OCP\Util::writeLog('files', 'No class given for objectstore', \OCP\Util::ERROR);
+ }
+ if (!isset($config['arguments'])) {
+ $config['arguments'] = [];
+ }
+ $config['arguments']['user'] = $user;
+ // instantiate object store implementation
+ $config['arguments']['objectstore'] = new $config['class']($config['arguments']);
+
+ return new MountPoint('\OC\Files\ObjectStore\HomeObjectStoreStorage', '/' . $user->getUID(), $config['arguments'], $loader);
+ }
+}
diff --git a/lib/private/Files/Storage/Wrapper/Availability.php b/lib/private/Files/Storage/Wrapper/Availability.php
index 0ed31ba854a..8d6fc4b3369 100644
--- a/lib/private/Files/Storage/Wrapper/Availability.php
+++ b/lib/private/Files/Storage/Wrapper/Availability.php
@@ -40,9 +40,13 @@ class Availability extends Wrapper {
}
/**
+ * Only called if availability === false
+ *
* @return bool
*/
private function updateAvailability() {
+ // reset availability to false so that multiple requests don't recheck concurrently
+ $this->setAvailability(false);
try {
$result = $this->test();
} catch (\Exception $e) {
diff --git a/lib/private/forbiddenexception.php b/lib/private/ForbiddenException.php
index 48be35ba316..48be35ba316 100644
--- a/lib/private/forbiddenexception.php
+++ b/lib/private/ForbiddenException.php
diff --git a/lib/private/group/backend.php b/lib/private/Group/Backend.php
index 3d8d71b1529..6dd5bdc3507 100644
--- a/lib/private/group/backend.php
+++ b/lib/private/Group/Backend.php
@@ -29,32 +29,12 @@
*
*/
-/**
- * error code for functions not provided by the group backend
- * @deprecated Use \OC_Group_Backend::NOT_IMPLEMENTED instead
- */
-define('OC_GROUP_BACKEND_NOT_IMPLEMENTED', -501);
-
-/**
- * actions that user backends can define
- */
-/** @deprecated Use \OC_Group_Backend::CREATE_GROUP instead */
-define('OC_GROUP_BACKEND_CREATE_GROUP', 0x00000001);
-/** @deprecated Use \OC_Group_Backend::DELETE_GROUP instead */
-define('OC_GROUP_BACKEND_DELETE_GROUP', 0x00000010);
-/** @deprecated Use \OC_Group_Backend::ADD_TO_GROUP instead */
-define('OC_GROUP_BACKEND_ADD_TO_GROUP', 0x00000100);
-/** @deprecated Use \OC_Group_Backend::REMOVE_FROM_GOUP instead */
-define('OC_GROUP_BACKEND_REMOVE_FROM_GOUP', 0x00001000);
-/** @deprecated Obsolete */
-define('OC_GROUP_BACKEND_GET_DISPLAYNAME', 0x00010000); //OBSOLETE
-/** @deprecated Use \OC_Group_Backend::COUNT_USERS instead */
-define('OC_GROUP_BACKEND_COUNT_USERS', 0x00100000);
+namespace OC\Group;
/**
* Abstract base class for user management
*/
-abstract class OC_Group_Backend implements \OCP\GroupInterface {
+abstract class Backend implements \OCP\GroupInterface {
/**
* error code for functions not provided by the group backend
*/
@@ -83,7 +63,7 @@ abstract class OC_Group_Backend implements \OCP\GroupInterface {
* @return int bitwise-or'ed actions
*
* Returns the supported actions as int to be
- * compared with \OC_Group_Backend::CREATE_GROUP etc.
+ * compared with \OC\Group\Backend::CREATE_GROUP etc.
*/
public function getSupportedActions() {
$actions = 0;
@@ -102,7 +82,7 @@ abstract class OC_Group_Backend implements \OCP\GroupInterface {
* @return bool
*
* Returns the supported actions as int to be
- * compared with \OC_Group_Backend::CREATE_GROUP etc.
+ * compared with \OC\Group\Backend::CREATE_GROUP etc.
*/
public function implementsActions($actions) {
return (bool)($this->getSupportedActions() & $actions);
diff --git a/lib/private/group/database.php b/lib/private/Group/Database.php
index 9ea0bbb8242..9fefdd77300 100644
--- a/lib/private/group/database.php
+++ b/lib/private/Group/Database.php
@@ -46,10 +46,12 @@
*
*/
+namespace OC\Group;
+
/**
* Class for group management in a SQL Database (e.g. MySQL, SQLite)
*/
-class OC_Group_Database extends OC_Group_Backend {
+class Database extends \OC\Group\Backend {
/** @var string[] */
private $groupCache = [];
@@ -58,7 +60,7 @@ class OC_Group_Database extends OC_Group_Backend {
private $dbConn;
/**
- * OC_Group_Database constructor.
+ * \OC\Group\Database constructor.
*
* @param \OCP\IDBConnection|null $dbConn
*/
@@ -245,7 +247,7 @@ class OC_Group_Database extends OC_Group_Backend {
$searchLike = ' WHERE LOWER(`gid`) LIKE LOWER(?)';
}
- $stmt = OC_DB::prepare('SELECT `gid` FROM `*PREFIX*groups`' . $searchLike . ' ORDER BY `gid` ASC', $limit, $offset);
+ $stmt = \OC_DB::prepare('SELECT `gid` FROM `*PREFIX*groups`' . $searchLike . ' ORDER BY `gid` ASC', $limit, $offset);
$result = $stmt->execute($parameters);
$groups = array();
while ($row = $result->fetchRow()) {
@@ -298,7 +300,7 @@ class OC_Group_Database extends OC_Group_Backend {
$searchLike = ' AND `uid` LIKE ?';
}
- $stmt = OC_DB::prepare('SELECT `uid` FROM `*PREFIX*group_user` WHERE `gid` = ?' . $searchLike . ' ORDER BY `uid` ASC',
+ $stmt = \OC_DB::prepare('SELECT `uid` FROM `*PREFIX*group_user` WHERE `gid` = ?' . $searchLike . ' ORDER BY `uid` ASC',
$limit,
$offset);
$result = $stmt->execute($parameters);
@@ -324,7 +326,7 @@ class OC_Group_Database extends OC_Group_Backend {
$searchLike = ' AND `uid` LIKE ?';
}
- $stmt = OC_DB::prepare('SELECT COUNT(`uid`) AS `count` FROM `*PREFIX*group_user` WHERE `gid` = ?' . $searchLike);
+ $stmt = \OC_DB::prepare('SELECT COUNT(`uid`) AS `count` FROM `*PREFIX*group_user` WHERE `gid` = ?' . $searchLike);
$result = $stmt->execute($parameters);
$count = $result->fetchOne();
if($count !== false) {
diff --git a/lib/private/group/group.php b/lib/private/Group/Group.php
index 064b9f899e6..c42f53af9a6 100644
--- a/lib/private/group/group.php
+++ b/lib/private/Group/Group.php
@@ -46,7 +46,7 @@ class Group implements IGroup {
private $usersLoaded;
/**
- * @var \OC_Group_Backend[]|\OC_Group_Database[] $backend
+ * @var \OC\Group\Backend[]|\OC\Group\Database[] $backend
*/
private $backends;
@@ -62,7 +62,7 @@ class Group implements IGroup {
/**
* @param string $gid
- * @param \OC_Group_Backend[] $backends
+ * @param \OC\Group\Backend[] $backends
* @param \OC\User\Manager $userManager
* @param \OC\Hooks\PublicEmitter $emitter
*/
@@ -136,7 +136,7 @@ class Group implements IGroup {
$this->emitter->emit('\OC\Group', 'preAddUser', array($this, $user));
}
foreach ($this->backends as $backend) {
- if ($backend->implementsActions(\OC_Group_Backend::ADD_TO_GROUP)) {
+ if ($backend->implementsActions(\OC\Group\Backend::ADD_TO_GROUP)) {
$backend->addToGroup($user->getUID(), $this->gid);
if ($this->users) {
$this->users[$user->getUID()] = $user;
@@ -160,7 +160,7 @@ class Group implements IGroup {
$this->emitter->emit('\OC\Group', 'preRemoveUser', array($this, $user));
}
foreach ($this->backends as $backend) {
- if ($backend->implementsActions(\OC_Group_Backend::REMOVE_FROM_GOUP) and $backend->inGroup($user->getUID(), $this->gid)) {
+ if ($backend->implementsActions(\OC\Group\Backend::REMOVE_FROM_GOUP) and $backend->inGroup($user->getUID(), $this->gid)) {
$backend->removeFromGroup($user->getUID(), $this->gid);
$result = true;
}
@@ -209,7 +209,7 @@ class Group implements IGroup {
public function count($search = '') {
$users = false;
foreach ($this->backends as $backend) {
- if($backend->implementsActions(\OC_Group_Backend::COUNT_USERS)) {
+ if($backend->implementsActions(\OC\Group\Backend::COUNT_USERS)) {
if($users === false) {
//we could directly add to a bool variable, but this would
//be ugly
@@ -257,7 +257,7 @@ class Group implements IGroup {
$this->emitter->emit('\OC\Group', 'preDelete', array($this));
}
foreach ($this->backends as $backend) {
- if ($backend->implementsActions(\OC_Group_Backend::DELETE_GROUP)) {
+ if ($backend->implementsActions(\OC\Group\Backend::DELETE_GROUP)) {
$result = true;
$backend->deleteGroup($this->gid);
}
diff --git a/lib/private/group/manager.php b/lib/private/Group/Manager.php
index e82a1d4f2e6..22367180edd 100644
--- a/lib/private/group/manager.php
+++ b/lib/private/Group/Manager.php
@@ -190,7 +190,7 @@ class Manager extends PublicEmitter implements IGroupManager {
} else {
$this->emit('\OC\Group', 'preCreate', array($gid));
foreach ($this->backends as $backend) {
- if ($backend->implementsActions(\OC_Group_Backend::CREATE_GROUP)) {
+ if ($backend->implementsActions(\OC\Group\Backend::CREATE_GROUP)) {
$backend->createGroup($gid);
$group = $this->getGroupObject($gid);
$this->emit('\OC\Group', 'postCreate', array($group));
diff --git a/lib/private/group/metadata.php b/lib/private/Group/MetaData.php
index 8e0866479c1..8e0866479c1 100644
--- a/lib/private/group/metadata.php
+++ b/lib/private/Group/MetaData.php
diff --git a/lib/private/httphelper.php b/lib/private/HTTPHelper.php
index f33d4a51745..f33d4a51745 100644
--- a/lib/private/httphelper.php
+++ b/lib/private/HTTPHelper.php
diff --git a/lib/private/hintexception.php b/lib/private/HintException.php
index aeddea481cc..aeddea481cc 100644
--- a/lib/private/hintexception.php
+++ b/lib/private/HintException.php
diff --git a/lib/private/Http/Client/Client.php b/lib/private/Http/Client/Client.php
index bd9e82ddae7..3f49b224d1e 100644
--- a/lib/private/Http/Client/Client.php
+++ b/lib/private/Http/Client/Client.php
@@ -39,6 +39,7 @@ class Client implements IClient {
private $config;
/** @var ICertificateManager */
private $certificateManager;
+ private $configured = false;
/**
* @param IConfig $config
@@ -51,13 +52,16 @@ class Client implements IClient {
$this->config = $config;
$this->client = $client;
$this->certificateManager = $certificateManager;
- $this->setDefaultOptions();
}
/**
* Sets the default options to the client
*/
private function setDefaultOptions() {
+ if ($this->configured) {
+ return;
+ }
+ $this->configured = true;
// Either use user bundle or the system bundle if nothing is specified
if ($this->certificateManager->listCertificates() !== []) {
$this->client->setDefaultOption('verify', $this->certificateManager->getAbsoluteBundlePath());
@@ -65,7 +69,7 @@ class Client implements IClient {
// If the instance is not yet setup we need to use the static path as
// $this->certificateManager->getAbsoluteBundlePath() tries to instantiiate
// a view
- if($this->config->getSystemValue('installed', false)) {
+ if ($this->config->getSystemValue('installed', false)) {
$this->client->setDefaultOption('verify', $this->certificateManager->getAbsoluteBundlePath(null));
} else {
$this->client->setDefaultOption('verify', \OC::$SERVERROOT . '/resources/config/ca-bundle.crt');
@@ -73,13 +77,14 @@ class Client implements IClient {
}
$this->client->setDefaultOption('headers/User-Agent', 'ownCloud Server Crawler');
- if($this->getProxyUri() !== '') {
+ if ($this->getProxyUri() !== '') {
$this->client->setDefaultOption('proxy', $this->getProxyUri());
}
}
/**
* Get the proxy URI
+ *
* @return string
*/
private function getProxyUri() {
@@ -87,10 +92,10 @@ class Client implements IClient {
$proxyUserPwd = $this->config->getSystemValue('proxyuserpwd', null);
$proxyUri = '';
- if(!is_null($proxyUserPwd)) {
- $proxyUri .= $proxyUserPwd.'@';
+ if (!is_null($proxyUserPwd)) {
+ $proxyUri .= $proxyUserPwd . '@';
}
- if(!is_null($proxyHost)) {
+ if (!is_null($proxyHost)) {
$proxyUri .= $proxyHost;
}
@@ -99,6 +104,7 @@ class Client implements IClient {
/**
* Sends a GET request
+ *
* @param string $uri
* @param array $options Array such as
* 'query' => [
@@ -126,6 +132,7 @@ class Client implements IClient {
* @throws \Exception If the request could not get completed
*/
public function get($uri, array $options = []) {
+ $this->setDefaultOptions();
$response = $this->client->get($uri, $options);
$isStream = isset($options['stream']) && $options['stream'];
return new Response($response, $isStream);
@@ -133,6 +140,7 @@ class Client implements IClient {
/**
* Sends a HEAD request
+ *
* @param string $uri
* @param array $options Array such as
* 'headers' => [
@@ -155,12 +163,14 @@ class Client implements IClient {
* @throws \Exception If the request could not get completed
*/
public function head($uri, $options = []) {
+ $this->setDefaultOptions();
$response = $this->client->head($uri, $options);
return new Response($response);
}
/**
* Sends a POST request
+ *
* @param string $uri
* @param array $options Array such as
* 'body' => [
@@ -188,12 +198,14 @@ class Client implements IClient {
* @throws \Exception If the request could not get completed
*/
public function post($uri, array $options = []) {
+ $this->setDefaultOptions();
$response = $this->client->post($uri, $options);
return new Response($response);
}
/**
* Sends a PUT request
+ *
* @param string $uri
* @param array $options Array such as
* 'body' => [
@@ -221,12 +233,14 @@ class Client implements IClient {
* @throws \Exception If the request could not get completed
*/
public function put($uri, array $options = []) {
+ $this->setDefaultOptions();
$response = $this->client->put($uri, $options);
return new Response($response);
}
/**
* Sends a DELETE request
+ *
* @param string $uri
* @param array $options Array such as
* 'body' => [
@@ -254,6 +268,7 @@ class Client implements IClient {
* @throws \Exception If the request could not get completed
*/
public function delete($uri, array $options = []) {
+ $this->setDefaultOptions();
$response = $this->client->delete($uri, $options);
return new Response($response);
}
@@ -261,6 +276,7 @@ class Client implements IClient {
/**
* Sends a options request
+ *
* @param string $uri
* @param array $options Array such as
* 'body' => [
@@ -288,6 +304,7 @@ class Client implements IClient {
* @throws \Exception If the request could not get completed
*/
public function options($uri, array $options = []) {
+ $this->setDefaultOptions();
$response = $this->client->options($uri, $options);
return new Response($response);
}
diff --git a/lib/private/installer.php b/lib/private/Installer.php
index 24c79b2dd8c..336fa0acef8 100644
--- a/lib/private/installer.php
+++ b/lib/private/Installer.php
@@ -37,15 +37,19 @@
*
*/
+namespace OC;
+
use OC\App\CodeChecker\CodeChecker;
use OC\App\CodeChecker\EmptyCheck;
use OC\App\CodeChecker\PrivateCheck;
-use OC\OCSClient;
+use OC_App;
+use OC_DB;
+use OC_Helper;
/**
* This class provides the functionality needed to install, update and remove plugins/apps
*/
-class OC_Installer{
+class Installer {
/**
*
@@ -129,21 +133,26 @@ class OC_Installer{
}
}
+ \OC_App::setupBackgroundJobs($info['background-jobs']);
+
//run appinfo/install.php
if((!isset($data['noinstall']) or $data['noinstall']==false)) {
self::includeAppScript($basedir . '/appinfo/install.php');
}
+ $appData = OC_App::getAppInfo($appId);
+ OC_App::executeRepairSteps($appId, $appData['repair-steps']['install']);
+
//set the installed version
- \OC::$server->getAppConfig()->setValue($info['id'], 'installed_version', OC_App::getAppVersion($info['id']));
- \OC::$server->getAppConfig()->setValue($info['id'], 'enabled', 'no');
+ \OC::$server->getConfig()->setAppValue($info['id'], 'installed_version', OC_App::getAppVersion($info['id']));
+ \OC::$server->getConfig()->setAppValue($info['id'], 'enabled', 'no');
- //set remote/public handelers
+ //set remote/public handlers
foreach($info['remote'] as $name=>$path) {
- OCP\CONFIG::setAppValue('core', 'remote_'.$name, $info['id'].'/'.$path);
+ \OC::$server->getConfig()->setAppValue('core', 'remote_'.$name, $info['id'].'/'.$path);
}
foreach($info['public'] as $name=>$path) {
- OCP\CONFIG::setAppValue('core', 'public_'.$name, $info['id'].'/'.$path);
+ \OC::$server->getConfig()->setAppValue('core', 'public_'.$name, $info['id'].'/'.$path);
}
OC_App::setAppTypes($info['id']);
@@ -158,15 +167,15 @@ class OC_Installer{
*
* Checks whether or not an app is installed, i.e. registered in apps table.
*/
- public static function isInstalled( $app ) {
- return (\OC::$server->getAppConfig()->getValue($app, "installed_version") !== null);
+ public static function isInstalled( $app ) {
+ return (\OC::$server->getConfig()->getAppValue($app, "installed_version", null) !== null);
}
/**
* @brief Update an application
* @param array $info
* @param bool $isShipped
- * @throws Exception
+ * @throws \Exception
* @return bool
*
* This function could work like described below, but currently it disables and then
@@ -229,7 +238,7 @@ class OC_Installer{
*
* @param integer $ocsId
* @return bool
- * @throws Exception
+ * @throws \Exception
*/
public static function updateAppByOCSId($ocsId) {
$ocsClient = new OCSClient(
@@ -257,7 +266,7 @@ class OC_Installer{
/**
* @param array $data
* @return array
- * @throws Exception
+ * @throws \Exception
*/
public static function downloadApp($data = array()) {
$l = \OC::$server->getL10N('lib');
@@ -293,7 +302,7 @@ class OC_Installer{
$extractDir = \OC::$server->getTempManager()->getTemporaryFolder();
OC_Helper::rmdirr($extractDir);
mkdir($extractDir);
- if($archive=OC_Archive::open($path)) {
+ if($archive=\OC\Archive\Archive::open($path)) {
$archive->extract($extractDir);
} else {
OC_Helper::rmdirr($extractDir);
@@ -375,7 +384,7 @@ class OC_Installer{
}
// check the code for not allowed calls
- if(!$isShipped && !OC_Installer::checkCode($extractDir)) {
+ if(!$isShipped && !Installer::checkCode($extractDir)) {
OC_Helper::rmdirr($extractDir);
throw new \Exception($l->t("App can't be installed because of not allowed code in the App"));
}
@@ -457,7 +466,7 @@ class OC_Installer{
* The function will check if the app is already downloaded in the apps repository
*/
public static function isDownloaded( $name ) {
- foreach(OC::$APPSROOTS as $dir) {
+ foreach(\OC::$APPSROOTS as $dir) {
$dirToTest = $dir['path'];
$dirToTest .= '/';
$dirToTest .= $name;
@@ -474,52 +483,25 @@ class OC_Installer{
/**
* Removes an app
* @param string $name name of the application to remove
- * @param array $options options
* @return boolean
*
- * This function removes an app. $options is an associative array. The
- * following keys are optional:ja
- * - keeppreferences: boolean, if true the user preferences won't be deleted
- * - keepappconfig: boolean, if true the config will be kept
- * - keeptables: boolean, if true the database will be kept
- * - keepfiles: boolean, if true the user files will be kept
*
* This function works as follows
- * -# including appinfo/remove.php
+ * -# call uninstall repair steps
* -# removing the files
*
* The function will not delete preferences, tables and the configuration,
* this has to be done by the function oc_app_uninstall().
*/
- public static function removeApp( $name, $options = array()) {
-
- if(isset($options['keeppreferences']) and $options['keeppreferences']==false ) {
- // todo
- // remove preferences
- }
-
- if(isset($options['keepappconfig']) and $options['keepappconfig']==false ) {
- // todo
- // remove app config
- }
-
- if(isset($options['keeptables']) and $options['keeptables']==false ) {
- // todo
- // remove app database tables
- }
-
- if(isset($options['keepfiles']) and $options['keepfiles']==false ) {
- // todo
- // remove user files
- }
+ public static function removeApp($appId) {
- if(OC_Installer::isDownloaded( $name )) {
- $appdir=OC_App::getInstallPath().'/'.$name;
- OC_Helper::rmdirr($appdir);
+ if(Installer::isDownloaded( $appId )) {
+ $appDir=OC_App::getInstallPath() . '/' . $appId;
+ OC_Helper::rmdirr($appDir);
return true;
}else{
- \OCP\Util::writeLog('core', 'can\'t remove app '.$name.'. It is not installed.', \OCP\Util::ERROR);
+ \OCP\Util::writeLog('core', 'can\'t remove app '.$appId.'. It is not installed.', \OCP\Util::ERROR);
return false;
}
@@ -536,25 +518,25 @@ class OC_Installer{
*/
public static function installShippedApps($softErrors = false) {
$errors = [];
- foreach(OC::$APPSROOTS as $app_dir) {
+ foreach(\OC::$APPSROOTS as $app_dir) {
if($dir = opendir( $app_dir['path'] )) {
while( false !== ( $filename = readdir( $dir ))) {
if( substr( $filename, 0, 1 ) != '.' and is_dir($app_dir['path']."/$filename") ) {
if( file_exists( $app_dir['path']."/$filename/appinfo/info.xml" )) {
- if(!OC_Installer::isInstalled($filename)) {
+ if(!Installer::isInstalled($filename)) {
$info=OC_App::getAppInfo($filename);
$enabled = isset($info['default_enable']);
if (($enabled || in_array($filename, \OC::$server->getAppManager()->getAlwaysEnabledApps()))
&& \OC::$server->getConfig()->getAppValue($filename, 'enabled') !== 'no') {
if ($softErrors) {
try {
- OC_Installer::installShippedApp($filename);
+ Installer::installShippedApp($filename);
} catch (\Doctrine\DBAL\Exception\TableExistsException $e) {
$errors[$filename] = $e;
continue;
}
} else {
- OC_Installer::installShippedApp($filename);
+ Installer::installShippedApp($filename);
}
\OC::$server->getConfig()->setAppValue($filename, 'enabled', 'yes');
}
@@ -582,13 +564,16 @@ class OC_Installer{
}
//run appinfo/install.php
- \OC::$loader->addValidRoot($appPath);
+ \OC_App::registerAutoloading($app, $appPath);
self::includeAppScript("$appPath/appinfo/install.php");
$info = OC_App::getAppInfo($app);
if (is_null($info)) {
return false;
}
+ \OC_App::setupBackgroundJobs($info['background-jobs']);
+
+ OC_App::executeRepairSteps($app, $info['repair-steps']['install']);
$config = \OC::$server->getConfig();
diff --git a/lib/private/L10N/Factory.php b/lib/private/L10N/Factory.php
index 8f157d9c0bb..08b92657a1b 100644
--- a/lib/private/L10N/Factory.php
+++ b/lib/private/L10N/Factory.php
@@ -263,7 +263,7 @@ class Factory implements IFactory {
}
}
- if (!$this->requestLanguage) {
+ if ($app === null && !$this->requestLanguage) {
$this->requestLanguage = 'en';
}
return 'en'; // Last try: English
diff --git a/lib/private/largefilehelper.php b/lib/private/LargeFileHelper.php
index f5252ee01e7..f5252ee01e7 100644
--- a/lib/private/largefilehelper.php
+++ b/lib/private/LargeFileHelper.php
diff --git a/lib/private/Lock/AbstractLockingProvider.php b/lib/private/Lock/AbstractLockingProvider.php
index f96358778c1..ff9f99a9630 100644
--- a/lib/private/Lock/AbstractLockingProvider.php
+++ b/lib/private/Lock/AbstractLockingProvider.php
@@ -77,6 +77,9 @@ abstract class AbstractLockingProvider implements ILockingProvider {
if ($type === self::LOCK_SHARED) {
if (isset($this->acquiredLocks['shared'][$path]) and $this->acquiredLocks['shared'][$path] > 0) {
$this->acquiredLocks['shared'][$path]--;
+ if ($this->acquiredLocks['shared'][$path] === 0) {
+ unset($this->acquiredLocks['shared'][$path]);
+ }
}
} else if ($type === self::LOCK_EXCLUSIVE) {
unset($this->acquiredLocks['exclusive'][$path]);
@@ -116,4 +119,8 @@ abstract class AbstractLockingProvider implements ILockingProvider {
$this->releaseLock($path, self::LOCK_EXCLUSIVE);
}
}
+
+ protected function getOwnSharedLockCount($path) {
+ return isset($this->acquiredLocks['shared'][$path]) ? $this->acquiredLocks['shared'][$path] : 0;
+ }
}
diff --git a/lib/private/Lock/MemcacheLockingProvider.php b/lib/private/Lock/MemcacheLockingProvider.php
index 536b29e2c28..56e581b2192 100644
--- a/lib/private/Lock/MemcacheLockingProvider.php
+++ b/lib/private/Lock/MemcacheLockingProvider.php
@@ -88,9 +88,14 @@ class MemcacheLockingProvider extends AbstractLockingProvider {
*/
public function releaseLock($path, $type) {
if ($type === self::LOCK_SHARED) {
- if (isset($this->acquiredLocks['shared'][$path]) and $this->acquiredLocks['shared'][$path] > 0) {
+ if ($this->getOwnSharedLockCount($path) === 1) {
+ $removed = $this->memcache->cad($path, 1); // if we're the only one having a shared lock we can remove it in one go
+ if (!$removed) { //someone else also has a shared lock, decrease only
+ $this->memcache->dec($path);
+ }
+ } else {
+ // if we own more than one lock ourselves just decrease
$this->memcache->dec($path);
- $this->memcache->cad($path, 0);
}
} else if ($type === self::LOCK_EXCLUSIVE) {
$this->memcache->cad($path, 'exclusive');
diff --git a/lib/private/log.php b/lib/private/Log.php
index bbdad9cf166..9248070c067 100644
--- a/lib/private/log.php
+++ b/lib/private/Log.php
@@ -73,7 +73,7 @@ class Log implements ILogger {
// FIXME: Add this for backwards compatibility, should be fixed at some point probably
if($logger === null) {
- $this->logger = 'OC_Log_'.ucfirst($this->config->getValue('log_type', 'owncloud'));
+ $this->logger = 'OC\\Log\\'.ucfirst($this->config->getValue('log_type', 'owncloud'));
call_user_func(array($this->logger, 'init'));
} else {
$this->logger = $logger;
@@ -284,7 +284,7 @@ class Log implements ILogger {
'File' => $exception->getFile(),
'Line' => $exception->getLine(),
);
- $exception['Trace'] = preg_replace('!(login|checkPassword|updatePrivateKeyPassword)\(.*\)!', '$1(*** username and password replaced ***)', $exception['Trace']);
+ $exception['Trace'] = preg_replace('!(login|checkPassword|updatePrivateKeyPassword|validateUserPass)\(.*\)!', '$1(*** username and password replaced ***)', $exception['Trace']);
$msg = isset($context['message']) ? $context['message'] : 'Exception';
$msg .= ': ' . json_encode($exception);
$this->error($msg, $context);
diff --git a/lib/private/log/errorhandler.php b/lib/private/Log/ErrorHandler.php
index 8899bcfcb03..8899bcfcb03 100644
--- a/lib/private/log/errorhandler.php
+++ b/lib/private/Log/ErrorHandler.php
diff --git a/lib/private/log/errorlog.php b/lib/private/Log/Errorlog.php
index ad3605136d0..37498c36aba 100644
--- a/lib/private/log/errorlog.php
+++ b/lib/private/Log/Errorlog.php
@@ -23,7 +23,9 @@
* THE SOFTWARE.
*/
-class OC_Log_Errorlog {
+namespace OC\Log;
+
+class Errorlog {
/**
diff --git a/lib/private/log/owncloud.php b/lib/private/Log/Owncloud.php
index 9c106299e4c..13997a0d552 100644
--- a/lib/private/log/owncloud.php
+++ b/lib/private/Log/Owncloud.php
@@ -27,13 +27,15 @@
*
*/
+namespace OC\Log;
+
/**
* logging utilities
*
* Log is saved at data/owncloud.log (on default)
*/
-class OC_Log_Owncloud {
+class Owncloud {
static protected $logFile;
/**
@@ -41,7 +43,7 @@ class OC_Log_Owncloud {
*/
public static function init() {
$systemConfig = \OC::$server->getSystemConfig();
- $defaultLogFile = $systemConfig->getValue("datadirectory", OC::$SERVERROOT.'/data').'/owncloud.log';
+ $defaultLogFile = $systemConfig->getValue("datadirectory", \OC::$SERVERROOT.'/data').'/owncloud.log';
self::$logFile = $systemConfig->getValue("logfile", $defaultLogFile);
/**
@@ -72,13 +74,13 @@ class OC_Log_Owncloud {
$format = $config->getValue('logdateformat', 'c');
$logTimeZone = $config->getValue( "logtimezone", 'UTC' );
try {
- $timezone = new DateTimeZone($logTimeZone);
- } catch (Exception $e) {
- $timezone = new DateTimeZone('UTC');
+ $timezone = new \DateTimeZone($logTimeZone);
+ } catch (\Exception $e) {
+ $timezone = new \DateTimeZone('UTC');
}
- $time = DateTime::createFromFormat("U.u", number_format(microtime(true), 4, ".", ""));
+ $time = \DateTime::createFromFormat("U.u", number_format(microtime(true), 4, ".", ""));
if ($time === false) {
- $time = new DateTime(null, $timezone);
+ $time = new \DateTime(null, $timezone);
} else {
// apply timezone if $time is created from UNIX timestamp
$time->setTimezone($timezone);
diff --git a/lib/private/log/rotate.php b/lib/private/Log/Rotate.php
index 458661c82d0..458661c82d0 100644
--- a/lib/private/log/rotate.php
+++ b/lib/private/Log/Rotate.php
diff --git a/lib/private/log/syslog.php b/lib/private/Log/Syslog.php
index 96cf463d042..115103f26d6 100644
--- a/lib/private/log/syslog.php
+++ b/lib/private/Log/Syslog.php
@@ -21,7 +21,9 @@
*
*/
-class OC_Log_Syslog {
+namespace OC\Log;
+
+class Syslog {
static protected $levels = array(
\OCP\Util::DEBUG => LOG_DEBUG,
\OCP\Util::INFO => LOG_INFO,
diff --git a/lib/private/Memcache/Memcached.php b/lib/private/Memcache/Memcached.php
index a30f9da7ed7..63ac73e9b9d 100644
--- a/lib/private/Memcache/Memcached.php
+++ b/lib/private/Memcache/Memcached.php
@@ -26,6 +26,7 @@
namespace OC\Memcache;
+use OC\HintException;
use OCP\IMemcache;
class Memcached extends Cache implements IMemcache {
@@ -52,6 +53,35 @@ class Memcached extends Cache implements IMemcache {
}
}
self::$cache->addServers($servers);
+
+ $defaultOptions = [
+ \Memcached::OPT_CONNECT_TIMEOUT => 50,
+ \Memcached::OPT_RETRY_TIMEOUT => 50,
+ \Memcached::OPT_SEND_TIMEOUT => 50,
+ \Memcached::OPT_RECV_TIMEOUT => 50,
+ \Memcached::OPT_POLL_TIMEOUT => 50,
+
+ // Enable compression
+ \Memcached::OPT_COMPRESSION => true,
+
+ // Turn on consistent hashing
+ \Memcached::OPT_LIBKETAMA_COMPATIBLE => true,
+
+ // Enable Binary Protocol
+ \Memcached::OPT_BINARY_PROTOCOL => true,
+ ];
+ // by default enable igbinary serializer if available
+ if (\Memcached::HAVE_IGBINARY) {
+ $defaultOptions[\Memcached::OPT_SERIALIZER] =
+ \Memcached::SERIALIZER_IGBINARY;
+ }
+ $options = \OC::$server->getConfig()->getSystemValue('memcached_options', []);
+ if (is_array($options)) {
+ $options = $options + $defaultOptions;
+ self::$cache->setOptions($options);
+ } else {
+ throw new HintException("Expected 'memcached_options' config to be an array, got $options");
+ }
}
}
diff --git a/lib/private/Memcache/Redis.php b/lib/private/Memcache/Redis.php
index b3444a2b4e9..5b6955823c4 100644
--- a/lib/private/Memcache/Redis.php
+++ b/lib/private/Memcache/Redis.php
@@ -37,33 +37,7 @@ class Redis extends Cache implements IMemcacheTTL {
public function __construct($prefix = '') {
parent::__construct($prefix);
if (is_null(self::$cache)) {
- // TODO allow configuring a RedisArray, see https://github.com/nicolasff/phpredis/blob/master/arrays.markdown#redis-arrays
- self::$cache = new \Redis();
- $config = \OC::$server->getSystemConfig()->getValue('redis', array());
- if (isset($config['host'])) {
- $host = $config['host'];
- } else {
- $host = '127.0.0.1';
- }
- if (isset($config['port'])) {
- $port = $config['port'];
- } else {
- $port = 6379;
- }
- if (isset($config['timeout'])) {
- $timeout = $config['timeout'];
- } else {
- $timeout = 0.0; // unlimited
- }
-
- self::$cache->connect($host, $port, $timeout);
- if(isset($config['password']) && $config['password'] !== '') {
- self::$cache->auth($config['password']);
- }
-
- if (isset($config['dbindex'])) {
- self::$cache->select($config['dbindex']);
- }
+ self::$cache = \OC::$server->getGetRedisFactory()->getInstance();
}
}
@@ -201,8 +175,7 @@ class Redis extends Cache implements IMemcacheTTL {
}
static public function isAvailable() {
- return extension_loaded('redis')
- && version_compare(phpversion('redis'), '2.2.5', '>=');
+ return \OC::$server->getGetRedisFactory()->isAvailable();
}
}
diff --git a/lib/private/naturalsort.php b/lib/private/NaturalSort.php
index f44e8032d36..f44e8032d36 100644
--- a/lib/private/naturalsort.php
+++ b/lib/private/NaturalSort.php
diff --git a/lib/private/naturalsort_defaultcollator.php b/lib/private/NaturalSort_DefaultCollator.php
index 7b8400fa8e1..7b8400fa8e1 100644
--- a/lib/private/naturalsort_defaultcollator.php
+++ b/lib/private/NaturalSort_DefaultCollator.php
diff --git a/lib/private/navigationmanager.php b/lib/private/NavigationManager.php
index 6dbb9c925e0..6dbb9c925e0 100644
--- a/lib/private/navigationmanager.php
+++ b/lib/private/NavigationManager.php
diff --git a/lib/private/needsupdateexception.php b/lib/private/NeedsUpdateException.php
index 90c642780d8..90c642780d8 100644
--- a/lib/private/needsupdateexception.php
+++ b/lib/private/NeedsUpdateException.php
diff --git a/lib/private/notsquareexception.php b/lib/private/NotSquareException.php
index e3494463850..e3494463850 100644
--- a/lib/private/notsquareexception.php
+++ b/lib/private/NotSquareException.php
diff --git a/lib/private/ocs/cloud.php b/lib/private/OCS/Cloud.php
index 1d47fb208a7..9686e9bfb58 100644
--- a/lib/private/ocs/cloud.php
+++ b/lib/private/OCS/Cloud.php
@@ -22,7 +22,9 @@
*
*/
-class OC_OCS_Cloud {
+namespace OC\OCS;
+
+class Cloud {
public static function getCapabilities() {
$result = array();
@@ -31,22 +33,22 @@ class OC_OCS_Cloud {
'major' => $major,
'minor' => $minor,
'micro' => $micro,
- 'string' => OC_Util::getVersionString(),
- 'edition' => OC_Util::getEditionString(),
+ 'string' => \OC_Util::getVersionString(),
+ 'edition' => \OC_Util::getEditionString(),
);
$result['capabilities'] = \OC::$server->getCapabilitiesManager()->getCapabilities();
- return new OC_OCS_Result($result);
+ return new Result($result);
}
public static function getCurrentUser() {
- $userObject = \OC::$server->getUserManager()->get(OC_User::getUser());
+ $userObject = \OC::$server->getUserManager()->get(\OC_User::getUser());
$data = array(
'id' => $userObject->getUID(),
'display-name' => $userObject->getDisplayName(),
'email' => $userObject->getEMailAddress(),
);
- return new OC_OCS_Result($data);
+ return new Result($data);
}
}
diff --git a/lib/private/ocs/config.php b/lib/private/OCS/Config.php
index db04dcbd400..5478411d6fd 100644
--- a/lib/private/ocs/config.php
+++ b/lib/private/OCS/Config.php
@@ -21,15 +21,17 @@
*
*/
-class OC_OCS_Config {
+namespace OC\OCS;
+
+class Config {
public static function apiConfig() {
$xml['version'] = '1.7';
$xml['website'] = 'ownCloud';
- $xml['host'] = OCP\Util::getServerHost();
+ $xml['host'] = \OCP\Util::getServerHost();
$xml['contact'] = '';
$xml['ssl'] = 'false';
- return new OC_OCS_Result($xml);
+ return new Result($xml);
}
}
diff --git a/lib/private/ocs/corecapabilities.php b/lib/private/OCS/CoreCapabilities.php
index 388a58791b4..388a58791b4 100644
--- a/lib/private/ocs/corecapabilities.php
+++ b/lib/private/OCS/CoreCapabilities.php
diff --git a/lib/private/ocs/exception.php b/lib/private/OCS/Exception.php
index ca67ac5e841..33c88fcf7d3 100644
--- a/lib/private/ocs/exception.php
+++ b/lib/private/OCS/Exception.php
@@ -23,7 +23,7 @@ namespace OC\OCS;
class Exception extends \Exception {
- public function __construct(\OC_OCS_Result $result) {
+ public function __construct(Result $result) {
$this->result = $result;
}
diff --git a/lib/private/ocs/person.php b/lib/private/OCS/Person.php
index 7162fa5e4fb..fd33504e0a8 100644
--- a/lib/private/ocs/person.php
+++ b/lib/private/OCS/Person.php
@@ -21,20 +21,22 @@
*
*/
-class OC_OCS_Person {
+namespace OC\OCS;
+
+class Person {
public static function check() {
$login = isset($_POST['login']) ? $_POST['login'] : false;
$password = isset($_POST['password']) ? $_POST['password'] : false;
if($login && $password) {
- if(OC_User::checkPassword($login, $password)) {
+ if(\OC_User::checkPassword($login, $password)) {
$xml['person']['personid'] = $login;
- return new OC_OCS_Result($xml);
+ return new Result($xml);
} else {
- return new OC_OCS_Result(null, 102);
+ return new Result(null, 102);
}
} else {
- return new OC_OCS_Result(null, 101);
+ return new Result(null, 101);
}
}
diff --git a/lib/private/ocs/privatedata.php b/lib/private/OCS/PrivateData.php
index e514c05a3dd..c69d8b9cc17 100644
--- a/lib/private/ocs/privatedata.php
+++ b/lib/private/OCS/PrivateData.php
@@ -25,8 +25,9 @@
*
*/
+namespace OC\OCS;
-class OC_OCS_Privatedata {
+class PrivateData {
/**
* read keys
@@ -36,7 +37,7 @@ class OC_OCS_Privatedata {
* @return \OC_OCS_Result
*/
public static function get($parameters) {
- $user = OC_User::getUser();
+ $user = \OC_User::getUser();
$app = addslashes(strip_tags($parameters['app']));
$key = isset($parameters['key']) ? addslashes(strip_tags($parameters['key'])) : null;
@@ -57,7 +58,7 @@ class OC_OCS_Privatedata {
$xml[] = $data;
}
- return new OC_OCS_Result($xml);
+ return new Result($xml);
}
/**
@@ -67,7 +68,7 @@ class OC_OCS_Privatedata {
* @return \OC_OCS_Result
*/
public static function set($parameters) {
- $user = OC_User::getUser();
+ $user = \OC_User::getUser();
$app = addslashes(strip_tags($parameters['app']));
$key = addslashes(strip_tags($parameters['key']));
$value = (string)$_POST['value'];
@@ -82,7 +83,7 @@ class OC_OCS_Privatedata {
$query->execute(array($user, $app, $key, $value));
}
- return new OC_OCS_Result(null, 100);
+ return new Result(null, 100);
}
/**
@@ -92,10 +93,10 @@ class OC_OCS_Privatedata {
* @return \OC_OCS_Result
*/
public static function delete($parameters) {
- $user = OC_User::getUser();
+ $user = \OC_User::getUser();
if (!isset($parameters['app']) or !isset($parameters['key'])) {
//key and app are NOT optional here
- return new OC_OCS_Result(null, 101);
+ return new Result(null, 101);
}
$app = addslashes(strip_tags($parameters['app']));
@@ -105,7 +106,7 @@ class OC_OCS_Privatedata {
$query = \OCP\DB::prepare('DELETE FROM `*PREFIX*privatedata` WHERE `user` = ? AND `app` = ? AND `key` = ? ');
$query->execute(array($user, $app, $key ));
- return new OC_OCS_Result(null, 100);
+ return new Result(null, 100);
}
}
diff --git a/lib/private/OCS/Provider.php b/lib/private/OCS/Provider.php
new file mode 100644
index 00000000000..4a7caa79fa5
--- /dev/null
+++ b/lib/private/OCS/Provider.php
@@ -0,0 +1,96 @@
+<?php
+/**
+ * @author Lukas Reschke <lukas@owncloud.com>
+ *
+ * @copyright Copyright (c) 2015, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OC\OCS;
+
+class Provider extends \OCP\AppFramework\Controller {
+ /** @var \OCP\App\IAppManager */
+ private $appManager;
+
+ /**
+ * @param string $appName
+ * @param \OCP\IRequest $request
+ * @param \OCP\App\IAppManager $appManager
+ */
+ public function __construct($appName,
+ \OCP\IRequest $request,
+ \OCP\App\IAppManager $appManager) {
+ parent::__construct($appName, $request);
+ $this->appManager = $appManager;
+ }
+
+ /**
+ * @return \OCP\AppFramework\Http\JSONResponse
+ */
+ public function buildProviderList() {
+ $services = [
+ 'PRIVATE_DATA' => [
+ 'version' => 1,
+ 'endpoints' => [
+ 'store' => '/ocs/v2.php/privatedata/setattribute',
+ 'read' => '/ocs/v2.php/privatedata/getattribute',
+ 'delete' => '/ocs/v2.php/privatedata/deleteattribute',
+ ],
+ ],
+ ];
+
+ if($this->appManager->isEnabledForUser('files_sharing')) {
+ $services['SHARING'] = [
+ 'version' => 1,
+ 'endpoints' => [
+ 'share' => '/ocs/v2.php/apps/files_sharing/api/v1/shares',
+ ],
+ ];
+ $services['FEDERATED_SHARING'] = [
+ 'version' => 1,
+ 'endpoints' => [
+ 'share' => '/ocs/v2.php/cloud/shares',
+ 'webdav' => '/public.php/webdav/',
+ ],
+ ];
+ }
+
+ if($this->appManager->isEnabledForUser('activity')) {
+ $services['ACTIVITY'] = [
+ 'version' => 1,
+ 'endpoints' => [
+ 'list' => '/ocs/v2.php/cloud/activity',
+ ],
+ ];
+ }
+
+ if($this->appManager->isEnabledForUser('provisioning_api')) {
+ $services['PROVISIONING'] = [
+ 'version' => 1,
+ 'endpoints' => [
+ 'user' => '/ocs/v2.php/cloud/users',
+ 'groups' => '/ocs/v2.php/cloud/groups',
+ 'apps' => '/ocs/v2.php/cloud/apps',
+ ],
+ ];
+ }
+
+ return new \OCP\AppFramework\Http\JSONResponse([
+ 'version' => 2,
+ 'services' => $services,
+ ]);
+ }
+}
diff --git a/lib/private/ocs/result.php b/lib/private/OCS/Result.php
index c342bc582fe..c2c61e2383d 100644
--- a/lib/private/ocs/result.php
+++ b/lib/private/OCS/Result.php
@@ -26,7 +26,9 @@
*
*/
-class OC_OCS_Result{
+namespace OC\OCS;
+
+class Result {
/** @var array */
protected $data;
diff --git a/lib/private/ocsclient.php b/lib/private/OCSClient.php
index a783a1f8425..da2f5c61769 100644
--- a/lib/private/ocsclient.php
+++ b/lib/private/OCSClient.php
@@ -128,7 +128,7 @@ class OCSClient {
$response = $client->get(
$this->getAppStoreUrl() . '/content/categories',
[
- 'timeout' => 5,
+ 'timeout' => 20,
'query' => [
'version' => implode('x', $targetVersion),
],
@@ -179,7 +179,7 @@ class OCSClient {
$response = $client->get(
$this->getAppStoreUrl() . '/content/data',
[
- 'timeout' => 5,
+ 'timeout' => 20,
'query' => [
'version' => implode('x', $targetVersion),
'filter' => $filter,
@@ -256,7 +256,7 @@ class OCSClient {
$response = $client->get(
$this->getAppStoreUrl() . '/content/data/' . urlencode($id),
[
- 'timeout' => 5,
+ 'timeout' => 20,
'query' => [
'version' => implode('x', $targetVersion),
],
@@ -321,7 +321,7 @@ class OCSClient {
$response = $client->get(
$url,
[
- 'timeout' => 5,
+ 'timeout' => 20,
'query' => [
'version' => implode('x', $targetVersion),
],
diff --git a/lib/private/preview.php b/lib/private/Preview.php
index 4fca56dd984..4fca56dd984 100644
--- a/lib/private/preview.php
+++ b/lib/private/Preview.php
diff --git a/lib/private/previewmanager.php b/lib/private/PreviewManager.php
index f3c7a4de0d0..f3c7a4de0d0 100644
--- a/lib/private/previewmanager.php
+++ b/lib/private/PreviewManager.php
diff --git a/lib/private/RedisFactory.php b/lib/private/RedisFactory.php
new file mode 100644
index 00000000000..d286c0167b2
--- /dev/null
+++ b/lib/private/RedisFactory.php
@@ -0,0 +1,85 @@
+<?php
+/**
+ * @author Robin Appelman <icewind@owncloud.com>
+ *
+ * @copyright Copyright (c) 2016, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OC;
+
+class RedisFactory {
+ /** @var \Redis */
+ private $instance;
+
+ /** @var SystemConfig */
+ private $config;
+
+ /**
+ * RedisFactory constructor.
+ *
+ * @param SystemConfig $config
+ */
+ public function __construct(SystemConfig $config) {
+ $this->config = $config;
+ }
+
+ private function create() {
+ $this->instance = new \Redis();
+ // TODO allow configuring a RedisArray, see https://github.com/nicolasff/phpredis/blob/master/arrays.markdown#redis-arrays
+ $config = $this->config->getValue('redis', array());
+ if (isset($config['host'])) {
+ $host = $config['host'];
+ } else {
+ $host = '127.0.0.1';
+ }
+ if (isset($config['port'])) {
+ $port = $config['port'];
+ } else {
+ $port = 6379;
+ }
+ if (isset($config['timeout'])) {
+ $timeout = $config['timeout'];
+ } else {
+ $timeout = 0.0; // unlimited
+ }
+
+ $this->instance->connect($host, $port, $timeout);
+ if (isset($config['password']) && $config['password'] !== '') {
+ $this->instance->auth($config['password']);
+ }
+
+ if (isset($config['dbindex'])) {
+ $this->instance->select($config['dbindex']);
+ }
+ }
+
+ public function getInstance() {
+ if (!$this->isAvailable()) {
+ throw new \Exception('Redis support is not available');
+ }
+ if (!$this->instance instanceof \Redis) {
+ $this->create();
+ }
+
+ return $this->instance;
+ }
+
+ public function isAvailable() {
+ return extension_loaded('redis')
+ && version_compare(phpversion('redis'), '2.2.5', '>=');
+ }
+}
diff --git a/lib/private/repair.php b/lib/private/Repair.php
index 586e4e42b13..38752ee1703 100644
--- a/lib/private/repair.php
+++ b/lib/private/Repair.php
@@ -28,8 +28,6 @@
namespace OC;
-use OC\Hooks\BasicEmitter;
-use OC\Hooks\Emitter;
use OC\Repair\AssetCache;
use OC\Repair\CleanTags;
use OC\Repair\Collation;
@@ -46,16 +44,19 @@ use OC\Repair\RepairMimeTypes;
use OC\Repair\SearchLuceneTables;
use OC\Repair\UpdateOutdatedOcsIds;
use OC\Repair\RepairInvalidShares;
+use OCP\AppFramework\QueryException;
use OCP\Migration\IOutput;
use OCP\Migration\IRepairStep;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\EventDispatcher\GenericEvent;
-class Repair extends BasicEmitter implements IOutput{
+class Repair implements IOutput{
/* @var IRepairStep[] */
private $repairSteps;
/** @var EventDispatcher */
private $dispatcher;
+ /** @var string */
+ private $currentStep;
/**
* Creates a new repair step runner
@@ -72,24 +73,14 @@ class Repair extends BasicEmitter implements IOutput{
* Run a series of repair steps for common problems
*/
public function run() {
- $self = $this;
if (count($this->repairSteps) === 0) {
$this->emit('\OC\Repair', 'info', array('No repair steps available'));
return;
}
// run each repair step
foreach ($this->repairSteps as $step) {
- $this->emit('\OC\Repair', 'step', array($step->getName()));
-
- if ($step instanceof Emitter) {
- $step->listen('\OC\Repair', 'warning', function ($description) use ($self) {
- $self->emit('\OC\Repair', 'warning', array($description));
- });
- $step->listen('\OC\Repair', 'info', function ($description) use ($self) {
- $self->emit('\OC\Repair', 'info', array($description));
- });
- }
-
+ $this->currentStep = $step->getName();
+ $this->emit('\OC\Repair', 'step', [$this->currentStep]);
$step->run($this);
}
}
@@ -102,15 +93,20 @@ class Repair extends BasicEmitter implements IOutput{
*/
public function addStep($repairStep) {
if (is_string($repairStep)) {
- if (class_exists($repairStep)) {
- $s = new $repairStep();
- if ($s instanceof IRepairStep) {
- $this->repairSteps[] = $s;
+ try {
+ $s = \OC::$server->query($repairStep);
+ } catch (QueryException $e) {
+ if (class_exists($repairStep)) {
+ $s = new $repairStep();
} else {
- throw new \Exception("Repair step '$repairStep' is not of type \\OCP\\Migration\\IRepairStep");
+ throw new \Exception("Repair step '$repairStep' is unknown");
}
+ }
+
+ if ($s instanceof IRepairStep) {
+ $this->repairSteps[] = $s;
} else {
- throw new \Exception("Repair step '$repairStep' is unknown");
+ throw new \Exception("Repair step '$repairStep' is not of type \\OCP\\Migration\\IRepairStep");
}
} else {
$this->repairSteps[] = $repairStep;
@@ -178,10 +174,11 @@ class Repair extends BasicEmitter implements IOutput{
}
/**
- * {@inheritDoc}
+ * @param string $scope
+ * @param string $method
+ * @param array $arguments
*/
public function emit($scope, $method, array $arguments = []) {
- parent::emit($scope, $method, $arguments);
if (!is_null($this->dispatcher)) {
$this->dispatcher->dispatch("$scope::$method",
new GenericEvent("$scope::$method", $arguments));
@@ -206,15 +203,16 @@ class Repair extends BasicEmitter implements IOutput{
*/
public function startProgress($max = 0) {
// for now just emit as we did in the past
- $this->emit('\OC\Repair', 'startProgress', [$max]);
+ $this->emit('\OC\Repair', 'startProgress', [$max, $this->currentStep]);
}
/**
* @param int $step
+ * @param string $description
*/
- public function advance($step = 1) {
+ public function advance($step = 1, $description = '') {
// for now just emit as we did in the past
- $this->emit('\OC\Repair', 'advance', [$step]);
+ $this->emit('\OC\Repair', 'advance', [$step, $description]);
}
/**
diff --git a/lib/private/Repair/DropOldTables.php b/lib/private/Repair/DropOldTables.php
index 15d5b9a3577..b9963b50775 100644
--- a/lib/private/Repair/DropOldTables.php
+++ b/lib/private/Repair/DropOldTables.php
@@ -55,12 +55,15 @@ class DropOldTables implements IRepairStep {
* @throws \Exception in case of failure
*/
public function run(IOutput $output) {
+ $tables = $this->oldDatabaseTables();
+ $output->startProgress(count($tables));
foreach ($this->oldDatabaseTables() as $tableName) {
if ($this->connection->tableExists($tableName)){
- $output->info(sprintf('Table %s has been deleted', $tableName));
$this->connection->dropTable($tableName);
}
+ $output->advance(1, "Drop old database table: $tableName");
}
+ $output->finishProgress();
}
/**
diff --git a/lib/private/repairexception.php b/lib/private/RepairException.php
index e244f2bb820..e244f2bb820 100644
--- a/lib/private/repairexception.php
+++ b/lib/private/RepairException.php
diff --git a/lib/private/Route/CachingRouter.php b/lib/private/Route/CachingRouter.php
index d6270dcf2c7..063d389e98b 100644
--- a/lib/private/Route/CachingRouter.php
+++ b/lib/private/Route/CachingRouter.php
@@ -50,8 +50,9 @@ class CachingRouter extends Router {
public function generate($name, $parameters = array(), $absolute = false) {
asort($parameters);
$key = $this->context->getHost() . '#' . $this->context->getBaseUrl() . $name . sha1(json_encode($parameters)) . intval($absolute);
- if ($this->cache->hasKey($key)) {
- return $this->cache->get($key);
+ $cachedKey = $this->cache->get($key);
+ if ($cachedKey) {
+ return $cachedKey;
} else {
$url = parent::generate($name, $parameters, $absolute);
$this->cache->set($key, $url, 3600);
diff --git a/lib/private/search.php b/lib/private/Search.php
index 7d1e2734195..7d1e2734195 100644
--- a/lib/private/search.php
+++ b/lib/private/Search.php
diff --git a/lib/private/Server.php b/lib/private/Server.php
index d37edc4f45f..0b7b8f9e403 100644
--- a/lib/private/Server.php
+++ b/lib/private/Server.php
@@ -5,6 +5,7 @@
* @author Bernhard Posselt <dev@bernhard-posselt.com>
* @author Bernhard Reiter <ockham@raz.or.at>
* @author Björn Schießle <schiessle@owncloud.com>
+ * @author Christoph Wurst <christoph@owncloud.com>
* @author Christopher Schäpers <kondou@ts.unde.re>
* @author Joas Schilling <nickvergessen@owncloud.com>
* @author Jörn Friedrich Dreyer <jfd@butonic.de>
@@ -47,6 +48,9 @@ use OC\Diagnostics\NullQueryLogger;
use OC\Diagnostics\QueryLogger;
use OC\Files\Config\UserMountCache;
use OC\Files\Config\UserMountCacheListener;
+use OC\Files\Mount\CacheMountProvider;
+use OC\Files\Mount\LocalHomeMountProvider;
+use OC\Files\Mount\ObjectHomeMountProvider;
use OC\Files\Node\HookConnector;
use OC\Files\Node\LazyRoot;
use OC\Files\Node\Root;
@@ -207,12 +211,31 @@ class Server extends ServerContainer implements IServerContainer {
});
return $groupManager;
});
+ $this->registerService('OC\Authentication\Token\DefaultTokenMapper', function (Server $c) {
+ $dbConnection = $c->getDatabaseConnection();
+ return new Authentication\Token\DefaultTokenMapper($dbConnection);
+ });
+ $this->registerService('OC\Authentication\Token\DefaultTokenProvider', function (Server $c) {
+ $mapper = $c->query('OC\Authentication\Token\DefaultTokenMapper');
+ $crypto = $c->getCrypto();
+ $config = $c->getConfig();
+ $logger = $c->getLogger();
+ $timeFactory = new TimeFactory();
+ return new \OC\Authentication\Token\DefaultTokenProvider($mapper, $crypto, $config, $logger, $timeFactory);
+ });
$this->registerService('UserSession', function (Server $c) {
$manager = $c->getUserManager();
-
$session = new \OC\Session\Memory('');
-
- $userSession = new \OC\User\Session($manager, $session);
+ $timeFactory = new TimeFactory();
+ // Token providers might require a working database. This code
+ // might however be called when ownCloud is not yet setup.
+ if (\OC::$server->getSystemConfig()->getValue('installed', false)) {
+ $defaultTokenProvider = $c->query('OC\Authentication\Token\DefaultTokenProvider');
+ } else {
+ $defaultTokenProvider = null;
+ }
+
+ $userSession = new \OC\User\Session($manager, $session, $timeFactory, $defaultTokenProvider);
$userSession->listen('\OC\User', 'preCreateUser', function ($uid, $password) {
\OC_Hook::emit('OC_User', 'pre_createUser', array('run' => true, 'uid' => $uid, 'password' => $password));
});
@@ -311,8 +334,12 @@ class Server extends ServerContainer implements IServerContainer {
'\\OC\\Memcache\\ArrayCache'
);
});
+ $this->registerService('RedisFactory', function (Server $c) {
+ $systemConfig = $c->getSystemConfig();
+ return new RedisFactory($systemConfig);
+ });
$this->registerService('ActivityManager', function (Server $c) {
- return new ActivityManager(
+ return new \OC\Activity\Manager(
$c->getRequest(),
$c->getUserSession(),
$c->getConfig()
@@ -328,14 +355,18 @@ class Server extends ServerContainer implements IServerContainer {
});
$this->registerService('Logger', function (Server $c) {
$logClass = $c->query('AllConfig')->getSystemValue('log_type', 'owncloud');
- $logger = 'OC_Log_' . ucfirst($logClass);
+ $logger = 'OC\\Log\\' . ucfirst($logClass);
call_user_func(array($logger, 'init'));
return new Log($logger);
});
$this->registerService('JobList', function (Server $c) {
$config = $c->getConfig();
- return new \OC\BackgroundJob\JobList($c->getDatabaseConnection(), $config);
+ return new \OC\BackgroundJob\JobList(
+ $c->getDatabaseConnection(),
+ $config,
+ new TimeFactory()
+ );
});
$this->registerService('Router', function (Server $c) {
$cacheFactory = $c->getMemCacheFactory();
@@ -444,7 +475,16 @@ class Server extends ServerContainer implements IServerContainer {
$this->registerService('MountConfigManager', function (Server $c) {
$loader = \OC\Files\Filesystem::getLoader();
$mountCache = $c->query('UserMountCache');
- return new \OC\Files\Config\MountProviderCollection($loader, $mountCache);
+ $manager = new \OC\Files\Config\MountProviderCollection($loader, $mountCache);
+
+ // builtin providers
+
+ $config = $c->getConfig();
+ $manager->registerProvider(new CacheMountProvider($config));
+ $manager->registerHomeProvider(new LocalHomeMountProvider());
+ $manager->registerHomeProvider(new ObjectHomeMountProvider($config));
+
+ return $manager;
});
$this->registerService('IniWrapper', function ($c) {
return new IniGetWrapper();
@@ -615,7 +655,7 @@ class Server extends ServerContainer implements IServerContainer {
$this->registerService('ShareManager', function(Server $c) {
$config = $c->getConfig();
$factoryClass = $config->getSystemValue('sharing.managerFactory', '\OC\Share20\ProviderFactory');
- /** @var \OC\Share20\IProviderFactory $factory */
+ /** @var \OCP\Share\IProviderFactory $factory */
$factory = new $factoryClass($this);
$manager = new \OC\Share20\Manager(
@@ -829,8 +869,7 @@ class Server extends ServerContainer implements IServerContainer {
}
/**
- * For internal use only
- *
+ * @internal For internal use only
* @return \OC\SystemConfig
*/
public function getSystemConfig() {
@@ -899,6 +938,16 @@ class Server extends ServerContainer implements IServerContainer {
}
/**
+ * Returns an \OC\RedisFactory instance
+ *
+ * @return \OC\RedisFactory
+ */
+ public function getGetRedisFactory() {
+ return $this->query('RedisFactory');
+ }
+
+
+ /**
* Returns the current session
*
* @return \OCP\IDBConnection
@@ -1172,7 +1221,7 @@ class Server extends ServerContainer implements IServerContainer {
return $this->query('MountManager');
}
- /*
+ /**
* Get the MimeTypeDetector
*
* @return \OCP\Files\IMimeTypeDetector
diff --git a/lib/private/servercontainer.php b/lib/private/ServerContainer.php
index d297c9fd39c..d297c9fd39c 100644
--- a/lib/private/servercontainer.php
+++ b/lib/private/ServerContainer.php
diff --git a/lib/private/servernotavailableexception.php b/lib/private/ServerNotAvailableException.php
index f4b5f4f8cf3..f4b5f4f8cf3 100644
--- a/lib/private/servernotavailableexception.php
+++ b/lib/private/ServerNotAvailableException.php
diff --git a/lib/private/serviceunavailableexception.php b/lib/private/ServiceUnavailableException.php
index fb4920b3607..fb4920b3607 100644
--- a/lib/private/serviceunavailableexception.php
+++ b/lib/private/ServiceUnavailableException.php
diff --git a/lib/private/Session/CryptoSessionData.php b/lib/private/Session/CryptoSessionData.php
index f6c585c1611..629e6af5412 100644
--- a/lib/private/Session/CryptoSessionData.php
+++ b/lib/private/Session/CryptoSessionData.php
@@ -24,6 +24,7 @@ namespace OC\Session;
use OCP\ISession;
use OCP\Security\ICrypto;
+use OCP\Session\Exceptions\SessionNotAvailableException;
/**
* Class CryptoSessionData
@@ -142,6 +143,17 @@ class CryptoSessionData implements \ArrayAccess, ISession {
}
/**
+ * Wrapper around session_id
+ *
+ * @return string
+ * @throws SessionNotAvailableException
+ * @since 9.1.0
+ */
+ public function getId() {
+ return $this->session->getId();
+ }
+
+ /**
* Close the session and release the lock, also writes all changed data in batch
*/
public function close() {
diff --git a/lib/private/Session/Internal.php b/lib/private/Session/Internal.php
index 09175bf1f2f..a24aec55222 100644
--- a/lib/private/Session/Internal.php
+++ b/lib/private/Session/Internal.php
@@ -26,6 +26,8 @@
namespace OC\Session;
+use OCP\Session\Exceptions\SessionNotAvailableException;
+
/**
* Class Internal
*
@@ -112,6 +114,21 @@ class Internal extends Session {
}
/**
+ * Wrapper around session_id
+ *
+ * @return string
+ * @throws SessionNotAvailableException
+ * @since 9.1.0
+ */
+ public function getId() {
+ $id = @session_id();
+ if ($id === '') {
+ throw new SessionNotAvailableException();
+ }
+ return $id;
+ }
+
+ /**
* @throws \Exception
*/
public function reopen() {
diff --git a/lib/private/Session/Memory.php b/lib/private/Session/Memory.php
index 777458a9aa5..bcb1f1d950c 100644
--- a/lib/private/Session/Memory.php
+++ b/lib/private/Session/Memory.php
@@ -26,6 +26,9 @@
namespace OC\Session;
+use Exception;
+use OCP\Session\Exceptions\SessionNotAvailableException;
+
/**
* Class Internal
*
@@ -89,6 +92,17 @@ class Memory extends Session {
public function regenerateId($deleteOldSession = true) {}
/**
+ * Wrapper around session_id
+ *
+ * @return string
+ * @throws SessionNotAvailableException
+ * @since 9.1.0
+ */
+ public function getId() {
+ throw new SessionNotAvailableException('Memory session does not have an ID');
+ }
+
+ /**
* Helper function for PHPUnit execution - don't use in non-test code
*/
public function reopen() {
@@ -98,11 +112,11 @@ class Memory extends Session {
/**
* In case the session has already been locked an exception will be thrown
*
- * @throws \Exception
+ * @throws Exception
*/
private function validateSession() {
if ($this->sessionClosed) {
- throw new \Exception('Session has been closed - no further changes to the session are allowed');
+ throw new Exception('Session has been closed - no further changes to the session are allowed');
}
}
}
diff --git a/lib/private/setup.php b/lib/private/Setup.php
index 196ae8a8bce..d60c4663fb0 100644
--- a/lib/private/setup.php
+++ b/lib/private/Setup.php
@@ -364,10 +364,17 @@ class Setup {
$group =\OC::$server->getGroupManager()->createGroup('admin');
$group->addUser($user);
- \OC_User::login($username, $password);
+
+ // Create a session token for the newly created user
+ // The token provider requires a working db, so it's not injected on setup
+ /* @var $userSession User\Session */
+ $userSession = \OC::$server->getUserSession();
+ $defaultTokenProvider = \OC::$server->query('OC\Authentication\Token\DefaultTokenProvider');
+ $userSession->setTokenProvider($defaultTokenProvider);
+ $userSession->createSessionToken($request, $username, $password);
//guess what this does
- \OC_Installer::installShippedApps();
+ Installer::installShippedApps();
// create empty file in data dir, so we can later find
// out that this is indeed an ownCloud data directory
@@ -382,6 +389,8 @@ class Setup {
$config->setSystemValue('logtimezone', date_default_timezone_get());
}
+ self::installBackgroundJobs();
+
//and we are done
$config->setSystemValue('installed', true);
}
@@ -389,6 +398,10 @@ class Setup {
return $error;
}
+ public static function installBackgroundJobs() {
+ \OC::$server->getJobList()->add('\OC\Authentication\Token\DefaultTokenCleanupJob');
+ }
+
/**
* @return string Absolute path to htaccess
*/
@@ -420,37 +433,47 @@ class Setup {
$htaccessContent = file_get_contents($setupHelper->pathToHtaccess());
$content = "#### DO NOT CHANGE ANYTHING ABOVE THIS LINE ####\n";
- if(strpos($htaccessContent, $content) === false) {
- //custom 403 error page
- $content.= "\nErrorDocument 403 ".$webRoot."/core/templates/403.php";
+ $htaccessContent = explode($content, $htaccessContent, 2)[0];
- //custom 404 error page
- $content.= "\nErrorDocument 404 ".$webRoot."/core/templates/404.php";
+ //custom 403 error page
+ $content.= "\nErrorDocument 403 ".$webRoot."/core/templates/403.php";
- // ownCloud may be configured to live at the root folder without a
- // trailing slash being specified. In this case manually set the
- // rewrite base to `/`
- $rewriteBase = $webRoot;
- if($webRoot === '') {
- $rewriteBase = '/';
- }
+ //custom 404 error page
+ $content.= "\nErrorDocument 404 ".$webRoot."/core/templates/404.php";
- // Add rewrite base
+ // Add rewrite rules if the RewriteBase is configured
+ $rewriteBase = $config->getSystemValue('htaccess.RewriteBase', '');
+ if($rewriteBase !== '') {
$content .= "\n<IfModule mod_rewrite.c>";
+ $content .= "\n Options -MultiViews";
+ $content .= "\n RewriteRule ^core/js/oc.js$ index.php [PT,E=PATH_INFO:$1]";
+ $content .= "\n RewriteRule ^core/preview.png$ index.php [PT,E=PATH_INFO:$1]";
+ $content .= "\n RewriteCond %{REQUEST_FILENAME} !\\.(css|js|svg|gif|png|html|ttf|woff|ico|jpg|jpeg)$";
+ $content .= "\n RewriteCond %{REQUEST_FILENAME} !core/img/favicon.ico$";
+ $content .= "\n RewriteCond %{REQUEST_FILENAME} !/remote.php";
+ $content .= "\n RewriteCond %{REQUEST_FILENAME} !/public.php";
+ $content .= "\n RewriteCond %{REQUEST_FILENAME} !/cron.php";
+ $content .= "\n RewriteCond %{REQUEST_FILENAME} !/core/ajax/update.php";
+ $content .= "\n RewriteCond %{REQUEST_FILENAME} !/status.php";
+ $content .= "\n RewriteCond %{REQUEST_FILENAME} !/ocs/v1.php";
+ $content .= "\n RewriteCond %{REQUEST_FILENAME} !/ocs/v2.php";
+ $content .= "\n RewriteCond %{REQUEST_FILENAME} !/updater/";
+ $content .= "\n RewriteCond %{REQUEST_FILENAME} !/ocs-provider/";
+ $content .= "\n RewriteCond %{REQUEST_URI} !^/.well-known/acme-challenge/.*";
$content .= "\n RewriteRule . index.php [PT,E=PATH_INFO:$1]";
- $content .= "\n RewriteBase ".$rewriteBase;
+ $content .= "\n RewriteBase " . $rewriteBase;
$content .= "\n <IfModule mod_env.c>";
$content .= "\n SetEnv front_controller_active true";
$content .= "\n <IfModule mod_dir.c>";
$content .= "\n DirectorySlash off";
$content .= "\n </IfModule>";
- $content.="\n </IfModule>";
- $content.="\n</IfModule>";
+ $content .= "\n </IfModule>";
+ $content .= "\n</IfModule>";
+ }
- if ($content !== '') {
- //suppress errors in case we don't have permissions for it
- @file_put_contents($setupHelper->pathToHtaccess(), $content . "\n", FILE_APPEND);
- }
+ if ($content !== '') {
+ //suppress errors in case we don't have permissions for it
+ @file_put_contents($setupHelper->pathToHtaccess(), $htaccessContent.$content . "\n");
}
}
diff --git a/lib/private/share/constants.php b/lib/private/Share/Constants.php
index e60eb98832b..e60eb98832b 100644
--- a/lib/private/share/constants.php
+++ b/lib/private/Share/Constants.php
diff --git a/lib/private/share/helper.php b/lib/private/Share/Helper.php
index f9581e48e62..f9581e48e62 100644
--- a/lib/private/share/helper.php
+++ b/lib/private/Share/Helper.php
diff --git a/lib/private/share/mailnotifications.php b/lib/private/Share/MailNotifications.php
index f71651e71fc..afecff0b97b 100644
--- a/lib/private/share/mailnotifications.php
+++ b/lib/private/Share/MailNotifications.php
@@ -119,27 +119,9 @@ class MailNotifications {
}
}
- // Link to folder, or root folder if a file
-
- if ($itemType === 'folder') {
- $args = array(
- 'dir' => $filename,
- );
- } else if (strpos($filename, '/')) {
- $args = array(
- 'dir' => '/' . dirname($filename),
- 'scrollto' => basename($filename),
- );
- } else {
- $args = array(
- 'dir' => '/',
- 'scrollto' => $filename,
- );
- }
-
$link = $this->urlGenerator->linkToRouteAbsolute(
- 'files.view.index',
- $args
+ 'files.viewcontroller.showFile',
+ ['fileId' => $items[0]['item_source']]
);
list($htmlBody, $textBody) = $this->createMailBody($filename, $link, $expiration, 'internal');
diff --git a/lib/private/share/searchresultsorter.php b/lib/private/Share/SearchResultSorter.php
index 6d5542146e7..6d5542146e7 100644
--- a/lib/private/share/searchresultsorter.php
+++ b/lib/private/Share/SearchResultSorter.php
diff --git a/lib/private/share/share.php b/lib/private/Share/Share.php
index 5b61f418a4d..5b61f418a4d 100644
--- a/lib/private/share/share.php
+++ b/lib/private/Share/Share.php
diff --git a/lib/private/streamer.php b/lib/private/Streamer.php
index 23c191b68da..23c191b68da 100644
--- a/lib/private/streamer.php
+++ b/lib/private/Streamer.php
diff --git a/lib/private/subadmin.php b/lib/private/SubAdmin.php
index 34dd40c22ff..34dd40c22ff 100644
--- a/lib/private/subadmin.php
+++ b/lib/private/SubAdmin.php
diff --git a/lib/private/systemconfig.php b/lib/private/SystemConfig.php
index 449a2dc50b2..449a2dc50b2 100644
--- a/lib/private/systemconfig.php
+++ b/lib/private/SystemConfig.php
diff --git a/lib/private/SystemTag/ManagerFactory.php b/lib/private/SystemTag/ManagerFactory.php
index d9acf327f8a..6b238e3c428 100644
--- a/lib/private/SystemTag/ManagerFactory.php
+++ b/lib/private/SystemTag/ManagerFactory.php
@@ -59,6 +59,7 @@ class ManagerFactory implements ISystemTagManagerFactory {
public function getManager() {
return new SystemTagManager(
$this->serverContainer->getDatabaseConnection(),
+ $this->serverContainer->getGroupManager(),
$this->serverContainer->getEventDispatcher()
);
}
diff --git a/lib/private/SystemTag/SystemTagManager.php b/lib/private/SystemTag/SystemTagManager.php
index 76a60a91328..2b0ef03e471 100644
--- a/lib/private/SystemTag/SystemTagManager.php
+++ b/lib/private/SystemTag/SystemTagManager.php
@@ -30,10 +30,18 @@ use OCP\SystemTag\ManagerEvent;
use OCP\SystemTag\TagAlreadyExistsException;
use OCP\SystemTag\TagNotFoundException;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
+use OCP\IUserManager;
+use OCP\IGroupManager;
+use OCP\SystemTag\ISystemTag;
+use OCP\IUser;
+/**
+ * Manager class for system tags
+ */
class SystemTagManager implements ISystemTagManager {
const TAG_TABLE = 'systemtag';
+ const TAG_GROUP_TABLE = 'systemtag_group';
/** @var IDBConnection */
protected $connection;
@@ -41,6 +49,9 @@ class SystemTagManager implements ISystemTagManager {
/** @var EventDispatcherInterface */
protected $dispatcher;
+ /** @var IGroupManager */
+ protected $groupManager;
+
/**
* Prepared query for selecting tags directly
*
@@ -54,8 +65,13 @@ class SystemTagManager implements ISystemTagManager {
* @param IDBConnection $connection database connection
* @param EventDispatcherInterface $dispatcher
*/
- public function __construct(IDBConnection $connection, EventDispatcherInterface $dispatcher) {
+ public function __construct(
+ IDBConnection $connection,
+ IGroupManager $groupManager,
+ EventDispatcherInterface $dispatcher
+ ) {
$this->connection = $connection;
+ $this->groupManager = $groupManager;
$this->dispatcher = $dispatcher;
$query = $this->connection->getQueryBuilder();
@@ -316,7 +332,102 @@ class SystemTagManager implements ISystemTagManager {
}
}
+ /**
+ * {@inheritdoc}
+ */
+ public function canUserAssignTag(ISystemTag $tag, IUser $user) {
+ // early check to avoid unneeded group lookups
+ if ($tag->isUserAssignable() && $tag->isUserVisible()) {
+ return true;
+ }
+
+ if ($this->groupManager->isAdmin($user->getUID())) {
+ return true;
+ }
+
+ if (!$tag->isUserVisible()) {
+ return false;
+ }
+
+ $groupIds = $this->groupManager->getUserGroupIds($user);
+ if (!empty($groupIds)) {
+ $matchingGroups = array_intersect($groupIds, $this->getTagGroups($tag));
+ if (!empty($matchingGroups)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function canUserSeeTag(ISystemTag $tag, IUser $user) {
+ if ($tag->isUserVisible()) {
+ return true;
+ }
+
+ if ($this->groupManager->isAdmin($user->getUID())) {
+ return true;
+ }
+
+ return false;
+ }
+
private function createSystemTagFromRow($row) {
return new SystemTag((int)$row['id'], $row['name'], (bool)$row['visibility'], (bool)$row['editable']);
}
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setTagGroups(ISystemTag $tag, $groupIds) {
+ // delete relationships first
+ $this->connection->beginTransaction();
+ try {
+ $query = $this->connection->getQueryBuilder();
+ $query->delete(self::TAG_GROUP_TABLE)
+ ->where($query->expr()->eq('systemtagid', $query->createNamedParameter($tag->getId())))
+ ->execute();
+
+ // add each group id
+ $query = $this->connection->getQueryBuilder();
+ $query->insert(self::TAG_GROUP_TABLE)
+ ->values([
+ 'systemtagid' => $query->createNamedParameter($tag->getId()),
+ 'gid' => $query->createParameter('gid'),
+ ]);
+ foreach ($groupIds as $groupId) {
+ $query->setParameter('gid', $groupId);
+ $query->execute();
+ }
+
+ $this->connection->commit();
+ } catch (\Exception $e) {
+ $this->connection->rollback();
+ throw $e;
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getTagGroups(ISystemTag $tag) {
+ $groupIds = [];
+ $query = $this->connection->getQueryBuilder();
+ $query->select('gid')
+ ->from(self::TAG_GROUP_TABLE)
+ ->where($query->expr()->eq('systemtagid', $query->createNamedParameter($tag->getId())))
+ ->orderBy('gid');
+
+ $result = $query->execute();
+ while ($row = $result->fetch()) {
+ $groupIds[] = $row['gid'];
+ }
+
+ $result->closeCursor();
+
+ return $groupIds;
+ }
}
diff --git a/lib/private/tagmanager.php b/lib/private/TagManager.php
index a9e1cdfe076..a9e1cdfe076 100644
--- a/lib/private/tagmanager.php
+++ b/lib/private/TagManager.php
diff --git a/lib/private/tags.php b/lib/private/Tags.php
index cf39a9a9759..cf39a9a9759 100644
--- a/lib/private/tags.php
+++ b/lib/private/Tags.php
diff --git a/lib/private/tempmanager.php b/lib/private/TempManager.php
index dd97a36cd7f..dd97a36cd7f 100644
--- a/lib/private/tempmanager.php
+++ b/lib/private/TempManager.php
diff --git a/lib/private/template/base.php b/lib/private/Template/Base.php
index cfe629b5fbf..cfe629b5fbf 100644
--- a/lib/private/template/base.php
+++ b/lib/private/Template/Base.php
diff --git a/lib/private/template/cssresourcelocator.php b/lib/private/Template/CSSResourceLocator.php
index 6a547931ee3..6a547931ee3 100644
--- a/lib/private/template/cssresourcelocator.php
+++ b/lib/private/Template/CSSResourceLocator.php
diff --git a/lib/private/template/jsresourcelocator.php b/lib/private/Template/JSResourceLocator.php
index 6ea7b6291c0..6ea7b6291c0 100644
--- a/lib/private/template/jsresourcelocator.php
+++ b/lib/private/Template/JSResourceLocator.php
diff --git a/lib/private/template/resourcelocator.php b/lib/private/Template/ResourceLocator.php
index e64fce81afc..e64fce81afc 100644
--- a/lib/private/template/resourcelocator.php
+++ b/lib/private/Template/ResourceLocator.php
diff --git a/lib/private/template/resourcenotfoundexception.php b/lib/private/Template/ResourceNotFoundException.php
index 8c7f1f14175..8c7f1f14175 100644
--- a/lib/private/template/resourcenotfoundexception.php
+++ b/lib/private/Template/ResourceNotFoundException.php
diff --git a/lib/private/template/templatefilelocator.php b/lib/private/Template/TemplateFileLocator.php
index f8553156914..f8553156914 100644
--- a/lib/private/template/templatefilelocator.php
+++ b/lib/private/Template/TemplateFileLocator.php
diff --git a/lib/private/templatelayout.php b/lib/private/TemplateLayout.php
index 88077b418a7..88077b418a7 100644
--- a/lib/private/templatelayout.php
+++ b/lib/private/TemplateLayout.php
diff --git a/lib/private/urlgenerator.php b/lib/private/URLGenerator.php
index 327c0c32dfe..327c0c32dfe 100644
--- a/lib/private/urlgenerator.php
+++ b/lib/private/URLGenerator.php
diff --git a/lib/private/updater.php b/lib/private/Updater.php
index 66f410b779f..dbcaccaad26 100644
--- a/lib/private/updater.php
+++ b/lib/private/Updater.php
@@ -36,7 +36,6 @@ namespace OC;
use OC\Hooks\BasicEmitter;
use OC\IntegrityCheck\Checker;
use OC_App;
-use OC_Installer;
use OCP\IConfig;
use OC\Setup;
use OCP\ILogger;
@@ -132,6 +131,8 @@ class Updater extends BasicEmitter {
* @return bool true if the operation succeeded, false otherwise
*/
public function upgrade() {
+ $this->emitRepairEvents();
+
$logLevel = $this->config->getSystemValue('loglevel', \OCP\Util::WARN);
$this->emit('\OC\Updater', 'setDebugLogLevel', [ $logLevel, $this->logLevelNames[$logLevel] ]);
$this->config->setSystemValue('loglevel', \OCP\Util::DEBUG);
@@ -196,26 +197,6 @@ class Updater extends BasicEmitter {
}
/**
- * Forward messages emitted by the repair routine
- *
- * @param Repair $repair repair routine
- */
- private function emitRepairMessages(Repair $repair) {
- $repair->listen('\OC\Repair', 'warning', function ($description) {
- $this->emit('\OC\Updater', 'repairWarning', array($description));
- });
- $repair->listen('\OC\Repair', 'error', function ($description) {
- $this->emit('\OC\Updater', 'repairError', array($description));
- });
- $repair->listen('\OC\Repair', 'info', function ($description) {
- $this->emit('\OC\Updater', 'repairInfo', array($description));
- });
- $repair->listen('\OC\Repair', 'step', function ($description) {
- $this->emit('\OC\Updater', 'repairStep', array($description));
- });
- }
-
- /**
* runs the update actions in maintenance mode, does not upgrade the source files
* except the main .htaccess file
*
@@ -235,6 +216,8 @@ class Updater extends BasicEmitter {
try {
Setup::updateHtaccess();
Setup::protectDataDirectory();
+ // TODO: replace with the new repair step mechanism https://github.com/owncloud/core/pull/24378
+ Setup::installBackgroundJobs();
} catch (\Exception $e) {
throw new \Exception($e->getMessage());
}
@@ -245,8 +228,7 @@ class Updater extends BasicEmitter {
file_put_contents($this->config->getSystemValue('datadirectory', \OC::$SERVERROOT . '/data') . '/.ocdata', '');
// pre-upgrade repairs
- $repair = new Repair(Repair::getBeforeUpgradeRepairSteps());
- $this->emitRepairMessages($repair);
+ $repair = new Repair(Repair::getBeforeUpgradeRepairSteps(), \OC::$server->getEventDispatcher());
$repair->run();
// simulate DB upgrade
@@ -270,7 +252,7 @@ class Updater extends BasicEmitter {
// install new shipped apps on upgrade
OC_App::loadApps('authentication');
- $errors = OC_Installer::installShippedApps(true);
+ $errors = Installer::installShippedApps(true);
foreach ($errors as $appId => $exception) {
/** @var \Exception $exception */
$this->log->logException($exception, ['app' => $appId]);
@@ -278,8 +260,7 @@ class Updater extends BasicEmitter {
}
// post-upgrade repairs
- $repair = new Repair(Repair::getRepairSteps());
- $this->emitRepairMessages($repair);
+ $repair = new Repair(Repair::getRepairSteps(), \OC::$server->getEventDispatcher());
$repair->run();
//Invalidate update feed
@@ -362,7 +343,6 @@ class Updater extends BasicEmitter {
* @throws NeedsUpdateException
*/
protected function doAppUpgrade() {
- $this->emitRepairEvents();
$apps = \OC_App::getEnabledApps();
$priorityTypes = array('authentication', 'filesystem', 'logging');
$pseudoOtherType = 'other';
@@ -464,11 +444,11 @@ class Updater extends BasicEmitter {
private function upgradeAppStoreApps(array $disabledApps) {
foreach($disabledApps as $app) {
try {
- if (OC_Installer::isUpdateAvailable($app)) {
+ if (Installer::isUpdateAvailable($app)) {
$ocsId = \OC::$server->getConfig()->getAppValue($app, 'ocsid', '');
$this->emit('\OC\Updater', 'upgradeAppStoreApp', array($app));
- OC_Installer::updateAppByOCSId($ocsId);
+ Installer::updateAppByOCSId($ocsId);
}
} catch (\Exception $ex) {
$this->log->logException($ex, ['app' => 'core']);
diff --git a/lib/private/Updater/VersionCheck.php b/lib/private/Updater/VersionCheck.php
index e42a1e2a40c..7b330b53686 100644
--- a/lib/private/Updater/VersionCheck.php
+++ b/lib/private/Updater/VersionCheck.php
@@ -61,19 +61,15 @@ class VersionCheck {
/**
* Check if a new version is available
*
- * @param string $updaterUrl the url to check, i.e. 'http://apps.owncloud.com/updater.php'
* @return array|bool
*/
- public function check($updaterUrl = null) {
-
+ public function check() {
// Look up the cache - it is invalidated all 30 minutes
if (((int)$this->config->getAppValue('core', 'lastupdatedat') + 1800) > time()) {
return json_decode($this->config->getAppValue('core', 'lastupdateResult'), true);
}
- if (is_null($updaterUrl)) {
- $updaterUrl = 'https://updates.owncloud.com/server/';
- }
+ $updaterUrl = $this->config->getSystemValue('updater.server.url', 'https://updates.owncloud.com/server/');
$this->config->setAppValue('core', 'lastupdatedat', time());
diff --git a/lib/private/user/backend.php b/lib/private/User/Backend.php
index 2bb1df4d6b3..d5f82dc9621 100644
--- a/lib/private/user/backend.php
+++ b/lib/private/User/Backend.php
@@ -32,37 +32,13 @@
*
*/
-/**
- * error code for functions not provided by the user backend
- * @deprecated Use \OC_User_Backend::NOT_IMPLEMENTED instead
- */
-define('OC_USER_BACKEND_NOT_IMPLEMENTED', -501);
-
-/**
- * actions that user backends can define
- */
-/** @deprecated Use \OC_User_Backend::CREATE_USER instead */
-define('OC_USER_BACKEND_CREATE_USER', 1 << 0);
-/** @deprecated Use \OC_User_Backend::SET_PASSWORD instead */
-define('OC_USER_BACKEND_SET_PASSWORD', 1 << 4);
-/** @deprecated Use \OC_User_Backend::CHECK_PASSWORD instead */
-define('OC_USER_BACKEND_CHECK_PASSWORD', 1 << 8);
-/** @deprecated Use \OC_User_Backend::GET_HOME instead */
-define('OC_USER_BACKEND_GET_HOME', 1 << 12);
-/** @deprecated Use \OC_User_Backend::GET_DISPLAYNAME instead */
-define('OC_USER_BACKEND_GET_DISPLAYNAME', 1 << 16);
-/** @deprecated Use \OC_User_Backend::SET_DISPLAYNAME instead */
-define('OC_USER_BACKEND_SET_DISPLAYNAME', 1 << 20);
-/** @deprecated Use \OC_User_Backend::PROVIDE_AVATAR instead */
-define('OC_USER_BACKEND_PROVIDE_AVATAR', 1 << 24);
-/** @deprecated Use \OC_User_Backend::COUNT_USERS instead */
-define('OC_USER_BACKEND_COUNT_USERS', 1 << 28);
+namespace OC\User;
/**
* Abstract base class for user management. Provides methods for querying backend
* capabilities.
*/
-abstract class OC_User_Backend implements \OCP\UserInterface {
+abstract class Backend implements \OCP\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 22a05090b96..7a4b58e6f40 100644
--- a/lib/private/user/database.php
+++ b/lib/private/User/Database.php
@@ -48,11 +48,23 @@
*
*/
+namespace OC\User;
+
+use OC\Cache\CappedMemoryCache;
+
/**
* Class for user management in a SQL Database (e.g. MySQL, SQLite)
*/
-class OC_User_Database extends OC_User_Backend implements \OCP\IUserBackend {
- private $cache = array();
+class Database extends \OC\User\Backend implements \OCP\IUserBackend {
+ /** @var CappedMemoryCache */
+ private $cache;
+
+ /**
+ * OC_User_Database constructor.
+ */
+ public function __construct() {
+ $this->cache = new CappedMemoryCache();
+ }
/**
* Create a new user
@@ -65,7 +77,7 @@ class OC_User_Database extends OC_User_Backend implements \OCP\IUserBackend {
*/
public function createUser($uid, $password) {
if (!$this->userExists($uid)) {
- $query = OC_DB::prepare('INSERT INTO `*PREFIX*users` ( `uid`, `password` ) VALUES( ?, ? )');
+ $query = \OC_DB::prepare('INSERT INTO `*PREFIX*users` ( `uid`, `password` ) VALUES( ?, ? )');
$result = $query->execute(array($uid, \OC::$server->getHasher()->hash($password)));
return $result ? true : false;
@@ -83,7 +95,7 @@ class OC_User_Database extends OC_User_Backend implements \OCP\IUserBackend {
*/
public function deleteUser($uid) {
// Delete user-group-relation
- $query = OC_DB::prepare('DELETE FROM `*PREFIX*users` WHERE `uid` = ?');
+ $query = \OC_DB::prepare('DELETE FROM `*PREFIX*users` WHERE `uid` = ?');
$result = $query->execute(array($uid));
if (isset($this->cache[$uid])) {
@@ -103,7 +115,7 @@ class OC_User_Database extends OC_User_Backend implements \OCP\IUserBackend {
*/
public function setPassword($uid, $password) {
if ($this->userExists($uid)) {
- $query = OC_DB::prepare('UPDATE `*PREFIX*users` SET `password` = ? WHERE `uid` = ?');
+ $query = \OC_DB::prepare('UPDATE `*PREFIX*users` SET `password` = ? WHERE `uid` = ?');
$result = $query->execute(array(\OC::$server->getHasher()->hash($password), $uid));
return $result ? true : false;
@@ -122,7 +134,7 @@ class OC_User_Database extends OC_User_Backend implements \OCP\IUserBackend {
*/
public function setDisplayName($uid, $displayName) {
if ($this->userExists($uid)) {
- $query = OC_DB::prepare('UPDATE `*PREFIX*users` SET `displayname` = ? WHERE LOWER(`uid`) = LOWER(?)');
+ $query = \OC_DB::prepare('UPDATE `*PREFIX*users` SET `displayname` = ? WHERE LOWER(`uid`) = LOWER(?)');
$query->execute(array($displayName, $uid));
$this->cache[$uid]['displayname'] = $displayName;
@@ -161,7 +173,7 @@ class OC_User_Database extends OC_User_Backend implements \OCP\IUserBackend {
}
$displayNames = array();
- $query = OC_DB::prepare('SELECT `uid`, `displayname` FROM `*PREFIX*users`'
+ $query = \OC_DB::prepare('SELECT `uid`, `displayname` FROM `*PREFIX*users`'
. $searchLike .' ORDER BY `uid` ASC', $limit, $offset);
$result = $query->execute($parameters);
while ($row = $result->fetchRow()) {
@@ -181,7 +193,7 @@ class OC_User_Database extends OC_User_Backend implements \OCP\IUserBackend {
* returns the user id or false
*/
public function checkPassword($uid, $password) {
- $query = OC_DB::prepare('SELECT `uid`, `password` FROM `*PREFIX*users` WHERE LOWER(`uid`) = LOWER(?)');
+ $query = \OC_DB::prepare('SELECT `uid`, `password` FROM `*PREFIX*users` WHERE LOWER(`uid`) = LOWER(?)');
$result = $query->execute(array($uid));
$row = $result->fetchRow();
@@ -207,11 +219,11 @@ class OC_User_Database extends OC_User_Backend implements \OCP\IUserBackend {
*/
private function loadUser($uid) {
if (empty($this->cache[$uid])) {
- $query = OC_DB::prepare('SELECT `uid`, `displayname` FROM `*PREFIX*users` WHERE LOWER(`uid`) = LOWER(?)');
+ $query = \OC_DB::prepare('SELECT `uid`, `displayname` FROM `*PREFIX*users` WHERE LOWER(`uid`) = LOWER(?)');
$result = $query->execute(array($uid));
if ($result === false) {
- \OCP\Util::writeLog('core', OC_DB::getErrorMessage(), \OCP\Util::ERROR);
+ \OCP\Util::writeLog('core', \OC_DB::getErrorMessage(), \OCP\Util::ERROR);
return false;
}
@@ -240,7 +252,7 @@ class OC_User_Database extends OC_User_Backend implements \OCP\IUserBackend {
$searchLike = ' WHERE LOWER(`uid`) LIKE LOWER(?)';
}
- $query = OC_DB::prepare('SELECT `uid` FROM `*PREFIX*users`' . $searchLike . ' ORDER BY `uid` ASC', $limit, $offset);
+ $query = \OC_DB::prepare('SELECT `uid` FROM `*PREFIX*users`' . $searchLike . ' ORDER BY `uid` ASC', $limit, $offset);
$result = $query->execute($parameters);
$users = array();
while ($row = $result->fetchRow()) {
@@ -266,7 +278,7 @@ class OC_User_Database extends OC_User_Backend implements \OCP\IUserBackend {
*/
public function getHome($uid) {
if ($this->userExists($uid)) {
- return \OC::$server->getConfig()->getSystemValue("datadirectory", OC::$SERVERROOT . "/data") . '/' . $uid;
+ return \OC::$server->getConfig()->getSystemValue("datadirectory", \OC::$SERVERROOT . "/data") . '/' . $uid;
}
return false;
@@ -285,10 +297,10 @@ class OC_User_Database extends OC_User_Backend implements \OCP\IUserBackend {
* @return int|bool
*/
public function countUsers() {
- $query = OC_DB::prepare('SELECT COUNT(*) FROM `*PREFIX*users`');
+ $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);
+ \OCP\Util::writeLog('core', \OC_DB::getErrorMessage(), \OCP\Util::ERROR);
return false;
}
return $result->fetchOne();
@@ -323,8 +335,8 @@ class OC_User_Database extends OC_User_Backend implements \OCP\IUserBackend {
$backends = \OC::$server->getUserManager()->getBackends();
foreach ($backends as $backend) {
- if ($backend instanceof \OC_User_Database) {
- /** @var \OC_User_Database $backend */
+ if ($backend instanceof \OC\User\Database) {
+ /** @var \OC\User\Database $backend */
$uid = $backend->loginName2UserName($param['uid']);
if ($uid !== false) {
$param['uid'] = $uid;
diff --git a/lib/private/user/loginexception.php b/lib/private/User/LoginException.php
index 84426f7f5da..84426f7f5da 100644
--- a/lib/private/user/loginexception.php
+++ b/lib/private/User/LoginException.php
diff --git a/lib/private/user/manager.php b/lib/private/User/Manager.php
index 7967f877024..a9d9425e24d 100644
--- a/lib/private/user/manager.php
+++ b/lib/private/User/Manager.php
@@ -33,6 +33,7 @@
namespace OC\User;
use OC\Hooks\PublicEmitter;
+use OCP\IUser;
use OCP\IUserBackend;
use OCP\IUserManager;
use OCP\IConfig;
@@ -147,14 +148,19 @@ class Manager extends PublicEmitter implements IUserManager {
*
* @param string $uid
* @param \OCP\UserInterface $backend
+ * @param bool $cacheUser If false the newly created user object will not be cached
* @return \OC\User\User
*/
- protected function getUserObject($uid, $backend) {
+ protected function getUserObject($uid, $backend, $cacheUser = true) {
if (isset($this->cachedUsers[$uid])) {
return $this->cachedUsers[$uid];
}
- $this->cachedUsers[$uid] = new User($uid, $backend, $this, $this->config);
- return $this->cachedUsers[$uid];
+
+ $user = new User($uid, $backend, $this, $this->config);
+ if ($cacheUser) {
+ $this->cachedUsers[$uid] = $user;
+ }
+ return $user;
}
/**
@@ -180,7 +186,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(\OC\User\Backend::CHECK_PASSWORD)) {
$uid = $backend->checkPassword($loginName, $password);
if ($uid !== false) {
return $this->getUserObject($uid, $backend);
@@ -284,7 +290,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(\OC\User\Backend::CREATE_USER)) {
$backend->createUser($uid, $password);
$user = $this->getUserObject($uid, $backend);
$this->emit('\OC\User', 'postCreateUser', array($user, $password));
@@ -302,7 +308,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(\OC\User\Backend::COUNT_USERS)) {
$backendUsers = $backend->countUsers();
if($backendUsers !== false) {
if($backend instanceof IUserBackend) {
@@ -335,11 +341,11 @@ class Manager extends PublicEmitter implements IUserManager {
$offset = 0;
do {
$users = $backend->getUsers($search, $limit, $offset);
- foreach ($users as $user) {
- $user = $this->get($user);
- if (is_null($user)) {
+ foreach ($users as $uid) {
+ if (!$backend->userExists($uid)) {
continue;
}
+ $user = $this->getUserObject($uid, $backend, false);
$return = $callback($user);
if ($return === false) {
break;
@@ -349,4 +355,17 @@ class Manager extends PublicEmitter implements IUserManager {
} while (count($users) >= $limit);
}
}
+
+ /**
+ * @param string $email
+ * @return IUser[]
+ * @since 9.1.0
+ */
+ public function getByEmail($email) {
+ $userIds = $this->config->getUsersForUserValue('settings', 'email', $email);
+
+ return array_map(function($uid) {
+ return $this->get($uid);
+ }, $userIds);
+ }
}
diff --git a/lib/private/user/nouserexception.php b/lib/private/User/NoUserException.php
index afd5c729fcf..afd5c729fcf 100644
--- a/lib/private/user/nouserexception.php
+++ b/lib/private/User/NoUserException.php
diff --git a/lib/private/User/Session.php b/lib/private/User/Session.php
new file mode 100644
index 00000000000..7104f46fea2
--- /dev/null
+++ b/lib/private/User/Session.php
@@ -0,0 +1,545 @@
+<?php
+
+/**
+ * @author Arthur Schiwon <blizzz@owncloud.com>
+ * @author Bernhard Posselt <dev@bernhard-posselt.com>
+ * @author Christoph Wurst <christoph@owncloud.com>
+ * @author Joas Schilling <nickvergessen@owncloud.com>
+ * @author Jörn Friedrich Dreyer <jfd@butonic.de>
+ * @author Lukas Reschke <lukas@owncloud.com>
+ * @author Morris Jobke <hey@morrisjobke.de>
+ * @author Robin Appelman <icewind@owncloud.com>
+ * @author Robin McCorkell <robin@mccorkell.me.uk>
+ * @author Roeland Jago Douma <rullzer@owncloud.com>
+ * @author Thomas Müller <thomas.mueller@tmit.eu>
+ * @author Vincent Petry <pvince81@owncloud.com>
+ *
+ * @copyright Copyright (c) 2016, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OC\User;
+
+use OC;
+use OC\Authentication\Exceptions\InvalidTokenException;
+use OC\Authentication\Token\IProvider;
+use OC\Authentication\Token\IToken;
+use OC\Hooks\Emitter;
+use OC_User;
+use OC_Util;
+use OCA\DAV\Connector\Sabre\Auth;
+use OCP\AppFramework\Utility\ITimeFactory;
+use OCP\IRequest;
+use OCP\ISession;
+use OCP\IUser;
+use OCP\IUserManager;
+use OCP\IUserSession;
+use OCP\Session\Exceptions\SessionNotAvailableException;
+
+/**
+ * Class Session
+ *
+ * Hooks available in scope \OC\User:
+ * - preSetPassword(\OC\User\User $user, string $password, string $recoverPassword)
+ * - postSetPassword(\OC\User\User $user, string $password, string $recoverPassword)
+ * - preDelete(\OC\User\User $user)
+ * - postDelete(\OC\User\User $user)
+ * - preCreateUser(string $uid, string $password)
+ * - postCreateUser(\OC\User\User $user)
+ * - preLogin(string $user, string $password)
+ * - postLogin(\OC\User\User $user, string $password)
+ * - preRememberedLogin(string $uid)
+ * - postRememberedLogin(\OC\User\User $user)
+ * - logout()
+ *
+ * @package OC\User
+ */
+class Session implements IUserSession, Emitter {
+
+ /** @var Manager $manager */
+ private $manager;
+
+ /** @var ISession $session */
+ private $session;
+
+ /** @var ITimeFactory */
+ private $timeFacory;
+
+ /** @var IProvider */
+ private $tokenProvider;
+
+ /** @var User $activeUser */
+ protected $activeUser;
+
+ /**
+ * @param IUserManager $manager
+ * @param ISession $session
+ * @param ITimeFactory $timeFacory
+ * @param IProvider $tokenProvider
+ */
+ public function __construct(IUserManager $manager, ISession $session, ITimeFactory $timeFacory, $tokenProvider) {
+ $this->manager = $manager;
+ $this->session = $session;
+ $this->timeFacory = $timeFacory;
+ $this->tokenProvider = $tokenProvider;
+ }
+
+ /**
+ * @param IProvider $provider
+ */
+ public function setTokenProvider(IProvider $provider) {
+ $this->tokenProvider = $provider;
+ }
+
+ /**
+ * @param string $scope
+ * @param string $method
+ * @param callable $callback
+ */
+ public function listen($scope, $method, callable $callback) {
+ $this->manager->listen($scope, $method, $callback);
+ }
+
+ /**
+ * @param string $scope optional
+ * @param string $method optional
+ * @param callable $callback optional
+ */
+ public function removeListener($scope = null, $method = null, callable $callback = null) {
+ $this->manager->removeListener($scope, $method, $callback);
+ }
+
+ /**
+ * get the manager object
+ *
+ * @return Manager
+ */
+ public function getManager() {
+ return $this->manager;
+ }
+
+ /**
+ * get the session object
+ *
+ * @return ISession
+ */
+ public function getSession() {
+ return $this->session;
+ }
+
+ /**
+ * set the session object
+ *
+ * @param ISession $session
+ */
+ public function setSession(ISession $session) {
+ if ($this->session instanceof ISession) {
+ $this->session->close();
+ }
+ $this->session = $session;
+ $this->activeUser = null;
+ }
+
+ /**
+ * set the currently active user
+ *
+ * @param User|null $user
+ */
+ public function setUser($user) {
+ if (is_null($user)) {
+ $this->session->remove('user_id');
+ } else {
+ $this->session->set('user_id', $user->getUID());
+ }
+ $this->activeUser = $user;
+ }
+
+ /**
+ * get the current active user
+ *
+ * @return IUser|null Current user, otherwise null
+ */
+ public function getUser() {
+ // FIXME: This is a quick'n dirty work-around for the incognito mode as
+ // described at https://github.com/owncloud/core/pull/12912#issuecomment-67391155
+ if (OC_User::isIncognitoMode()) {
+ return null;
+ }
+ if (is_null($this->activeUser)) {
+ $uid = $this->session->get('user_id');
+ if (is_null($uid)) {
+ return null;
+ }
+ $this->activeUser = $this->manager->get($uid);
+ if (is_null($this->activeUser)) {
+ return null;
+ }
+ $this->validateSession($this->activeUser);
+ }
+ return $this->activeUser;
+ }
+
+ protected function validateSession(IUser $user) {
+ try {
+ $sessionId = $this->session->getId();
+ } catch (SessionNotAvailableException $ex) {
+ return;
+ }
+ try {
+ $token = $this->tokenProvider->getToken($sessionId);
+ } catch (InvalidTokenException $ex) {
+ // Session was invalidated
+ $this->logout();
+ return;
+ }
+
+ // Check whether login credentials are still valid
+ // This check is performed each 5 minutes
+ $lastCheck = $this->session->get('last_login_check') ? : 0;
+ $now = $this->timeFacory->getTime();
+ if ($lastCheck < ($now - 60 * 5)) {
+ try {
+ $pwd = $this->tokenProvider->getPassword($token, $sessionId);
+ } catch (InvalidTokenException $ex) {
+ // An invalid token password was used -> log user out
+ $this->logout();
+ return;
+ }
+
+ if ($this->manager->checkPassword($user->getUID(), $pwd) === false) {
+ // Password has changed -> log user out
+ $this->logout();
+ return;
+ }
+ $this->session->set('last_login_check', $now);
+ }
+
+ // Session is valid, so the token can be refreshed
+ $this->updateToken($token);
+ }
+
+ /**
+ * Checks whether the user is logged in
+ *
+ * @return bool if logged in
+ */
+ public function isLoggedIn() {
+ $user = $this->getUser();
+ if (is_null($user)) {
+ return false;
+ }
+
+ return $user->isEnabled();
+ }
+
+ /**
+ * set the login name
+ *
+ * @param string|null $loginName for the logged in user
+ */
+ public function setLoginName($loginName) {
+ if (is_null($loginName)) {
+ $this->session->remove('loginname');
+ } else {
+ $this->session->set('loginname', $loginName);
+ }
+ }
+
+ /**
+ * get the login name of the current user
+ *
+ * @return string
+ */
+ public function getLoginName() {
+ if ($this->activeUser) {
+ return $this->session->get('loginname');
+ } else {
+ $uid = $this->session->get('user_id');
+ if ($uid) {
+ $this->activeUser = $this->manager->get($uid);
+ return $this->session->get('loginname');
+ } else {
+ return null;
+ }
+ }
+ }
+
+ /**
+ * try to login with the provided credentials
+ *
+ * @param string $uid
+ * @param string $password
+ * @return boolean|null
+ * @throws LoginException
+ */
+ public function login($uid, $password) {
+ $this->session->regenerateId();
+ $this->manager->emit('\OC\User', 'preLogin', array($uid, $password));
+ $user = $this->manager->checkPassword($uid, $password);
+ if ($user === false) {
+ if ($this->validateToken($password)) {
+ $user = $this->getUser();
+ }
+ }
+ if ($user !== false) {
+ if (!is_null($user)) {
+ if ($user->isEnabled()) {
+ $this->setUser($user);
+ $this->setLoginName($uid);
+ $this->manager->emit('\OC\User', 'postLogin', array($user, $password));
+ if ($this->isLoggedIn()) {
+ $this->prepareUserLogin();
+ return true;
+ } else {
+ // injecting l10n does not work - there is a circular dependency between session and \OCP\L10N\IFactory
+ $message = \OC::$server->getL10N('lib')->t('Login canceled by app');
+ throw new LoginException($message);
+ }
+ } else {
+ // injecting l10n does not work - there is a circular dependency between session and \OCP\L10N\IFactory
+ $message = \OC::$server->getL10N('lib')->t('User disabled');
+ throw new LoginException($message);
+ }
+ }
+ }
+ return false;
+ }
+
+ protected function prepareUserLogin() {
+ // TODO: mock/inject/use non-static
+ // Refresh the token
+ \OC::$server->getCsrfTokenManager()->refreshToken();
+ //we need to pass the user name, which may differ from login name
+ $user = $this->getUser()->getUID();
+ OC_Util::setupFS($user);
+ //trigger creation of user home and /files folder
+ \OC::$server->getUserFolder($user);
+ }
+
+ /**
+ * Tries to login the user with HTTP Basic Authentication
+ *
+ * @param IRequest $request
+ * @return boolean if the login was successful
+ */
+ public function tryBasicAuthLogin(IRequest $request) {
+ if (!empty($request->server['PHP_AUTH_USER']) && !empty($request->server['PHP_AUTH_PW'])) {
+ $result = $this->login($request->server['PHP_AUTH_USER'], $request->server['PHP_AUTH_PW']);
+ if ($result === true) {
+ /**
+ * Add DAV authenticated. This should in an ideal world not be
+ * necessary but the iOS App reads cookies from anywhere instead
+ * only the DAV endpoint.
+ * This makes sure that the cookies will be valid for the whole scope
+ * @see https://github.com/owncloud/core/issues/22893
+ */
+ $this->session->set(
+ Auth::DAV_AUTHENTICATED, $this->getUser()->getUID()
+ );
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private function loginWithToken($uid) {
+ // TODO: $this->manager->emit('\OC\User', 'preTokenLogin', array($uid));
+ $user = $this->manager->get($uid);
+ if (is_null($user)) {
+ // user does not exist
+ return false;
+ }
+ if (!$user->isEnabled()) {
+ // disabled users can not log in
+ return false;
+ }
+
+ //login
+ $this->setUser($user);
+ // TODO: $this->manager->emit('\OC\User', 'postTokenLogin', array($user));
+ return true;
+ }
+
+ /**
+ * Create a new session token for the given user credentials
+ *
+ * @param IRequest $request
+ * @param string $uid user UID
+ * @param string $password
+ * @return boolean
+ */
+ public function createSessionToken(IRequest $request, $uid, $password) {
+ if (is_null($this->manager->get($uid))) {
+ // User does not exist
+ return false;
+ }
+ $name = isset($request->server['HTTP_USER_AGENT']) ? $request->server['HTTP_USER_AGENT'] : 'unknown browser';
+ $loggedIn = $this->login($uid, $password);
+ if ($loggedIn) {
+ try {
+ $sessionId = $this->session->getId();
+ $this->tokenProvider->generateToken($sessionId, $uid, $password, $name);
+ } catch (SessionNotAvailableException $ex) {
+
+ }
+ }
+ return $loggedIn;
+ }
+
+ /**
+ * @param string $token
+ * @return boolean
+ */
+ private function validateToken($token) {
+ try {
+ $token = $this->tokenProvider->validateToken($token);
+ if (!is_null($token)) {
+ $result = $this->loginWithToken($token->getUID());
+ if ($result) {
+ // Login success
+ $this->updateToken($token);
+ return true;
+ }
+ }
+ } catch (InvalidTokenException $ex) {
+
+ }
+ return false;
+ }
+
+ /**
+ * @param IToken $token
+ */
+ private function updateToken(IToken $token) {
+ // To save unnecessary DB queries, this is only done once a minute
+ $lastTokenUpdate = $this->session->get('last_token_update') ? : 0;
+ $now = $this->timeFacory->getTime();
+ if ($lastTokenUpdate < ($now - 60)) {
+ $this->tokenProvider->updateToken($token);
+ $this->session->set('last_token_update', $now);
+ }
+ }
+
+ /**
+ * Tries to login the user with auth token header
+ *
+ * @todo check remember me cookie
+ * @return boolean
+ */
+ public function tryTokenLogin(IRequest $request) {
+ $authHeader = $request->getHeader('Authorization');
+ if (strpos($authHeader, 'token ') === false) {
+ // No auth header, let's try session id
+ try {
+ $sessionId = $this->session->getId();
+ return $this->validateToken($sessionId);
+ } catch (SessionNotAvailableException $ex) {
+ return false;
+ }
+ } else {
+ $token = substr($authHeader, 6);
+ return $this->validateToken($token);
+ }
+ }
+
+ /**
+ * perform login using the magic cookie (remember login)
+ *
+ * @param string $uid the username
+ * @param string $currentToken
+ * @return bool
+ */
+ public function loginWithCookie($uid, $currentToken) {
+ $this->session->regenerateId();
+ $this->manager->emit('\OC\User', 'preRememberedLogin', array($uid));
+ $user = $this->manager->get($uid);
+ if (is_null($user)) {
+ // user does not exist
+ return false;
+ }
+
+ // get stored tokens
+ $tokens = OC::$server->getConfig()->getUserKeys($uid, 'login_token');
+ // test cookies token against stored tokens
+ if (!in_array($currentToken, $tokens, true)) {
+ return false;
+ }
+ // replace successfully used token with a new one
+ OC::$server->getConfig()->deleteUserValue($uid, 'login_token', $currentToken);
+ $newToken = OC::$server->getSecureRandom()->generate(32);
+ OC::$server->getConfig()->setUserValue($uid, 'login_token', $newToken, time());
+ $this->setMagicInCookie($user->getUID(), $newToken);
+
+ //login
+ $this->setUser($user);
+ $this->manager->emit('\OC\User', 'postRememberedLogin', array($user));
+ return true;
+ }
+
+ /**
+ * logout the user from the session
+ */
+ public function logout() {
+ $this->manager->emit('\OC\User', 'logout');
+ $user = $this->getUser();
+ if (!is_null($user)) {
+ try {
+ $this->tokenProvider->invalidateToken($this->session->getId());
+ } catch (SessionNotAvailableException $ex) {
+
+ }
+ }
+ $this->setUser(null);
+ $this->setLoginName(null);
+ $this->unsetMagicInCookie();
+ $this->session->clear();
+ }
+
+ /**
+ * Set cookie value to use in next page load
+ *
+ * @param string $username username to be set
+ * @param string $token
+ */
+ public function setMagicInCookie($username, $token) {
+ $secureCookie = OC::$server->getRequest()->getServerProtocol() === 'https';
+ $expires = time() + OC::$server->getConfig()->getSystemValue('remember_login_cookie_lifetime', 60 * 60 * 24 * 15);
+ setcookie('oc_username', $username, $expires, OC::$WEBROOT, '', $secureCookie, true);
+ setcookie('oc_token', $token, $expires, OC::$WEBROOT, '', $secureCookie, true);
+ setcookie('oc_remember_login', '1', $expires, OC::$WEBROOT, '', $secureCookie, true);
+ }
+
+ /**
+ * Remove cookie for "remember username"
+ */
+ public function unsetMagicInCookie() {
+ //TODO: DI for cookies and IRequest
+ $secureCookie = OC::$server->getRequest()->getServerProtocol() === 'https';
+
+ unset($_COOKIE['oc_username']); //TODO: DI
+ unset($_COOKIE['oc_token']);
+ unset($_COOKIE['oc_remember_login']);
+ setcookie('oc_username', '', time() - 3600, OC::$WEBROOT, '', $secureCookie, true);
+ setcookie('oc_token', '', time() - 3600, OC::$WEBROOT, '', $secureCookie, true);
+ setcookie('oc_remember_login', '', time() - 3600, OC::$WEBROOT, '', $secureCookie, true);
+ // old cookies might be stored under /webroot/ instead of /webroot
+ // and Firefox doesn't like it!
+ setcookie('oc_username', '', time() - 3600, OC::$WEBROOT . '/', '', $secureCookie, true);
+ setcookie('oc_token', '', time() - 3600, OC::$WEBROOT . '/', '', $secureCookie, true);
+ setcookie('oc_remember_login', '', time() - 3600, OC::$WEBROOT . '/', '', $secureCookie, true);
+ }
+
+}
diff --git a/lib/private/user/user.php b/lib/private/User/User.php
index 3199790dba0..66ecbd18534 100644
--- a/lib/private/user/user.php
+++ b/lib/private/User/User.php
@@ -110,7 +110,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(\OC\User\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)) {
@@ -135,7 +135,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(\OC\User\Backend::SET_DISPLAYNAME) && !empty($displayName)) {
$result = $this->backend->setDisplayName($this->uid, $displayName);
if ($result) {
$this->displayName = $displayName;
@@ -230,7 +230,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(\OC\User\Backend::SET_PASSWORD)) {
$result = $this->backend->setPassword($this->uid, $password);
if ($this->emitter) {
$this->emitter->emit('\OC\User', 'postSetPassword', array($this, $password, $recoveryPassword));
@@ -248,7 +248,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(\OC\User\Backend::GET_HOME) and $home = $this->backend->getHome($this->uid)) {
$this->home = $home;
} elseif ($this->config) {
$this->home = $this->config->getSystemValue('datadirectory') . '/' . $this->uid;
@@ -277,7 +277,7 @@ class User implements IUser {
* @return bool
*/
public function canChangeAvatar() {
- if ($this->backend->implementsActions(\OC_User_Backend::PROVIDE_AVATAR)) {
+ if ($this->backend->implementsActions(\OC\User\Backend::PROVIDE_AVATAR)) {
return $this->backend->canChangeAvatar($this->uid);
}
return true;
@@ -289,7 +289,7 @@ class User implements IUser {
* @return bool
*/
public function canChangePassword() {
- return $this->backend->implementsActions(\OC_User_Backend::SET_PASSWORD);
+ return $this->backend->implementsActions(\OC\User\Backend::SET_PASSWORD);
}
/**
@@ -301,7 +301,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(\OC\User\Backend::SET_DISPLAYNAME);
}
/**
@@ -417,5 +417,4 @@ class User implements IUser {
$this->emitter->emit('\OC\User', 'changeUser', array($this, $feature, $value));
}
}
-
}
diff --git a/lib/private/api.php b/lib/private/legacy/api.php
index bab879c95f8..60300c88b57 100644
--- a/lib/private/api.php
+++ b/lib/private/legacy/api.php
@@ -337,7 +337,7 @@ class OC_API {
}
// reuse existing login
- $loggedIn = OC_User::isLoggedIn();
+ $loggedIn = \OC::$server->getUserSession()->isLoggedIn();
if ($loggedIn === true) {
$ocsApiRequest = isset($_SERVER['HTTP_OCS_APIREQUEST']) ? $_SERVER['HTTP_OCS_APIREQUEST'] === 'true' : false;
if ($ocsApiRequest) {
@@ -353,31 +353,25 @@ class OC_API {
// basic auth - because OC_User::login will create a new session we shall only try to login
// if user and pass are set
- if(isset($_SERVER['PHP_AUTH_USER']) && isset($_SERVER['PHP_AUTH_PW']) ) {
- $authUser = $_SERVER['PHP_AUTH_USER'];
- $authPw = $_SERVER['PHP_AUTH_PW'];
- $return = OC_User::login($authUser, $authPw);
- if ($return === true) {
- self::$logoutRequired = true;
-
- // initialize the user's filesystem
- \OC_Util::setUpFS(\OC_User::getUser());
- self::$isLoggedIn = true;
+ $userSession = \OC::$server->getUserSession();
+ $request = \OC::$server->getRequest();
+ try {
+ $loginSuccess = $userSession->tryTokenLogin($request);
+ if (!$loginSuccess) {
+ $loginSuccess = $userSession->tryBasicAuthLogin($request);
+ }
+ } catch (\OC\User\LoginException $e) {
+ return false;
+ }
+
+ if ($loginSuccess === true) {
+ self::$logoutRequired = true;
- /**
- * Add DAV authenticated. This should in an ideal world not be
- * necessary but the iOS App reads cookies from anywhere instead
- * only the DAV endpoint.
- * This makes sure that the cookies will be valid for the whole scope
- * @see https://github.com/owncloud/core/issues/22893
- */
- \OC::$server->getSession()->set(
- \OCA\DAV\Connector\Sabre\Auth::DAV_AUTHENTICATED,
- \OC::$server->getUserSession()->getUser()->getUID()
- );
+ // initialize the user's filesystem
+ \OC_Util::setUpFS(\OC_User::getUser());
+ self::$isLoggedIn = true;
- return \OC_User::getUser();
- }
+ return \OC_User::getUser();
}
return false;
diff --git a/lib/private/app.php b/lib/private/legacy/app.php
index 246bf97ee91..f558c873556 100644
--- a/lib/private/app.php
+++ b/lib/private/legacy/app.php
@@ -46,6 +46,7 @@
*/
use OC\App\DependencyAnalyzer;
use OC\App\Platform;
+use OC\Installer;
use OC\OCSClient;
use OC\Repair;
@@ -107,7 +108,7 @@ class OC_App {
foreach($apps as $app) {
$path = self::getAppPath($app);
if($path !== false) {
- \OC::$loader->addValidRoot($path);
+ self::registerAutoloading($app, $path);
}
}
@@ -136,7 +137,10 @@ class OC_App {
if($appPath === false) {
return;
}
- \OC::$loader->addValidRoot($appPath); // in case someone calls loadApp() directly
+
+ // in case someone calls loadApp() directly
+ self::registerAutoloading($app, $appPath);
+
if (is_file($appPath . '/appinfo/app.php')) {
\OC::$server->getEventLogger()->start('load_app_' . $app, 'Load app: ' . $app);
if ($checkUpgrade and self::shouldUpgrade($app)) {
@@ -155,6 +159,23 @@ class OC_App {
}
/**
+ * @internal
+ * @param string $app
+ * @param string $path
+ */
+ public static function registerAutoloading($app, $path) {
+ // Register on PSR-4 composer autoloader
+ $appNamespace = \OC\AppFramework\App::buildAppNamespace($app);
+ \OC::$composerAutoloader->addPsr4($appNamespace . '\\', $path . '/lib/', true);
+ if (defined('PHPUNIT_RUN')) {
+ \OC::$composerAutoloader->addPsr4($appNamespace . '\\Tests\\', $path . '/tests/', true);
+ }
+
+ // Register on legacy autoloader
+ \OC::$loader->addValidRoot($path);
+ }
+
+ /**
* Load app.php from the given app
*
* @param string $app app name
@@ -304,7 +325,7 @@ class OC_App {
*/
public static function enable($app, $groups = null) {
self::$enabledAppsCache = array(); // flush
- if (!OC_Installer::isInstalled($app)) {
+ if (!Installer::isInstalled($app)) {
$app = self::installApp($app);
}
@@ -340,7 +361,7 @@ class OC_App {
// Replace spaces in download link without encoding entire URL
$download['downloadlink'] = str_replace(' ', '%20', $download['downloadlink']);
$info = array('source' => 'http', 'href' => $download['downloadlink'], 'appdata' => $appData);
- $app = OC_Installer::installApp($info);
+ $app = Installer::installApp($info);
}
return $app;
}
@@ -354,7 +375,7 @@ class OC_App {
return false;
}
- return OC_Installer::removeApp($app);
+ return Installer::removeApp($app);
}
/**
@@ -369,9 +390,19 @@ class OC_App {
$app = self::getInternalAppIdByOcs($app);
}
- self::$enabledAppsCache = array(); // flush
- // check if app is a shipped app or not. if not delete
+ // flush
+ self::$enabledAppsCache = array();
+
+ // run uninstall steps
+ $appData = OC_App::getAppInfo($app);
+ if (!is_null($appData)) {
+ OC_App::executeRepairSteps($app, $appData['repair-steps']['uninstall']);
+ }
+
+ // emit disable hook - needed anymore ?
\OC_Hook::emit('OC_App', 'pre_disable', array('app' => $app));
+
+ // finally disable it
$appManager = \OC::$server->getAppManager();
$appManager->disableApp($app);
}
@@ -827,7 +858,7 @@ class OC_App {
$info['removable'] = true;
}
- $info['update'] = ($includeUpdateInfo) ? OC_Installer::isUpdateAvailable($app) : null;
+ $info['update'] = ($includeUpdateInfo) ? Installer::isUpdateAvailable($app) : null;
$appPath = self::getAppPath($app);
if($appPath !== false) {
@@ -1073,7 +1104,7 @@ class OC_App {
if ($appData && version_compare($shippedVersion, $appData['version'], '<')) {
$app = self::downloadApp($app);
} else {
- $app = OC_Installer::installShippedApp($app);
+ $app = Installer::installShippedApp($app);
}
} else {
// Maybe the app is already installed - compare the version in this
@@ -1160,6 +1191,7 @@ class OC_App {
self::loadApp($appId, false);
include $appPath . '/appinfo/update.php';
}
+ self::setupBackgroundJobs($appData['background-jobs']);
//set remote/public handlers
if (array_key_exists('ocsid', $appData)) {
@@ -1187,7 +1219,7 @@ class OC_App {
* @param string[] $steps
* @throws \OC\NeedsUpdateException
*/
- private static function executeRepairSteps($appId, array $steps) {
+ public static function executeRepairSteps($appId, array $steps) {
if (empty($steps)) {
return;
}
@@ -1210,6 +1242,13 @@ class OC_App {
$r->run();
}
+ public static function setupBackgroundJobs(array $jobs) {
+ $queue = \OC::$server->getJobList();
+ foreach ($jobs as $job) {
+ $queue->add($job);
+ }
+ }
+
/**
* @param string $appId
* @param string[] $steps
diff --git a/lib/private/db.php b/lib/private/legacy/db.php
index 5d612312919..5d612312919 100644
--- a/lib/private/db.php
+++ b/lib/private/legacy/db.php
diff --git a/lib/private/defaults.php b/lib/private/legacy/defaults.php
index 43e8c8082cc..43e8c8082cc 100644
--- a/lib/private/defaults.php
+++ b/lib/private/legacy/defaults.php
diff --git a/lib/private/eventsource.php b/lib/private/legacy/eventsource.php
index f567d1e6ca5..f567d1e6ca5 100644
--- a/lib/private/eventsource.php
+++ b/lib/private/legacy/eventsource.php
diff --git a/lib/private/filechunking.php b/lib/private/legacy/filechunking.php
index f2cef275458..f2cef275458 100644
--- a/lib/private/filechunking.php
+++ b/lib/private/legacy/filechunking.php
diff --git a/lib/private/files.php b/lib/private/legacy/files.php
index 9b6a1a4465f..9b6a1a4465f 100644
--- a/lib/private/files.php
+++ b/lib/private/legacy/files.php
diff --git a/lib/private/group.php b/lib/private/legacy/group.php
index f1b84069a38..ceb99389942 100644
--- a/lib/private/group.php
+++ b/lib/private/legacy/group.php
@@ -66,7 +66,7 @@ class OC_Group {
/**
* set the group backend
- * @param \OC_Group_Backend $backend The backend to use for user management
+ * @param \OC\Group\Backend $backend The backend to use for user management
* @return bool
*/
public static function useBackend($backend) {
diff --git a/lib/private/legacy/group/backend.php b/lib/private/legacy/group/backend.php
new file mode 100644
index 00000000000..a5df9c339b9
--- /dev/null
+++ b/lib/private/legacy/group/backend.php
@@ -0,0 +1,59 @@
+<?php
+/**
+ * @author Arthur Schiwon <blizzz@owncloud.com>
+ * @author Bart Visscher <bartv@thisnet.nl>
+ * @author Jakob Sack <mail@jakobsack.de>
+ * @author Joas Schilling <nickvergessen@owncloud.com>
+ * @author Jörn Friedrich Dreyer <jfd@butonic.de>
+ * @author Lukas Reschke <lukas@owncloud.com>
+ * @author Michael Gapczynski <GapczynskiM@gmail.com>
+ * @author Morris Jobke <hey@morrisjobke.de>
+ * @author Robin Appelman <icewind@owncloud.com>
+ * @author Robin McCorkell <robin@mccorkell.me.uk>
+ * @author Thomas Müller <thomas.mueller@tmit.eu>
+ *
+ * @copyright Copyright (c) 2016, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+/**
+ * error code for functions not provided by the group backend
+ * @deprecated Use \OC_Group_Backend::NOT_IMPLEMENTED instead
+ */
+define('OC_GROUP_BACKEND_NOT_IMPLEMENTED', -501);
+
+/**
+ * actions that user backends can define
+ */
+/** @deprecated Use \OC_Group_Backend::CREATE_GROUP instead */
+define('OC_GROUP_BACKEND_CREATE_GROUP', 0x00000001);
+/** @deprecated Use \OC_Group_Backend::DELETE_GROUP instead */
+define('OC_GROUP_BACKEND_DELETE_GROUP', 0x00000010);
+/** @deprecated Use \OC_Group_Backend::ADD_TO_GROUP instead */
+define('OC_GROUP_BACKEND_ADD_TO_GROUP', 0x00000100);
+/** @deprecated Use \OC_Group_Backend::REMOVE_FROM_GOUP instead */
+define('OC_GROUP_BACKEND_REMOVE_FROM_GOUP', 0x00001000);
+/** @deprecated Obsolete */
+define('OC_GROUP_BACKEND_GET_DISPLAYNAME', 0x00010000); //OBSOLETE
+/** @deprecated Use \OC_Group_Backend::COUNT_USERS instead */
+define('OC_GROUP_BACKEND_COUNT_USERS', 0x00100000);
+
+/**
+ * Abstract base class for user management
+ * @deprecated Since 9.1.0 use \OC\Group\Backend
+ */
+abstract class OC_Group_Backend extends \OC\Group\Backend {
+}
diff --git a/lib/private/legacy/group/database.php b/lib/private/legacy/group/database.php
new file mode 100644
index 00000000000..3969b3681fe
--- /dev/null
+++ b/lib/private/legacy/group/database.php
@@ -0,0 +1,30 @@
+<?php
+/**
+ * @author Jakob Sack <mail@jakobsack.de>
+ * @author Morris Jobke <hey@morrisjobke.de>
+ * @author Roeland Jago Douma <rullzer@owncloud.com>
+ *
+ * @copyright Copyright (c) 2016, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+/**
+ * Class OC_Group_Database
+ * @deprecated Since 9.1.0 use \OC\Group\Database
+ */
+class OC_Group_Database extends \OC\Group\Database {
+
+} \ No newline at end of file
diff --git a/lib/private/group/example.php b/lib/private/legacy/group/example.php
index 17fae90f2e0..17fae90f2e0 100644
--- a/lib/private/group/example.php
+++ b/lib/private/legacy/group/example.php
diff --git a/lib/private/group/interface.php b/lib/private/legacy/group/interface.php
index bdfe5235103..bdfe5235103 100644
--- a/lib/private/group/interface.php
+++ b/lib/private/legacy/group/interface.php
diff --git a/lib/private/helper.php b/lib/private/legacy/helper.php
index e6aaed0fd15..29ee1be76b4 100644
--- a/lib/private/helper.php
+++ b/lib/private/legacy/helper.php
@@ -67,21 +67,6 @@ class OC_Helper {
}
/**
- * get path to preview of file
- * @param string $path path
- * @return string the url
- *
- * Returns the path to the preview of the file.
- */
- public static function previewIcon($path) {
- return \OC::$server->getURLGenerator()->linkToRoute('core_ajax_preview', ['x' => 32, 'y' => 32, 'file' => $path]);
- }
-
- public static function publicPreviewIcon( $path, $token ) {
- return \OC::$server->getURLGenerator()->linkToRoute('core_ajax_public_preview', ['x' => 32, 'y' => 32, 'file' => $path, 't' => $token]);
- }
-
- /**
* Make a human file size
* @param int $bytes file size in bytes
* @return string a human readable file size
@@ -463,22 +448,6 @@ class OC_Helper {
}
/**
- * Shortens str to maxlen by replacing characters in the middle with '...', eg.
- * ellipsis('a very long string with lots of useless info to make a better example', 14) becomes 'a very ...example'
- *
- * @param string $str the string
- * @param string $maxlen the maximum length of the result
- * @return string with at most maxlen characters
- */
- public static function ellipsis($str, $maxlen) {
- if (strlen($str) > $maxlen) {
- $characters = floor($maxlen / 2);
- return substr($str, 0, $characters) . '...' . substr($str, -1 * $characters);
- }
- return $str;
- }
-
- /**
* calculates the maximum upload size respecting system settings, free space and user quota
*
* @param string $dir the current folder where the user currently operates
diff --git a/lib/private/hook.php b/lib/private/legacy/hook.php
index 76f3b657eb9..76f3b657eb9 100644
--- a/lib/private/hook.php
+++ b/lib/private/legacy/hook.php
diff --git a/lib/private/image.php b/lib/private/legacy/image.php
index a97347df623..a97347df623 100644
--- a/lib/private/image.php
+++ b/lib/private/legacy/image.php
diff --git a/lib/private/json.php b/lib/private/legacy/json.php
index 74aebd476fb..74aebd476fb 100644
--- a/lib/private/json.php
+++ b/lib/private/legacy/json.php
diff --git a/lib/private/ocs.php b/lib/private/legacy/ocs.php
index f48879a98b1..f48879a98b1 100644
--- a/lib/private/ocs.php
+++ b/lib/private/legacy/ocs.php
diff --git a/lib/private/legacy/ocs/cloud.php b/lib/private/legacy/ocs/cloud.php
new file mode 100644
index 00000000000..1430cfa94ed
--- /dev/null
+++ b/lib/private/legacy/ocs/cloud.php
@@ -0,0 +1,27 @@
+<?php
+/**
+ * @author Roeland Jago Douma <rullzer@owncloud.com>
+ * @author Tom Needham <tom@owncloud.com>
+ *
+ * @copyright Copyright (c) 2016, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+/**
+ * @deprecated Since 9.1.0 use \OC\OCS\Cloud
+ */
+class OC_OCS_Cloud extends \OC\OCS\Cloud {
+}
diff --git a/lib/private/legacy/ocs/config.php b/lib/private/legacy/ocs/config.php
new file mode 100644
index 00000000000..b2e473276b4
--- /dev/null
+++ b/lib/private/legacy/ocs/config.php
@@ -0,0 +1,27 @@
+<?php
+/**
+ * @author Roeland Jago Douma <rullzer@owncloud.com>
+ * @author Tom Needham <tom@owncloud.com>
+ *
+ * @copyright Copyright (c) 2016, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+/**
+ * @deprecated Since 9.1.0 use \OC\OCS\Config
+ */
+class OC_OCS_Config extends \OC\OCS\Config {
+}
diff --git a/lib/private/legacy/ocs/person.php b/lib/private/legacy/ocs/person.php
new file mode 100644
index 00000000000..edf4a7ced55
--- /dev/null
+++ b/lib/private/legacy/ocs/person.php
@@ -0,0 +1,27 @@
+<?php
+/**
+ * @author Roeland Jago Douma <rullzer@owncloud.com>
+ * @author Tom Needham <tom@owncloud.com>
+ *
+ * @copyright Copyright (c) 2016, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+/**
+ * @deprecated Since 9.1.0 use \OC\OCS\Person
+ */
+class OC_OCS_Person extends \OC\OCS\Person {
+}
diff --git a/lib/private/legacy/ocs/privatedata.php b/lib/private/legacy/ocs/privatedata.php
new file mode 100644
index 00000000000..3c402457366
--- /dev/null
+++ b/lib/private/legacy/ocs/privatedata.php
@@ -0,0 +1,27 @@
+<?php
+/**
+ * @author Roeland Jago Douma <rullzer@owncloud.com>
+ * @author Tom Needham <tom@owncloud.com>
+ *
+ * @copyright Copyright (c) 2016, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+/**
+ * @deprecated Since 9.1.0 use \OC\OCS\PrivateData
+ */
+class OC_OCS_Privatedata extends \OC\OCS\PrivateData {
+}
diff --git a/lib/private/legacy/ocs/result.php b/lib/private/legacy/ocs/result.php
new file mode 100644
index 00000000000..b59c6404e25
--- /dev/null
+++ b/lib/private/legacy/ocs/result.php
@@ -0,0 +1,27 @@
+<?php
+/**
+ * @author Christopher Schäpers <kondou@ts.unde.re>
+ * @author Roeland Jago Douma <rullzer@owncloud.com>
+ *
+ * @copyright Copyright (c) 2016, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+/**
+ * @deprecated Since 9.1.0 use \OC\OCS\Result
+ */
+class OC_OCS_Result extends \OC\OCS\Result {
+}
diff --git a/lib/private/response.php b/lib/private/legacy/response.php
index 51e0ff75e6a..51e0ff75e6a 100644
--- a/lib/private/response.php
+++ b/lib/private/legacy/response.php
diff --git a/lib/private/template.php b/lib/private/legacy/template.php
index 73725529702..73725529702 100644
--- a/lib/private/template.php
+++ b/lib/private/legacy/template.php
diff --git a/lib/private/template/functions.php b/lib/private/legacy/template/functions.php
index a57b3575ba9..a0540420e29 100644
--- a/lib/private/template/functions.php
+++ b/lib/private/legacy/template/functions.php
@@ -184,18 +184,16 @@ function mimetype_icon( $mimetype ) {
* Returns the path to the preview of the image.
* @param string $path path of file
* @return link to the preview
- *
- * For further information have a look at OC_Helper::previewIcon
*/
function preview_icon( $path ) {
- return OC_Helper::previewIcon( $path );
+ return \OC::$server->getURLGenerator()->linkToRoute('core_ajax_preview', ['x' => 32, 'y' => 32, 'file' => $path]);
}
/**
* @param string $path
*/
function publicPreview_icon ( $path, $token ) {
- return OC_Helper::publicPreviewIcon( $path, $token );
+ return \OC::$server->getURLGenerator()->linkToRoute('core_ajax_public_preview', ['x' => 32, 'y' => 32, 'file' => $path, 't' => $token]);
}
/**
diff --git a/lib/private/user.php b/lib/private/legacy/user.php
index 11c35daa0de..499e916994a 100644
--- a/lib/private/user.php
+++ b/lib/private/legacy/user.php
@@ -6,6 +6,7 @@
* @author Bart Visscher <bartv@thisnet.nl>
* @author Bartek Przybylski <bart.p.pl@gmail.com>
* @author Björn Schießle <schiessle@owncloud.com>
+ * @author Christoph Wurst <christoph@owncloud.com>
* @author Florian Preinstorfer <nblock@archlinux.us>
* @author Georg Ehrke <georg@owncloud.com>
* @author Jakob Sack <mail@jakobsack.de>
@@ -63,13 +64,11 @@ class OC_User {
return OC::$server->getUserSession();
}
- private static $_backends = array();
-
private static $_usedBackends = array();
private static $_setupedBackends = array();
- // bool, stores if a user want to access a resource anonymously, e.g if he opens a public link
+ // bool, stores if a user want to access a resource anonymously, e.g if they open a public link
private static $incognitoMode = false;
/**
@@ -96,7 +95,7 @@ class OC_User {
case 'mysql':
case 'sqlite':
\OCP\Util::writeLog('core', 'Adding user backend ' . $backend . '.', \OCP\Util::DEBUG);
- self::$_usedBackends[$backend] = new OC_User_Database();
+ self::$_usedBackends[$backend] = new \OC\User\Database();
\OC::$server->getUserManager()->registerBackend(self::$_usedBackends[$backend]);
break;
case 'dummy':
@@ -105,7 +104,7 @@ class OC_User {
break;
default:
\OCP\Util::writeLog('core', 'Adding default user backend ' . $backend . '.', \OCP\Util::DEBUG);
- $className = 'OC_USER_' . strToUpper($backend);
+ $className = 'OC_USER_' . strtoupper($backend);
self::$_usedBackends[$backend] = new $className();
\OC::$server->getUserManager()->registerBackend(self::$_usedBackends[$backend]);
break;
@@ -150,31 +149,10 @@ class OC_User {
}
/**
- * Try to login a user
- *
- * @param string $loginname The login name of the user to log in
- * @param string $password The password of the user
- * @return boolean|null
- *
- * Log in a user and regenerate a new session - if the password is ok
- */
- public static function login($loginname, $password) {
- $result = self::getUserSession()->login($loginname, $password);
- if ($result) {
- // Refresh the token
- \OC::$server->getCsrfTokenManager()->refreshToken();
- //we need to pass the user name, which may differ from login name
- $user = self::getUserSession()->getUser()->getUID();
- OC_Util::setupFS($user);
- //trigger creation of user home and /files folder
- \OC::$server->getUserFolder($user);
- }
- return $result;
- }
- /**
* Try to login a user using the magic cookie (remember login)
*
+ * @deprecated use \OCP\IUserSession::loginWithCookie()
* @param string $uid The username of the user to log in
* @param string $token
* @return bool
@@ -205,10 +183,13 @@ class OC_User {
self::getUserSession()->setLoginName($uid);
// setup the filesystem
OC_Util::setupFS($uid);
+ // first call the post_login hooks, the login-process needs to be
+ // completed before we can safely create the users folder.
+ // For example encryption needs to initialize the users keys first
+ // before we can create the user folder with the skeleton files
+ OC_Hook::emit("OC_User", "post_login", array("uid" => $uid, 'password' => ''));
//trigger creation of user home and /files folder
\OC::$server->getUserFolder($uid);
-
- OC_Hook::emit("OC_User", "post_login", array("uid" => $uid, 'password' => ''));
}
return true;
}
@@ -241,6 +222,8 @@ class OC_User {
/**
* Sets user id for session and triggers emit
+ *
+ * @param string $uid
*/
public static function setUserId($uid) {
$userSession = \OC::$server->getUserSession();
@@ -272,38 +255,13 @@ class OC_User {
}
/**
- * Tries to login the user with HTTP Basic Authentication
- */
- public static function tryBasicAuthLogin() {
- if (!empty($_SERVER['PHP_AUTH_USER']) && !empty($_SERVER['PHP_AUTH_PW'])) {
- $result = \OC_User::login($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']);
- if($result === true) {
- /**
- * Add DAV authenticated. This should in an ideal world not be
- * necessary but the iOS App reads cookies from anywhere instead
- * only the DAV endpoint.
- * This makes sure that the cookies will be valid for the whole scope
- * @see https://github.com/owncloud/core/issues/22893
- */
- \OC::$server->getSession()->set(
- \OCA\DAV\Connector\Sabre\Auth::DAV_AUTHENTICATED,
- \OC::$server->getUserSession()->getUser()->getUID()
- );
- }
- }
- }
-
- /**
* Check if the user is logged in, considers also the HTTP basic credentials
*
+ * @deprecated use \OC::$server->getUserSession()->isLoggedIn()
* @return bool
*/
public static function isLoggedIn() {
- if (\OC::$server->getSession()->get('user_id') !== null && self::$incognitoMode === false) {
- return self::userExists(\OC::$server->getSession()->get('user_id'));
- }
-
- return false;
+ return \OC::$server->getUserSession()->isLoggedIn();
}
/**
diff --git a/lib/private/legacy/user/backend.php b/lib/private/legacy/user/backend.php
new file mode 100644
index 00000000000..42c7b9aa126
--- /dev/null
+++ b/lib/private/legacy/user/backend.php
@@ -0,0 +1,67 @@
+<?php
+/**
+ * @author Aldo "xoen" Giambelluca <xoen@xoen.org>
+ * @author Bart Visscher <bartv@thisnet.nl>
+ * @author Björn Schießle <schiessle@owncloud.com>
+ * @author Dominik Schmidt <dev@dominik-schmidt.de>
+ * @author Georg Ehrke <georg@owncloud.com>
+ * @author Jakob Sack <mail@jakobsack.de>
+ * @author Joas Schilling <nickvergessen@owncloud.com>
+ * @author Jörn Friedrich Dreyer <jfd@butonic.de>
+ * @author Lukas Reschke <lukas@owncloud.com>
+ * @author Morris Jobke <hey@morrisjobke.de>
+ * @author Robin Appelman <icewind@owncloud.com>
+ * @author Sam Tuke <mail@samtuke.com>
+ * @author Thomas Müller <thomas.mueller@tmit.eu>
+ * @author Tigran Mkrtchyan <tigran.mkrtchyan@desy.de>
+ *
+ * @copyright Copyright (c) 2016, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+/**
+ * error code for functions not provided by the user backend
+ * @deprecated Use \OC_User_Backend::NOT_IMPLEMENTED instead
+ */
+define('OC_USER_BACKEND_NOT_IMPLEMENTED', -501);
+
+/**
+ * actions that user backends can define
+ */
+/** @deprecated Use \OC_User_Backend::CREATE_USER instead */
+define('OC_USER_BACKEND_CREATE_USER', 1 << 0);
+/** @deprecated Use \OC_User_Backend::SET_PASSWORD instead */
+define('OC_USER_BACKEND_SET_PASSWORD', 1 << 4);
+/** @deprecated Use \OC_User_Backend::CHECK_PASSWORD instead */
+define('OC_USER_BACKEND_CHECK_PASSWORD', 1 << 8);
+/** @deprecated Use \OC_User_Backend::GET_HOME instead */
+define('OC_USER_BACKEND_GET_HOME', 1 << 12);
+/** @deprecated Use \OC_User_Backend::GET_DISPLAYNAME instead */
+define('OC_USER_BACKEND_GET_DISPLAYNAME', 1 << 16);
+/** @deprecated Use \OC_User_Backend::SET_DISPLAYNAME instead */
+define('OC_USER_BACKEND_SET_DISPLAYNAME', 1 << 20);
+/** @deprecated Use \OC_User_Backend::PROVIDE_AVATAR instead */
+define('OC_USER_BACKEND_PROVIDE_AVATAR', 1 << 24);
+/** @deprecated Use \OC_User_Backend::COUNT_USERS instead */
+define('OC_USER_BACKEND_COUNT_USERS', 1 << 28);
+
+/**
+ * Abstract base class for user management. Provides methods for querying backend
+ * capabilities.
+ */
+abstract class OC_User_Backend extends \OC\User\Backend implements \OCP\UserInterface {
+
+}
diff --git a/lib/private/user/interface.php b/lib/private/legacy/user/interface.php
index d2868a79c2c..d2868a79c2c 100644
--- a/lib/private/user/interface.php
+++ b/lib/private/legacy/user/interface.php
diff --git a/lib/private/util.php b/lib/private/legacy/util.php
index 7caa1efcf54..4f7a8668dfc 100644
--- a/lib/private/util.php
+++ b/lib/private/legacy/util.php
@@ -145,6 +145,7 @@ class OC_Util {
\OC\Files\Filesystem::initMountManager();
+ \OC\Files\Filesystem::logWarningWhenAddingStorageWrapper(false);
\OC\Files\Filesystem::addStorageWrapper('mount_options', function ($mountPoint, \OCP\Files\Storage $storage, \OCP\Files\Mount\IMountPoint $mount) {
if ($storage->instanceOfStorage('\OC\Files\Storage\Common')) {
/** @var \OC\Files\Storage\Common $storage */
@@ -195,6 +196,7 @@ class OC_Util {
});
OC_Hook::emit('OC_Filesystem', 'preSetup', array('user' => $user));
+ \OC\Files\Filesystem::logWarningWhenAddingStorageWrapper(true);
//check if we are using an object storage
$objectStore = \OC::$server->getSystemConfig()->getValue('objectstore', null);
@@ -955,8 +957,7 @@ class OC_Util {
public static function checkLoggedIn() {
// Check if we are a user
if (!OC_User::isLoggedIn()) {
- header('Location: ' . \OC::$server->getURLGenerator()->linkToRoute(
- 'core.login.showLoginForm',
+ header('Location: ' . \OCP\Util::linkToAbsolute('', 'index.php',
[
'redirect_url' => \OC::$server->getRequest()->getRequestUri()
]
diff --git a/lib/private/user/session.php b/lib/private/user/session.php
deleted file mode 100644
index 5402c5cf74f..00000000000
--- a/lib/private/user/session.php
+++ /dev/null
@@ -1,318 +0,0 @@
-<?php
-/**
- * @author Arthur Schiwon <blizzz@owncloud.com>
- * @author Bernhard Posselt <dev@bernhard-posselt.com>
- * @author Joas Schilling <nickvergessen@owncloud.com>
- * @author Jörn Friedrich Dreyer <jfd@butonic.de>
- * @author Lukas Reschke <lukas@owncloud.com>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <icewind@owncloud.com>
- * @author Robin McCorkell <robin@mccorkell.me.uk>
- * @author Roeland Jago Douma <rullzer@owncloud.com>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- * @author Vincent Petry <pvince81@owncloud.com>
- *
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
- */
-
-namespace OC\User;
-
-use OC\Hooks\Emitter;
-use OCP\IUserSession;
-
-/**
- * Class Session
- *
- * Hooks available in scope \OC\User:
- * - preSetPassword(\OC\User\User $user, string $password, string $recoverPassword)
- * - postSetPassword(\OC\User\User $user, string $password, string $recoverPassword)
- * - preDelete(\OC\User\User $user)
- * - postDelete(\OC\User\User $user)
- * - preCreateUser(string $uid, string $password)
- * - postCreateUser(\OC\User\User $user)
- * - preLogin(string $user, string $password)
- * - postLogin(\OC\User\User $user, string $password)
- * - preRememberedLogin(string $uid)
- * - postRememberedLogin(\OC\User\User $user)
- * - logout()
- *
- * @package OC\User
- */
-class Session implements IUserSession, Emitter {
- /**
- * @var \OC\User\Manager $manager
- */
- private $manager;
-
- /**
- * @var \OC\Session\Session $session
- */
- private $session;
-
- /**
- * @var \OC\User\User $activeUser
- */
- protected $activeUser;
-
- /**
- * @param \OCP\IUserManager $manager
- * @param \OCP\ISession $session
- */
- public function __construct(\OCP\IUserManager $manager, \OCP\ISession $session) {
- $this->manager = $manager;
- $this->session = $session;
- }
-
- /**
- * @param string $scope
- * @param string $method
- * @param callable $callback
- */
- public function listen($scope, $method, callable $callback) {
- $this->manager->listen($scope, $method, $callback);
- }
-
- /**
- * @param string $scope optional
- * @param string $method optional
- * @param callable $callback optional
- */
- public function removeListener($scope = null, $method = null, callable $callback = null) {
- $this->manager->removeListener($scope, $method, $callback);
- }
-
- /**
- * get the manager object
- *
- * @return \OC\User\Manager
- */
- public function getManager() {
- return $this->manager;
- }
-
- /**
- * get the session object
- *
- * @return \OCP\ISession
- */
- public function getSession() {
- return $this->session;
- }
-
- /**
- * set the session object
- *
- * @param \OCP\ISession $session
- */
- public function setSession(\OCP\ISession $session) {
- if ($this->session instanceof \OCP\ISession) {
- $this->session->close();
- }
- $this->session = $session;
- $this->activeUser = null;
- }
-
- /**
- * set the currently active user
- *
- * @param \OC\User\User|null $user
- */
- public function setUser($user) {
- if (is_null($user)) {
- $this->session->remove('user_id');
- } else {
- $this->session->set('user_id', $user->getUID());
- }
- $this->activeUser = $user;
- }
-
- /**
- * get the current active user
- *
- * @return \OCP\IUser|null Current user, otherwise null
- */
- public function getUser() {
- // FIXME: This is a quick'n dirty work-around for the incognito mode as
- // described at https://github.com/owncloud/core/pull/12912#issuecomment-67391155
- if (\OC_User::isIncognitoMode()) {
- return null;
- }
- if ($this->activeUser) {
- return $this->activeUser;
- } else {
- $uid = $this->session->get('user_id');
- if ($uid !== null) {
- $this->activeUser = $this->manager->get($uid);
- return $this->activeUser;
- } else {
- return null;
- }
- }
- }
-
- /**
- * Checks whether the user is logged in
- *
- * @return bool if logged in
- */
- public function isLoggedIn() {
- return $this->getUser() !== null;
- }
-
- /**
- * set the login name
- *
- * @param string|null $loginName for the logged in user
- */
- public function setLoginName($loginName) {
- if (is_null($loginName)) {
- $this->session->remove('loginname');
- } else {
- $this->session->set('loginname', $loginName);
- }
- }
-
- /**
- * get the login name of the current user
- *
- * @return string
- */
- public function getLoginName() {
- if ($this->activeUser) {
- return $this->session->get('loginname');
- } else {
- $uid = $this->session->get('user_id');
- if ($uid) {
- $this->activeUser = $this->manager->get($uid);
- return $this->session->get('loginname');
- } else {
- return null;
- }
- }
- }
-
- /**
- * try to login with the provided credentials
- *
- * @param string $uid
- * @param string $password
- * @return boolean|null
- * @throws LoginException
- */
- public function login($uid, $password) {
- $this->session->regenerateId();
- $this->manager->emit('\OC\User', 'preLogin', array($uid, $password));
- $user = $this->manager->checkPassword($uid, $password);
- if ($user !== false) {
- if (!is_null($user)) {
- if ($user->isEnabled()) {
- $this->setUser($user);
- $this->setLoginName($uid);
- $this->manager->emit('\OC\User', 'postLogin', array($user, $password));
- if ($this->isLoggedIn()) {
- return true;
- } else {
- throw new LoginException('Login canceled by app');
- }
- } else {
- return false;
- }
- }
- } else {
- return false;
- }
- }
-
- /**
- * perform login using the magic cookie (remember login)
- *
- * @param string $uid the username
- * @param string $currentToken
- * @return bool
- */
- public function loginWithCookie($uid, $currentToken) {
- $this->session->regenerateId();
- $this->manager->emit('\OC\User', 'preRememberedLogin', array($uid));
- $user = $this->manager->get($uid);
- if (is_null($user)) {
- // user does not exist
- return false;
- }
-
- // get stored tokens
- $tokens = \OC::$server->getConfig()->getUserKeys($uid, 'login_token');
- // test cookies token against stored tokens
- if (!in_array($currentToken, $tokens, true)) {
- return false;
- }
- // replace successfully used token with a new one
- \OC::$server->getConfig()->deleteUserValue($uid, 'login_token', $currentToken);
- $newToken = \OC::$server->getSecureRandom()->generate(32);
- \OC::$server->getConfig()->setUserValue($uid, 'login_token', $newToken, time());
- $this->setMagicInCookie($user->getUID(), $newToken);
-
- //login
- $this->setUser($user);
- $this->manager->emit('\OC\User', 'postRememberedLogin', array($user));
- return true;
- }
-
- /**
- * logout the user from the session
- */
- public function logout() {
- $this->manager->emit('\OC\User', 'logout');
- $this->setUser(null);
- $this->setLoginName(null);
- $this->unsetMagicInCookie();
- $this->session->clear();
- }
-
- /**
- * Set cookie value to use in next page load
- *
- * @param string $username username to be set
- * @param string $token
- */
- public function setMagicInCookie($username, $token) {
- $secureCookie = \OC::$server->getRequest()->getServerProtocol() === 'https';
- $expires = time() + \OC::$server->getConfig()->getSystemValue('remember_login_cookie_lifetime', 60 * 60 * 24 * 15);
- setcookie("oc_username", $username, $expires, \OC::$WEBROOT, '', $secureCookie, true);
- setcookie("oc_token", $token, $expires, \OC::$WEBROOT, '', $secureCookie, true);
- setcookie("oc_remember_login", "1", $expires, \OC::$WEBROOT, '', $secureCookie, true);
- }
-
- /**
- * Remove cookie for "remember username"
- */
- public function unsetMagicInCookie() {
- //TODO: DI for cookies and IRequest
- $secureCookie = \OC::$server->getRequest()->getServerProtocol() === 'https';
-
- unset($_COOKIE["oc_username"]); //TODO: DI
- unset($_COOKIE["oc_token"]);
- unset($_COOKIE["oc_remember_login"]);
- setcookie('oc_username', '', time() - 3600, \OC::$WEBROOT, '',$secureCookie, true);
- setcookie('oc_token', '', time() - 3600, \OC::$WEBROOT, '', $secureCookie, true);
- setcookie('oc_remember_login', '', time() - 3600, \OC::$WEBROOT, '', $secureCookie, true);
- // old cookies might be stored under /webroot/ instead of /webroot
- // and Firefox doesn't like it!
- setcookie('oc_username', '', time() - 3600, \OC::$WEBROOT . '/', '', $secureCookie, true);
- setcookie('oc_token', '', time() - 3600, \OC::$WEBROOT . '/', '', $secureCookie, true);
- setcookie('oc_remember_login', '', time() - 3600, \OC::$WEBROOT . '/', '', $secureCookie, true);
- }
-}