summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/autoloader.php12
-rw-r--r--lib/base.php8
-rw-r--r--lib/l10n/cs_CZ.js12
-rw-r--r--lib/l10n/cs_CZ.json12
-rw-r--r--lib/l10n/de.js4
-rw-r--r--lib/l10n/de.json4
-rw-r--r--lib/l10n/de_DE.js4
-rw-r--r--lib/l10n/de_DE.json4
-rw-r--r--lib/l10n/es.js4
-rw-r--r--lib/l10n/es.json4
-rw-r--r--lib/l10n/fi_FI.js4
-rw-r--r--lib/l10n/fi_FI.json4
-rw-r--r--lib/l10n/it.js4
-rw-r--r--lib/l10n/it.json4
-rw-r--r--lib/private/AppFramework/Db/Db.php17
-rw-r--r--lib/private/Authentication/Token/DefaultTokenMapper.php28
-rw-r--r--lib/private/Authentication/Token/DefaultTokenProvider.php14
-rw-r--r--lib/private/Authentication/Token/IProvider.php12
-rw-r--r--lib/private/BackgroundJob/JobList.php86
-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/Files/Cache/Scanner.php47
-rw-r--r--lib/private/OCS/Provider.php96
-rw-r--r--lib/private/Server.php6
-rw-r--r--lib/private/Share20/DefaultShareProvider.php2
-rw-r--r--lib/private/Share20/Manager.php15
-rw-r--r--lib/private/Share20/ProviderFactory.php3
-rw-r--r--lib/private/Share20/Share.php17
-rw-r--r--lib/private/SystemTag/ManagerFactory.php1
-rw-r--r--lib/private/SystemTag/SystemTagManager.php113
-rw-r--r--lib/private/User/Session.php4
-rw-r--r--lib/public/API.php (renamed from lib/public/api.php)0
-rw-r--r--lib/public/App.php (renamed from lib/public/app.php)0
-rw-r--r--lib/public/AutoloadNotAllowedException.php (renamed from lib/public/autoloadnotallowedexception.php)0
-rw-r--r--lib/public/BackgroundJob.php (renamed from lib/public/backgroundjob.php)0
-rw-r--r--lib/public/BackgroundJob/IJobList.php11
-rw-r--r--lib/public/Comments/CommentsEntityEvent.php76
-rw-r--r--lib/public/Config.php (renamed from lib/public/config.php)0
-rw-r--r--lib/public/Constants.php (renamed from lib/public/constants.php)0
-rw-r--r--lib/public/Contacts.php (renamed from lib/public/contacts.php)0
-rw-r--r--lib/public/DB.php (renamed from lib/public/db.php)0
-rw-r--r--lib/public/Defaults.php (renamed from lib/public/defaults.php)0
-rw-r--r--lib/public/Files.php (renamed from lib/public/files.php)0
-rw-r--r--lib/public/GroupInterface.php (renamed from lib/public/groupinterface.php)0
-rw-r--r--lib/public/IAddressBook.php (renamed from lib/public/iaddressbook.php)0
-rw-r--r--lib/public/IAppConfig.php (renamed from lib/public/iappconfig.php)0
-rw-r--r--lib/public/IAvatar.php (renamed from lib/public/iavatar.php)0
-rw-r--r--lib/public/IAvatarManager.php (renamed from lib/public/iavatarmanager.php)0
-rw-r--r--lib/public/ICache.php (renamed from lib/public/icache.php)0
-rw-r--r--lib/public/ICacheFactory.php (renamed from lib/public/icachefactory.php)0
-rw-r--r--lib/public/ICertificate.php (renamed from lib/public/icertificate.php)0
-rw-r--r--lib/public/ICertificateManager.php (renamed from lib/public/icertificatemanager.php)0
-rw-r--r--lib/public/IConfig.php (renamed from lib/public/iconfig.php)0
-rw-r--r--lib/public/IContainer.php (renamed from lib/public/icontainer.php)0
-rw-r--r--lib/public/IDBConnection.php (renamed from lib/public/idbconnection.php)19
-rw-r--r--lib/public/IDateTimeFormatter.php (renamed from lib/public/idatetimeformatter.php)0
-rw-r--r--lib/public/IDateTimeZone.php (renamed from lib/public/idatetimezone.php)0
-rw-r--r--lib/public/IDb.php (renamed from lib/public/idb.php)0
-rw-r--r--lib/public/IEventSource.php (renamed from lib/public/ieventsource.php)0
-rw-r--r--lib/public/IGroup.php (renamed from lib/public/igroup.php)0
-rw-r--r--lib/public/IGroupManager.php (renamed from lib/public/igroupmanager.php)0
-rw-r--r--lib/public/IHelper.php (renamed from lib/public/ihelper.php)0
-rw-r--r--lib/public/IImage.php (renamed from lib/public/iimage.php)0
-rw-r--r--lib/public/IL10N.php (renamed from lib/public/il10n.php)0
-rw-r--r--lib/public/ILogger.php (renamed from lib/public/ilogger.php)0
-rw-r--r--lib/public/IMemcache.php (renamed from lib/public/imemcache.php)0
-rw-r--r--lib/public/IMemcacheTTL.php (renamed from lib/public/imemcachettl.php)0
-rw-r--r--lib/public/INavigationManager.php (renamed from lib/public/inavigationmanager.php)0
-rw-r--r--lib/public/IPreview.php (renamed from lib/public/ipreview.php)0
-rw-r--r--lib/public/IRequest.php (renamed from lib/public/irequest.php)0
-rw-r--r--lib/public/ISearch.php (renamed from lib/public/isearch.php)0
-rw-r--r--lib/public/ISession.php (renamed from lib/public/isession.php)0
-rw-r--r--lib/public/ITagManager.php (renamed from lib/public/itagmanager.php)0
-rw-r--r--lib/public/ITags.php (renamed from lib/public/itags.php)0
-rw-r--r--lib/public/ITempManager.php (renamed from lib/public/itempmanager.php)0
-rw-r--r--lib/public/IURLGenerator.php (renamed from lib/public/iurlgenerator.php)0
-rw-r--r--lib/public/IUser.php (renamed from lib/public/iuser.php)0
-rw-r--r--lib/public/IUserBackend.php (renamed from lib/public/iuserbackend.php)0
-rw-r--r--lib/public/IUserManager.php (renamed from lib/public/iusermanager.php)0
-rw-r--r--lib/public/IUserSession.php (renamed from lib/public/iusersession.php)0
-rw-r--r--lib/public/Image.php (renamed from lib/public/image.php)0
-rw-r--r--lib/public/JSON.php (renamed from lib/public/json.php)0
-rw-r--r--lib/public/Lock/ILockingProvider.php (renamed from lib/public/lock/ilockingprovider.php)0
-rw-r--r--lib/public/Lock/LockedException.php (renamed from lib/public/lock/lockedexception.php)0
-rw-r--r--lib/public/Mail/IMailer.php (renamed from lib/public/mail/imailer.php)0
-rw-r--r--lib/public/Migration/IOutput.php (renamed from lib/public/migration/ioutput.php)0
-rw-r--r--lib/public/Migration/IRepairStep.php (renamed from lib/public/migration/irepairstep.php)0
-rw-r--r--lib/public/Notification/IAction.php (renamed from lib/public/notification/iaction.php)0
-rw-r--r--lib/public/Notification/IApp.php (renamed from lib/public/notification/iapp.php)0
-rw-r--r--lib/public/Notification/IManager.php (renamed from lib/public/notification/imanager.php)0
-rw-r--r--lib/public/Notification/INotification.php (renamed from lib/public/notification/inotification.php)0
-rw-r--r--lib/public/Notification/INotifier.php (renamed from lib/public/notification/inotifier.php)0
-rw-r--r--lib/public/PreConditionNotMetException.php (renamed from lib/public/preconditionnotmetexception.php)0
-rw-r--r--lib/public/Preview/IProvider.php (renamed from lib/public/preview/iprovider.php)0
-rw-r--r--lib/public/Response.php (renamed from lib/public/response.php)0
-rw-r--r--lib/public/Route/IRoute.php (renamed from lib/public/route/iroute.php)0
-rw-r--r--lib/public/Route/IRouter.php (renamed from lib/public/route/irouter.php)0
-rw-r--r--lib/public/SabrePluginEvent.php (renamed from lib/public/sabrepluginevent.php)0
-rw-r--r--lib/public/SabrePluginException.php (renamed from lib/public/sabrepluginexception.php)0
-rw-r--r--lib/public/Security/IContentSecurityPolicyManager.php (renamed from lib/public/security/icontentsecuritypolicymanager.php)0
-rw-r--r--lib/public/Security/ICredentialsManager.php (renamed from lib/public/security/icredentialsmanager.php)0
-rw-r--r--lib/public/Security/ICrypto.php (renamed from lib/public/security/icrypto.php)0
-rw-r--r--lib/public/Security/IHasher.php (renamed from lib/public/security/ihasher.php)0
-rw-r--r--lib/public/Security/ISecureRandom.php (renamed from lib/public/security/isecurerandom.php)0
-rw-r--r--lib/public/Security/StringUtils.php (renamed from lib/public/security/stringutils.php)0
-rw-r--r--lib/public/Share.php (renamed from lib/public/share.php)0
-rw-r--r--lib/public/Share_Backend.php (renamed from lib/public/share_backend.php)0
-rw-r--r--lib/public/Share_Backend_Collection.php (renamed from lib/public/share_backend_collection.php)0
-rw-r--r--lib/public/Share_Backend_File_Dependent.php (renamed from lib/public/share_backend_file_dependent.php)0
-rw-r--r--lib/public/SystemTag/ISystemTag.php (renamed from lib/public/systemtag/isystemtag.php)0
-rw-r--r--lib/public/SystemTag/ISystemTagManager.php (renamed from lib/public/systemtag/isystemtagmanager.php)48
-rw-r--r--lib/public/SystemTag/ISystemTagManagerFactory.php (renamed from lib/public/systemtag/isystemtagmanagerfactory.php)0
-rw-r--r--lib/public/SystemTag/ISystemTagObjectMapper.php (renamed from lib/public/systemtag/isystemtagobjectmapper.php)0
-rw-r--r--lib/public/SystemTag/ManagerEvent.php (renamed from lib/public/systemtag/managerevent.php)0
-rw-r--r--lib/public/SystemTag/MapperEvent.php (renamed from lib/public/systemtag/mapperevent.php)0
-rw-r--r--lib/public/SystemTag/TagAlreadyExistsException.php (renamed from lib/public/systemtag/tagalreadyexistsexception.php)0
-rw-r--r--lib/public/SystemTag/TagNotFoundException.php (renamed from lib/public/systemtag/tagnotfoundexception.php)0
-rw-r--r--lib/public/Template.php (renamed from lib/public/template.php)0
-rw-r--r--lib/public/User.php (renamed from lib/public/user.php)0
-rw-r--r--lib/public/UserInterface.php (renamed from lib/public/userinterface.php)0
-rw-r--r--lib/public/Util.php (renamed from lib/public/util.php)0
123 files changed, 677 insertions, 104 deletions
diff --git a/lib/autoloader.php b/lib/autoloader.php
index 9cc573c0997..89b66a426a7 100644
--- a/lib/autoloader.php
+++ b/lib/autoloader.php
@@ -94,7 +94,7 @@ class Autoloader {
$paths[] = \OC::$CLASSPATH[$class];
/**
* @TODO: Remove this when necessary
- * Remove "apps/" from inclusion path for smooth migration to mutli app dir
+ * Remove "apps/" from inclusion path for smooth migration to multi app dir
*/
if (strpos(\OC::$CLASSPATH[$class], 'apps/') === 0) {
\OCP\Util::writeLog('core', 'include path for class "' . $class . '" starts with "apps/"', \OCP\Util::DEBUG);
@@ -102,8 +102,6 @@ class Autoloader {
}
} elseif (strpos($class, 'OC_') === 0) {
$paths[] = \OC::$SERVERROOT . '/lib/private/legacy/' . strtolower(str_replace('_', '/', substr($class, 3)) . '.php');
- } elseif (strpos($class, 'OCP\\') === 0) {
- $paths[] = \OC::$SERVERROOT . '/lib/public/' . strtolower(str_replace('\\', '/', substr($class, 4)) . '.php');
} elseif (strpos($class, 'OCA\\') === 0) {
list(, $app, $rest) = explode('\\', $class, 3);
$app = strtolower($app);
@@ -113,10 +111,10 @@ class Autoloader {
// If not found in the root of the app directory, insert '/lib' after app id and try again.
$paths[] = $appPath . '/lib/' . strtolower(str_replace('\\', '/', $rest) . '.php');
}
- } elseif (strpos($class, 'Test_') === 0) {
- $paths[] = \OC::$SERVERROOT . '/tests/lib/' . strtolower(str_replace('_', '/', substr($class, 5)) . '.php');
- } elseif (strpos($class, 'Test\\') === 0) {
- $paths[] = \OC::$SERVERROOT . '/tests/lib/' . strtolower(str_replace('\\', '/', substr($class, 5)) . '.php');
+ } elseif ($class === 'Test\\TestCase') {
+ // This File is considered public API, so we make sure that the class
+ // can still be loaded, although the PSR-4 paths have not been loaded.
+ $paths[] = \OC::$SERVERROOT . '/tests/lib/TestCase.php';
}
return $paths;
}
diff --git a/lib/base.php b/lib/base.php
index 1fdcf44f4d0..391bcf865a0 100644
--- a/lib/base.php
+++ b/lib/base.php
@@ -53,7 +53,7 @@
*
*/
-require_once 'public/constants.php';
+require_once 'public/Constants.php';
/**
* Class that is a namespace for all global OC variables
@@ -481,11 +481,7 @@ class OC {
$loaderStart = microtime(true);
require_once __DIR__ . '/autoloader.php';
self::$loader = new \OC\Autoloader([
- OC::$SERVERROOT . '/lib',
- OC::$SERVERROOT . '/core',
- OC::$SERVERROOT . '/settings',
- OC::$SERVERROOT . '/ocs',
- OC::$SERVERROOT . '/ocs-provider',
+ OC::$SERVERROOT . '/lib/private/legacy',
]);
if (defined('PHPUNIT_RUN')) {
self::$loader->addValidRoot(OC::$SERVERROOT . '/tests');
diff --git a/lib/l10n/cs_CZ.js b/lib/l10n/cs_CZ.js
index 9614eeef125..8074111faed 100644
--- a/lib/l10n/cs_CZ.js
+++ b/lib/l10n/cs_CZ.js
@@ -9,7 +9,7 @@ OC.L10N.register(
"It has been detected that the sample configuration has been copied. This can break your installation and is unsupported. Please read the documentation before performing changes on config.php" : "Pravděpodobně byla zkopírována konfigurační nastavení ze vzorových souborů. Toto není podporováno a může poškodit vaši instalaci. Nahlédněte prosím do dokumentace před prováděním změn v souboru config.php",
"PHP %s or higher is required." : "Je vyžadováno PHP %s nebo vyšší.",
"PHP with a version lower than %s is required." : "Je vyžadováno PHP ve verzi nižší než %s.",
- "%sbit or higher PHP required." : "Je vyžadováno PHP %s nebo vyšší.",
+ "%sbit or higher PHP required." : "Je vyžadováno PHP %sbit nebo vyšší.",
"Following databases are supported: %s" : "Jsou podporovány následující databáze: %s",
"The command line tool %s could not be found" : "Nástroj příkazového řádku %s nebyl nalezen",
"The library %s is not available." : "Knihovna %s není dostupná.",
@@ -38,7 +38,7 @@ OC.L10N.register(
"File name contains at least one invalid character" : "Jméno souboru obsahuje nejméně jeden neplatný znak",
"File name is too long" : "Jméno souboru je moc dlouhé",
"App directory already exists" : "Adresář aplikace již existuje",
- "Can't create app folder. Please fix permissions. %s" : "Nelze vytvořit složku aplikace. Opravte práva souborů. %s",
+ "Can't create app folder. Please fix permissions. %s" : "Nelze vytvořit adresář aplikace. Opravte práva souborů. %s",
"Archive does not contain a directory named %s" : "Archiv neobsahuje adresář pojmenovaný %s",
"No source specified when installing app" : "Nebyl zadán zdroj při instalaci aplikace",
"No href specified when installing app from http" : "Nebyl zadán odkaz pro instalaci aplikace z HTTP",
@@ -102,7 +102,7 @@ OC.L10N.register(
"Sharing %s failed, because the sharing backend for %s could not find its source" : "Sdílení položky %s selhalo, protože úložiště sdílení %s nenalezla zdroj",
"Sharing %s failed, because the file could not be found in the file cache" : "Sdílení položky %s selhalo, protože soubor nebyl nalezen ve vyrovnávací paměti",
"Cannot increase permissions of %s" : "Nelze navýšit oprávnění u %s",
- "Files can't be shared with delete permissions" : "Soubory nelze sdílet se smazanými oprávněními",
+ "Files can't be shared with delete permissions" : "Soubory nelze sdílet s oprávněními ke smazání",
"Files can't be shared with create permissions" : "Soubory nelze sdílet s vytvořenými oprávněními",
"Expiration date is in the past" : "Datum vypršení je v minulosti",
"Cannot set expiration date more than %s days in the future" : "Datum vypršení nelze nastavit na více než %s dní do budoucnosti",
@@ -138,7 +138,7 @@ OC.L10N.register(
"Cannot write into \"apps\" directory" : "Nelze zapisovat do adresáře \"apps\"",
"This can usually be fixed by %sgiving the webserver write access to the apps directory%s or disabling the appstore in the config file." : "To lze obvykle vyřešit %spovolením zápisu webovému serveru do adresáře apps%s nebo zakázáním appstore v konfiguračním souboru.",
"Cannot create \"data\" directory (%s)" : "Nelze vytvořit adresář \"data\" (%s)",
- "This can usually be fixed by <a href=\"%s\" target=\"_blank\" rel=\"noreferrer\">giving the webserver write access to the root directory</a>." : "Toto může být obvykle opraveno <a href=\"%s\" target=\"_blank\" rel=\"noreferrer\">nastavením přístupových práv webového serveru pro zápis do kořenové složky</a>.",
+ "This can usually be fixed by <a href=\"%s\" target=\"_blank\" rel=\"noreferrer\">giving the webserver write access to the root directory</a>." : "Toto může být obvykle opraveno <a href=\"%s\" target=\"_blank\" rel=\"noreferrer\">nastavením přístupových práv webového serveru pro zápis do kořenového adresáře</a>.",
"Permissions can usually be fixed by %sgiving the webserver write access to the root directory%s." : "Oprávnění lze obvykle napravit %spovolením zápisu webovému serveru do kořenového adresáře%s.",
"Setting locale to %s failed" : "Nastavení jazyka na %s selhalo",
"Please install one of these locales on your system and restart your webserver." : "Prosím nainstalujte alespoň jeden z těchto jazyků do svého systému a restartujte webový server.",
@@ -167,6 +167,8 @@ OC.L10N.register(
"Storage incomplete configuration. %s" : "Nekompletní konfigurace úložiště. %s",
"Storage connection error. %s" : "Chyba připojení úložiště. %s",
"Storage not available" : "Úložiště není dostupné",
- "Storage connection timeout. %s" : "Vypršení připojení k úložišti. %s"
+ "Storage connection timeout. %s" : "Vypršení připojení k úložišti. %s",
+ "_%n file_::_%n files_" : ["%n soubor","%n soubory","%n souborů"],
+ "_%n window_::_%n windows_" : ["%n okno","%n okna","%n oken"]
},
"nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;");
diff --git a/lib/l10n/cs_CZ.json b/lib/l10n/cs_CZ.json
index 50eb92efea6..1657a4b2dc0 100644
--- a/lib/l10n/cs_CZ.json
+++ b/lib/l10n/cs_CZ.json
@@ -7,7 +7,7 @@
"It has been detected that the sample configuration has been copied. This can break your installation and is unsupported. Please read the documentation before performing changes on config.php" : "Pravděpodobně byla zkopírována konfigurační nastavení ze vzorových souborů. Toto není podporováno a může poškodit vaši instalaci. Nahlédněte prosím do dokumentace před prováděním změn v souboru config.php",
"PHP %s or higher is required." : "Je vyžadováno PHP %s nebo vyšší.",
"PHP with a version lower than %s is required." : "Je vyžadováno PHP ve verzi nižší než %s.",
- "%sbit or higher PHP required." : "Je vyžadováno PHP %s nebo vyšší.",
+ "%sbit or higher PHP required." : "Je vyžadováno PHP %sbit nebo vyšší.",
"Following databases are supported: %s" : "Jsou podporovány následující databáze: %s",
"The command line tool %s could not be found" : "Nástroj příkazového řádku %s nebyl nalezen",
"The library %s is not available." : "Knihovna %s není dostupná.",
@@ -36,7 +36,7 @@
"File name contains at least one invalid character" : "Jméno souboru obsahuje nejméně jeden neplatný znak",
"File name is too long" : "Jméno souboru je moc dlouhé",
"App directory already exists" : "Adresář aplikace již existuje",
- "Can't create app folder. Please fix permissions. %s" : "Nelze vytvořit složku aplikace. Opravte práva souborů. %s",
+ "Can't create app folder. Please fix permissions. %s" : "Nelze vytvořit adresář aplikace. Opravte práva souborů. %s",
"Archive does not contain a directory named %s" : "Archiv neobsahuje adresář pojmenovaný %s",
"No source specified when installing app" : "Nebyl zadán zdroj při instalaci aplikace",
"No href specified when installing app from http" : "Nebyl zadán odkaz pro instalaci aplikace z HTTP",
@@ -100,7 +100,7 @@
"Sharing %s failed, because the sharing backend for %s could not find its source" : "Sdílení položky %s selhalo, protože úložiště sdílení %s nenalezla zdroj",
"Sharing %s failed, because the file could not be found in the file cache" : "Sdílení položky %s selhalo, protože soubor nebyl nalezen ve vyrovnávací paměti",
"Cannot increase permissions of %s" : "Nelze navýšit oprávnění u %s",
- "Files can't be shared with delete permissions" : "Soubory nelze sdílet se smazanými oprávněními",
+ "Files can't be shared with delete permissions" : "Soubory nelze sdílet s oprávněními ke smazání",
"Files can't be shared with create permissions" : "Soubory nelze sdílet s vytvořenými oprávněními",
"Expiration date is in the past" : "Datum vypršení je v minulosti",
"Cannot set expiration date more than %s days in the future" : "Datum vypršení nelze nastavit na více než %s dní do budoucnosti",
@@ -136,7 +136,7 @@
"Cannot write into \"apps\" directory" : "Nelze zapisovat do adresáře \"apps\"",
"This can usually be fixed by %sgiving the webserver write access to the apps directory%s or disabling the appstore in the config file." : "To lze obvykle vyřešit %spovolením zápisu webovému serveru do adresáře apps%s nebo zakázáním appstore v konfiguračním souboru.",
"Cannot create \"data\" directory (%s)" : "Nelze vytvořit adresář \"data\" (%s)",
- "This can usually be fixed by <a href=\"%s\" target=\"_blank\" rel=\"noreferrer\">giving the webserver write access to the root directory</a>." : "Toto může být obvykle opraveno <a href=\"%s\" target=\"_blank\" rel=\"noreferrer\">nastavením přístupových práv webového serveru pro zápis do kořenové složky</a>.",
+ "This can usually be fixed by <a href=\"%s\" target=\"_blank\" rel=\"noreferrer\">giving the webserver write access to the root directory</a>." : "Toto může být obvykle opraveno <a href=\"%s\" target=\"_blank\" rel=\"noreferrer\">nastavením přístupových práv webového serveru pro zápis do kořenového adresáře</a>.",
"Permissions can usually be fixed by %sgiving the webserver write access to the root directory%s." : "Oprávnění lze obvykle napravit %spovolením zápisu webovému serveru do kořenového adresáře%s.",
"Setting locale to %s failed" : "Nastavení jazyka na %s selhalo",
"Please install one of these locales on your system and restart your webserver." : "Prosím nainstalujte alespoň jeden z těchto jazyků do svého systému a restartujte webový server.",
@@ -165,6 +165,8 @@
"Storage incomplete configuration. %s" : "Nekompletní konfigurace úložiště. %s",
"Storage connection error. %s" : "Chyba připojení úložiště. %s",
"Storage not available" : "Úložiště není dostupné",
- "Storage connection timeout. %s" : "Vypršení připojení k úložišti. %s"
+ "Storage connection timeout. %s" : "Vypršení připojení k úložišti. %s",
+ "_%n file_::_%n files_" : ["%n soubor","%n soubory","%n souborů"],
+ "_%n window_::_%n windows_" : ["%n okno","%n okna","%n oken"]
},"pluralForm" :"nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;"
} \ No newline at end of file
diff --git a/lib/l10n/de.js b/lib/l10n/de.js
index ac65d37ecba..74f845ba6d9 100644
--- a/lib/l10n/de.js
+++ b/lib/l10n/de.js
@@ -167,6 +167,8 @@ OC.L10N.register(
"Storage incomplete configuration. %s" : "Unvollständige Konfiguration des Storage. %s",
"Storage connection error. %s" : "Verbindungsfehler zum Storage. %s",
"Storage not available" : "Speicher nicht verfügbar",
- "Storage connection timeout. %s" : "Zeitüberschreitung der Verbindung zum Storage. %s"
+ "Storage connection timeout. %s" : "Zeitüberschreitung der Verbindung zum Storage. %s",
+ "_%n file_::_%n files_" : ["%n Datei","%n Dateien"],
+ "_%n window_::_%n windows_" : ["%n Fenster","%n Fenster"]
},
"nplurals=2; plural=(n != 1);");
diff --git a/lib/l10n/de.json b/lib/l10n/de.json
index 97a5b59fea3..65bd3e97edf 100644
--- a/lib/l10n/de.json
+++ b/lib/l10n/de.json
@@ -165,6 +165,8 @@
"Storage incomplete configuration. %s" : "Unvollständige Konfiguration des Storage. %s",
"Storage connection error. %s" : "Verbindungsfehler zum Storage. %s",
"Storage not available" : "Speicher nicht verfügbar",
- "Storage connection timeout. %s" : "Zeitüberschreitung der Verbindung zum Storage. %s"
+ "Storage connection timeout. %s" : "Zeitüberschreitung der Verbindung zum Storage. %s",
+ "_%n file_::_%n files_" : ["%n Datei","%n Dateien"],
+ "_%n window_::_%n windows_" : ["%n Fenster","%n Fenster"]
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/lib/l10n/de_DE.js b/lib/l10n/de_DE.js
index ab4fa068c47..5e9900fd395 100644
--- a/lib/l10n/de_DE.js
+++ b/lib/l10n/de_DE.js
@@ -167,6 +167,8 @@ OC.L10N.register(
"Storage incomplete configuration. %s" : "Speicher-Konfiguration unvollständig. %s",
"Storage connection error. %s" : "Speicher-Verbindungsfehler. %s",
"Storage not available" : "Speicher nicht verfügbar",
- "Storage connection timeout. %s" : "Speicher-Verbindungszeitüberschreitung. %s"
+ "Storage connection timeout. %s" : "Speicher-Verbindungszeitüberschreitung. %s",
+ "_%n file_::_%n files_" : ["%n Datei","%n Dateien"],
+ "_%n window_::_%n windows_" : ["%n Fenster","%n Fenster"]
},
"nplurals=2; plural=(n != 1);");
diff --git a/lib/l10n/de_DE.json b/lib/l10n/de_DE.json
index 8d3fe907524..5d0114eadf1 100644
--- a/lib/l10n/de_DE.json
+++ b/lib/l10n/de_DE.json
@@ -165,6 +165,8 @@
"Storage incomplete configuration. %s" : "Speicher-Konfiguration unvollständig. %s",
"Storage connection error. %s" : "Speicher-Verbindungsfehler. %s",
"Storage not available" : "Speicher nicht verfügbar",
- "Storage connection timeout. %s" : "Speicher-Verbindungszeitüberschreitung. %s"
+ "Storage connection timeout. %s" : "Speicher-Verbindungszeitüberschreitung. %s",
+ "_%n file_::_%n files_" : ["%n Datei","%n Dateien"],
+ "_%n window_::_%n windows_" : ["%n Fenster","%n Fenster"]
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/lib/l10n/es.js b/lib/l10n/es.js
index 9e108b52ec7..dbf8ba89b48 100644
--- a/lib/l10n/es.js
+++ b/lib/l10n/es.js
@@ -167,6 +167,8 @@ OC.L10N.register(
"Storage incomplete configuration. %s" : "Configuración de almacenamiento incompleta. %s",
"Storage connection error. %s" : "Error de conexión de almacenamiento. %s",
"Storage not available" : "Almacenamiento no disponible",
- "Storage connection timeout. %s" : "Tiempo de conexión de almacenamiento agotado. %s"
+ "Storage connection timeout. %s" : "Tiempo de conexión de almacenamiento agotado. %s",
+ "_%n file_::_%n files_" : ["%n archivo","%n archivos"],
+ "_%n window_::_%n windows_" : ["%n window","%n windows"]
},
"nplurals=2; plural=(n != 1);");
diff --git a/lib/l10n/es.json b/lib/l10n/es.json
index 36f8a63c317..723d8699949 100644
--- a/lib/l10n/es.json
+++ b/lib/l10n/es.json
@@ -165,6 +165,8 @@
"Storage incomplete configuration. %s" : "Configuración de almacenamiento incompleta. %s",
"Storage connection error. %s" : "Error de conexión de almacenamiento. %s",
"Storage not available" : "Almacenamiento no disponible",
- "Storage connection timeout. %s" : "Tiempo de conexión de almacenamiento agotado. %s"
+ "Storage connection timeout. %s" : "Tiempo de conexión de almacenamiento agotado. %s",
+ "_%n file_::_%n files_" : ["%n archivo","%n archivos"],
+ "_%n window_::_%n windows_" : ["%n window","%n windows"]
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/lib/l10n/fi_FI.js b/lib/l10n/fi_FI.js
index 11e50686a15..b82b6a7b513 100644
--- a/lib/l10n/fi_FI.js
+++ b/lib/l10n/fi_FI.js
@@ -146,6 +146,8 @@ OC.L10N.register(
"Storage incomplete configuration. %s" : "Tallennustilan puutteellinen määritys. %s",
"Storage connection error. %s" : "Tallennustilan yhteysvirhe. %s",
"Storage not available" : "Tallennustila ei ole käytettävissä",
- "Storage connection timeout. %s" : "Tallennustilan yhteyden aikakatkaisu. %s"
+ "Storage connection timeout. %s" : "Tallennustilan yhteyden aikakatkaisu. %s",
+ "_%n file_::_%n files_" : ["%n tiedosto","%n tiedostoa"],
+ "_%n window_::_%n windows_" : ["%n ikkuna","%n ikkunaa"]
},
"nplurals=2; plural=(n != 1);");
diff --git a/lib/l10n/fi_FI.json b/lib/l10n/fi_FI.json
index f1c35d271f2..4bdddef1c57 100644
--- a/lib/l10n/fi_FI.json
+++ b/lib/l10n/fi_FI.json
@@ -144,6 +144,8 @@
"Storage incomplete configuration. %s" : "Tallennustilan puutteellinen määritys. %s",
"Storage connection error. %s" : "Tallennustilan yhteysvirhe. %s",
"Storage not available" : "Tallennustila ei ole käytettävissä",
- "Storage connection timeout. %s" : "Tallennustilan yhteyden aikakatkaisu. %s"
+ "Storage connection timeout. %s" : "Tallennustilan yhteyden aikakatkaisu. %s",
+ "_%n file_::_%n files_" : ["%n tiedosto","%n tiedostoa"],
+ "_%n window_::_%n windows_" : ["%n ikkuna","%n ikkunaa"]
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/lib/l10n/it.js b/lib/l10n/it.js
index ca940ac94c5..fbc26530db4 100644
--- a/lib/l10n/it.js
+++ b/lib/l10n/it.js
@@ -167,6 +167,8 @@ OC.L10N.register(
"Storage incomplete configuration. %s" : "Configurazione dell'archiviazione incompleta.%s",
"Storage connection error. %s" : "Errore di connessione all'archiviazione. %s",
"Storage not available" : "Archiviazione non disponibile",
- "Storage connection timeout. %s" : "Timeout di connessione all'archiviazione. %s"
+ "Storage connection timeout. %s" : "Timeout di connessione all'archiviazione. %s",
+ "_%n file_::_%n files_" : ["%n file","%n file"],
+ "_%n window_::_%n windows_" : ["%n finestra","%n finestre"]
},
"nplurals=2; plural=(n != 1);");
diff --git a/lib/l10n/it.json b/lib/l10n/it.json
index f74f2e818ab..3955bf27508 100644
--- a/lib/l10n/it.json
+++ b/lib/l10n/it.json
@@ -165,6 +165,8 @@
"Storage incomplete configuration. %s" : "Configurazione dell'archiviazione incompleta.%s",
"Storage connection error. %s" : "Errore di connessione all'archiviazione. %s",
"Storage not available" : "Archiviazione non disponibile",
- "Storage connection timeout. %s" : "Timeout di connessione all'archiviazione. %s"
+ "Storage connection timeout. %s" : "Timeout di connessione all'archiviazione. %s",
+ "_%n file_::_%n files_" : ["%n file","%n file"],
+ "_%n window_::_%n windows_" : ["%n finestra","%n finestre"]
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
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/Authentication/Token/DefaultTokenMapper.php b/lib/private/Authentication/Token/DefaultTokenMapper.php
index 18adbe48d78..9f173571270 100644
--- a/lib/private/Authentication/Token/DefaultTokenMapper.php
+++ b/lib/private/Authentication/Token/DefaultTokenMapper.php
@@ -26,6 +26,7 @@ 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 {
@@ -83,4 +84,31 @@ class DefaultTokenMapper extends Mapper {
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
index a335b79e332..6c69d852d7b 100644
--- a/lib/private/Authentication/Token/DefaultTokenProvider.php
+++ b/lib/private/Authentication/Token/DefaultTokenProvider.php
@@ -28,6 +28,7 @@ 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 {
@@ -103,6 +104,19 @@ class DefaultTokenProvider implements IProvider {
}
/**
+ * 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
diff --git a/lib/private/Authentication/Token/IProvider.php b/lib/private/Authentication/Token/IProvider.php
index 1fd3a70fbbf..a5c5faa5639 100644
--- a/lib/private/Authentication/Token/IProvider.php
+++ b/lib/private/Authentication/Token/IProvider.php
@@ -23,6 +23,7 @@
namespace OC\Authentication\Token;
use OC\Authentication\Exceptions\InvalidTokenException;
+use OCP\IUser;
interface IProvider {
@@ -69,6 +70,17 @@ interface IProvider {
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
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/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/Files/Cache/Scanner.php b/lib/private/Files/Cache/Scanner.php
index 03aca1924b0..10bb5f33e08 100644
--- a/lib/private/Files/Cache/Scanner.php
+++ b/lib/private/Files/Cache/Scanner.php
@@ -355,29 +355,45 @@ class Scanner extends BasicEmitter implements IScanner {
* @param string $path
* @param bool $recursive
* @param int $reuse
- * @param array $folderData existing cache data for the folder to be scanned
+ * @param int $folderId id for the folder to be scanned
* @param bool $lock set to false to disable getting an additional read lock during scanning
* @return int the size of the scanned folder or -1 if the size is unknown at this stage
*/
- protected function scanChildren($path, $recursive = self::SCAN_RECURSIVE, $reuse = -1, $folderData = null, $lock = true) {
+ protected function scanChildren($path, $recursive = self::SCAN_RECURSIVE, $reuse = -1, $folderId = null, $lock = true) {
if ($reuse === -1) {
$reuse = ($recursive === self::SCAN_SHALLOW) ? self::REUSE_ETAG | self::REUSE_SIZE : self::REUSE_ETAG;
}
$this->emit('\OC\Files\Cache\Scanner', 'scanFolder', array($path, $this->storageId));
$size = 0;
- $childQueue = array();
- if (is_array($folderData) and isset($folderData['fileid'])) {
- $folderId = $folderData['fileid'];
- } else {
+ if (!is_null($folderId)) {
$folderId = $this->cache->getId($path);
}
+ $childQueue = $this->handleChildren($path, $recursive, $reuse, $folderId, $lock, $size);
+
+ foreach ($childQueue as $child => $childId) {
+ $childSize = $this->scanChildren($child, self::SCAN_RECURSIVE, $reuse, $childId, $lock);
+ if ($childSize === -1) {
+ $size = -1;
+ } else if ($size !== -1) {
+ $size += $childSize;
+ }
+ }
+ $this->updateCache($path, array('size' => $size), $folderId);
+ $this->emit('\OC\Files\Cache\Scanner', 'postScanFolder', array($path, $this->storageId));
+ return $size;
+ }
+
+ private function handleChildren($path, $recursive, $reuse, $folderId, $lock, &$size) {
+ // we put this in it's own function so it cleans up the memory before we start recursing
$existingChildren = $this->getExistingChildren($folderId);
$newChildren = $this->getNewChildren($path);
if ($this->useTransactions) {
\OC::$server->getDatabaseConnection()->beginTransaction();
}
+
$exceptionOccurred = false;
+ $childQueue = [];
foreach ($newChildren as $file) {
$child = ($path) ? $path . '/' . $file : $file;
try {
@@ -385,7 +401,7 @@ class Scanner extends BasicEmitter implements IScanner {
$data = $this->scanFile($child, $reuse, $folderId, $existingData, $lock);
if ($data) {
if ($data['mimetype'] === 'httpd/unix-directory' and $recursive === self::SCAN_RECURSIVE) {
- $childQueue[$child] = $data;
+ $childQueue[$child] = $data['fileid'];
} else if ($data['size'] === -1) {
$size = -1;
} else if ($size !== -1) {
@@ -420,20 +436,7 @@ class Scanner extends BasicEmitter implements IScanner {
// we reload them here
\OC::$server->getMimeTypeLoader()->reset();
}
-
- foreach ($childQueue as $child => $childData) {
- $childSize = $this->scanChildren($child, self::SCAN_RECURSIVE, $reuse, $childData, $lock);
- if ($childSize === -1) {
- $size = -1;
- } else if ($size !== -1) {
- $size += $childSize;
- }
- }
- if (!is_array($folderData) or !isset($folderData['size']) or $folderData['size'] !== $size) {
- $this->updateCache($path, array('size' => $size), $folderId);
- }
- $this->emit('\OC\Files\Cache\Scanner', 'postScanFolder', array($path, $this->storageId));
- return $size;
+ return $childQueue;
}
/**
@@ -466,7 +469,7 @@ class Scanner extends BasicEmitter implements IScanner {
} else {
$lastPath = null;
while (($path = $this->cache->getIncomplete()) !== false && $path !== $lastPath) {
- $this->runBackgroundScanJob(function() use ($path) {
+ $this->runBackgroundScanJob(function () use ($path) {
$this->scan($path, self::SCAN_RECURSIVE, self::REUSE_ETAG);
}, $path);
// FIXME: this won't proceed with the next item, needs revamping of getIncomplete()
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/Server.php b/lib/private/Server.php
index a4294ee2c88..0b7b8f9e403 100644
--- a/lib/private/Server.php
+++ b/lib/private/Server.php
@@ -362,7 +362,11 @@ class Server extends ServerContainer implements IServerContainer {
});
$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();
diff --git a/lib/private/Share20/DefaultShareProvider.php b/lib/private/Share20/DefaultShareProvider.php
index f0de39fdad3..8a39c18a495 100644
--- a/lib/private/Share20/DefaultShareProvider.php
+++ b/lib/private/Share20/DefaultShareProvider.php
@@ -733,7 +733,7 @@ class DefaultShareProvider implements IShareProvider {
* @throws InvalidShare
*/
private function createShare($data) {
- $share = new Share($this->rootFolder);
+ $share = new Share($this->rootFolder, $this->userManager);
$share->setId((int)$data['id'])
->setShareType((int)$data['share_type'])
->setPermissions((int)$data['permissions'])
diff --git a/lib/private/Share20/Manager.php b/lib/private/Share20/Manager.php
index dee9e0cdd21..3568995472a 100644
--- a/lib/private/Share20/Manager.php
+++ b/lib/private/Share20/Manager.php
@@ -201,7 +201,12 @@ class Manager implements IManager {
}
// And you can't share your rootfolder
- if ($this->rootFolder->getUserFolder($share->getSharedBy())->getPath() === $share->getNode()->getPath()) {
+ if ($this->userManager->userExists($share->getSharedBy())) {
+ $sharedPath = $this->rootFolder->getUserFolder($share->getSharedBy())->getPath();
+ } else {
+ $sharedPath = $this->rootFolder->getUserFolder($share->getShareOwner())->getPath();
+ }
+ if ($sharedPath === $share->getNode()->getPath()) {
throw new \InvalidArgumentException('You can\'t share your root folder');
}
@@ -713,7 +718,11 @@ class Manager implements IManager {
}
if ($share->getPermissions() !== $originalShare->getPermissions()) {
- $userFolder = $this->rootFolder->getUserFolder($share->getShareOwner());
+ if ($this->userManager->userExists($share->getShareOwner())) {
+ $userFolder = $this->rootFolder->getUserFolder($share->getShareOwner());
+ } else {
+ $userFolder = $this->rootFolder->getUserFolder($share->getSharedBy());
+ }
\OC_Hook::emit('OCP\Share', 'post_update_permissions', array(
'itemType' => $share->getNode() instanceof \OCP\Files\File ? 'file' : 'folder',
'itemSource' => $share->getNode()->getId(),
@@ -1107,7 +1116,7 @@ class Manager implements IManager {
* @return \OCP\Share\IShare;
*/
public function newShare() {
- return new \OC\Share20\Share($this->rootFolder);
+ return new \OC\Share20\Share($this->rootFolder, $this->userManager);
}
/**
diff --git a/lib/private/Share20/ProviderFactory.php b/lib/private/Share20/ProviderFactory.php
index 0bedfb84fc7..b436a7bc5f3 100644
--- a/lib/private/Share20/ProviderFactory.php
+++ b/lib/private/Share20/ProviderFactory.php
@@ -115,7 +115,8 @@ class ProviderFactory implements IProviderFactory {
$l,
$this->serverContainer->getLogger(),
$this->serverContainer->getLazyRootFolder(),
- $this->serverContainer->getConfig()
+ $this->serverContainer->getConfig(),
+ $this->serverContainer->getUserManager()
);
}
diff --git a/lib/private/Share20/Share.php b/lib/private/Share20/Share.php
index c361f01216f..f56fd94b409 100644
--- a/lib/private/Share20/Share.php
+++ b/lib/private/Share20/Share.php
@@ -24,8 +24,7 @@ use OCP\Files\File;
use OCP\Files\IRootFolder;
use OCP\Files\Node;
use OCP\Files\NotFoundException;
-use OCP\IUser;
-use OCP\IGroup;
+use OCP\IUserManager;
use OCP\Share\Exceptions\IllegalIDChangeException;
class Share implements \OCP\Share\IShare {
@@ -68,8 +67,12 @@ class Share implements \OCP\Share\IShare {
/** @var IRootFolder */
private $rootFolder;
- public function __construct(IRootFolder $rootFolder) {
+ /** @var IUserManager */
+ private $userManager;
+
+ public function __construct(IRootFolder $rootFolder, IUserManager $userManager) {
$this->rootFolder = $rootFolder;
+ $this->userManager = $userManager;
}
/**
@@ -145,7 +148,13 @@ class Share implements \OCP\Share\IShare {
throw new NotFoundException();
}
- $userFolder = $this->rootFolder->getUserFolder($this->shareOwner);
+ // for federated shares the owner can be a remote user, in this
+ // case we use the initiator
+ if($this->userManager->userExists($this->shareOwner)) {
+ $userFolder = $this->rootFolder->getUserFolder($this->shareOwner);
+ } else {
+ $userFolder = $this->rootFolder->getUserFolder($this->sharedBy);
+ }
$nodes = $userFolder->getById($this->fileId);
if (empty($nodes)) {
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/User/Session.php b/lib/private/User/Session.php
index 3f074fa8adf..7104f46fea2 100644
--- a/lib/private/User/Session.php
+++ b/lib/private/User/Session.php
@@ -362,6 +362,10 @@ class Session implements IUserSession, Emitter {
// user does not exist
return false;
}
+ if (!$user->isEnabled()) {
+ // disabled users can not log in
+ return false;
+ }
//login
$this->setUser($user);
diff --git a/lib/public/api.php b/lib/public/API.php
index 4d68bef6f29..4d68bef6f29 100644
--- a/lib/public/api.php
+++ b/lib/public/API.php
diff --git a/lib/public/app.php b/lib/public/App.php
index c3ba90cea41..c3ba90cea41 100644
--- a/lib/public/app.php
+++ b/lib/public/App.php
diff --git a/lib/public/autoloadnotallowedexception.php b/lib/public/AutoloadNotAllowedException.php
index f0028b7d49d..f0028b7d49d 100644
--- a/lib/public/autoloadnotallowedexception.php
+++ b/lib/public/AutoloadNotAllowedException.php
diff --git a/lib/public/backgroundjob.php b/lib/public/BackgroundJob.php
index f532a97c747..f532a97c747 100644
--- a/lib/public/backgroundjob.php
+++ b/lib/public/BackgroundJob.php
diff --git a/lib/public/BackgroundJob/IJobList.php b/lib/public/BackgroundJob/IJobList.php
index 5a76ce1ba26..9e401e68419 100644
--- a/lib/public/BackgroundJob/IJobList.php
+++ b/lib/public/BackgroundJob/IJobList.php
@@ -93,10 +93,21 @@ interface IJobList {
public function setLastJob($job);
/**
+ * Remove the reservation for a job
+ *
+ * @param IJob $job
+ * @since 9.1.0
+ */
+ public function unlockJob($job);
+
+ /**
* get the id of the last ran job
*
* @return int
* @since 7.0.0
+ * @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();
diff --git a/lib/public/Comments/CommentsEntityEvent.php b/lib/public/Comments/CommentsEntityEvent.php
new file mode 100644
index 00000000000..5f012a79885
--- /dev/null
+++ b/lib/public/Comments/CommentsEntityEvent.php
@@ -0,0 +1,76 @@
+<?php
+/**
+ * @author Joas Schilling <nickvergessen@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 OCP\Comments;
+
+use Symfony\Component\EventDispatcher\Event;
+
+/**
+ * Class CommentsEntityEvent
+ *
+ * @package OCP\Comments
+ * @since 9.1.0
+ */
+class CommentsEntityEvent extends Event {
+
+ const EVENT_ENTITY = 'OCP\Comments\ICommentsManager::registerEntity';
+
+ /** @var string */
+ protected $event;
+ /** @var \Closure[] */
+ protected $collections;
+
+ /**
+ * DispatcherEvent constructor.
+ *
+ * @param string $event
+ * @since 9.1.0
+ */
+ public function __construct($event) {
+ $this->event = $event;
+ $this->collections = [];
+ }
+
+ /**
+ * @param string $name
+ * @param \Closure $entityExistsFunction The closure should take one
+ * argument, which is the id of the entity, that comments
+ * should be handled for. The return should then be bool,
+ * depending on whether comments are allowed (true) or not.
+ * @throws \OutOfBoundsException when the entity name is already taken
+ * @since 9.1.0
+ */
+ public function addEntityCollection($name, \Closure $entityExistsFunction) {
+ if (isset($this->collections[$name])) {
+ throw new \OutOfBoundsException('Duplicate entity name "' . $name . '"');
+ }
+
+ $this->collections[$name] = $entityExistsFunction;
+ }
+
+ /**
+ * @return \Closure[]
+ * @since 9.1.0
+ */
+ public function getEntityCollections() {
+ return $this->collections;
+ }
+}
diff --git a/lib/public/config.php b/lib/public/Config.php
index 5b5dcb0e78e..5b5dcb0e78e 100644
--- a/lib/public/config.php
+++ b/lib/public/Config.php
diff --git a/lib/public/constants.php b/lib/public/Constants.php
index abf5f95eb96..abf5f95eb96 100644
--- a/lib/public/constants.php
+++ b/lib/public/Constants.php
diff --git a/lib/public/contacts.php b/lib/public/Contacts.php
index 590fd9af1bd..590fd9af1bd 100644
--- a/lib/public/contacts.php
+++ b/lib/public/Contacts.php
diff --git a/lib/public/db.php b/lib/public/DB.php
index 4706c5e95ee..4706c5e95ee 100644
--- a/lib/public/db.php
+++ b/lib/public/DB.php
diff --git a/lib/public/defaults.php b/lib/public/Defaults.php
index 58b25d5914a..58b25d5914a 100644
--- a/lib/public/defaults.php
+++ b/lib/public/Defaults.php
diff --git a/lib/public/files.php b/lib/public/Files.php
index f7f0b30bf86..f7f0b30bf86 100644
--- a/lib/public/files.php
+++ b/lib/public/Files.php
diff --git a/lib/public/groupinterface.php b/lib/public/GroupInterface.php
index 628bc2f42ef..628bc2f42ef 100644
--- a/lib/public/groupinterface.php
+++ b/lib/public/GroupInterface.php
diff --git a/lib/public/iaddressbook.php b/lib/public/IAddressBook.php
index 63e7e061448..63e7e061448 100644
--- a/lib/public/iaddressbook.php
+++ b/lib/public/IAddressBook.php
diff --git a/lib/public/iappconfig.php b/lib/public/IAppConfig.php
index 1406e8a56d6..1406e8a56d6 100644
--- a/lib/public/iappconfig.php
+++ b/lib/public/IAppConfig.php
diff --git a/lib/public/iavatar.php b/lib/public/IAvatar.php
index 7b811b26b68..7b811b26b68 100644
--- a/lib/public/iavatar.php
+++ b/lib/public/IAvatar.php
diff --git a/lib/public/iavatarmanager.php b/lib/public/IAvatarManager.php
index ef6b00ffd13..ef6b00ffd13 100644
--- a/lib/public/iavatarmanager.php
+++ b/lib/public/IAvatarManager.php
diff --git a/lib/public/icache.php b/lib/public/ICache.php
index a1ce068d819..a1ce068d819 100644
--- a/lib/public/icache.php
+++ b/lib/public/ICache.php
diff --git a/lib/public/icachefactory.php b/lib/public/ICacheFactory.php
index 233a4f5525d..233a4f5525d 100644
--- a/lib/public/icachefactory.php
+++ b/lib/public/ICacheFactory.php
diff --git a/lib/public/icertificate.php b/lib/public/ICertificate.php
index c3a003fbf0a..c3a003fbf0a 100644
--- a/lib/public/icertificate.php
+++ b/lib/public/ICertificate.php
diff --git a/lib/public/icertificatemanager.php b/lib/public/ICertificateManager.php
index 27eebcf0491..27eebcf0491 100644
--- a/lib/public/icertificatemanager.php
+++ b/lib/public/ICertificateManager.php
diff --git a/lib/public/iconfig.php b/lib/public/IConfig.php
index 8dac390a99c..8dac390a99c 100644
--- a/lib/public/iconfig.php
+++ b/lib/public/IConfig.php
diff --git a/lib/public/icontainer.php b/lib/public/IContainer.php
index d23ee5ea3b5..d23ee5ea3b5 100644
--- a/lib/public/icontainer.php
+++ b/lib/public/IContainer.php
diff --git a/lib/public/idbconnection.php b/lib/public/IDBConnection.php
index 780fcd26364..4ecf01ca27e 100644
--- a/lib/public/idbconnection.php
+++ b/lib/public/IDBConnection.php
@@ -125,6 +125,25 @@ interface IDBConnection {
public function setValues($table, array $keys, array $values, array $updatePreconditionValues = []);
/**
+ * Create an exclusive read+write lock on a table
+ *
+ * Important Note: Due to the nature how locks work on different DBs, it is
+ * only possible to lock one table at a time. You should also NOT start a
+ * transaction while holding a lock.
+ *
+ * @param string $tableName
+ * @since 9.1.0
+ */
+ public function lockTable($tableName);
+
+ /**
+ * Release a previous acquired lock again
+ *
+ * @since 9.1.0
+ */
+ public function unlockTable();
+
+ /**
* Start a transaction
* @since 6.0.0
*/
diff --git a/lib/public/idatetimeformatter.php b/lib/public/IDateTimeFormatter.php
index e8d357ae50f..e8d357ae50f 100644
--- a/lib/public/idatetimeformatter.php
+++ b/lib/public/IDateTimeFormatter.php
diff --git a/lib/public/idatetimezone.php b/lib/public/IDateTimeZone.php
index 3df705a2413..3df705a2413 100644
--- a/lib/public/idatetimezone.php
+++ b/lib/public/IDateTimeZone.php
diff --git a/lib/public/idb.php b/lib/public/IDb.php
index f21fedd1f54..f21fedd1f54 100644
--- a/lib/public/idb.php
+++ b/lib/public/IDb.php
diff --git a/lib/public/ieventsource.php b/lib/public/IEventSource.php
index b643d1c9da7..b643d1c9da7 100644
--- a/lib/public/ieventsource.php
+++ b/lib/public/IEventSource.php
diff --git a/lib/public/igroup.php b/lib/public/IGroup.php
index 02f2ef201fd..02f2ef201fd 100644
--- a/lib/public/igroup.php
+++ b/lib/public/IGroup.php
diff --git a/lib/public/igroupmanager.php b/lib/public/IGroupManager.php
index cda40606f9d..cda40606f9d 100644
--- a/lib/public/igroupmanager.php
+++ b/lib/public/IGroupManager.php
diff --git a/lib/public/ihelper.php b/lib/public/IHelper.php
index 4ad1d5704fd..4ad1d5704fd 100644
--- a/lib/public/ihelper.php
+++ b/lib/public/IHelper.php
diff --git a/lib/public/iimage.php b/lib/public/IImage.php
index db0ca0f93be..db0ca0f93be 100644
--- a/lib/public/iimage.php
+++ b/lib/public/IImage.php
diff --git a/lib/public/il10n.php b/lib/public/IL10N.php
index f1954eeb4b9..f1954eeb4b9 100644
--- a/lib/public/il10n.php
+++ b/lib/public/IL10N.php
diff --git a/lib/public/ilogger.php b/lib/public/ILogger.php
index fa947612fcd..fa947612fcd 100644
--- a/lib/public/ilogger.php
+++ b/lib/public/ILogger.php
diff --git a/lib/public/imemcache.php b/lib/public/IMemcache.php
index b5c0cef923d..b5c0cef923d 100644
--- a/lib/public/imemcache.php
+++ b/lib/public/IMemcache.php
diff --git a/lib/public/imemcachettl.php b/lib/public/IMemcacheTTL.php
index f2d03dcdf40..f2d03dcdf40 100644
--- a/lib/public/imemcachettl.php
+++ b/lib/public/IMemcacheTTL.php
diff --git a/lib/public/inavigationmanager.php b/lib/public/INavigationManager.php
index 243f6ea3eea..243f6ea3eea 100644
--- a/lib/public/inavigationmanager.php
+++ b/lib/public/INavigationManager.php
diff --git a/lib/public/ipreview.php b/lib/public/IPreview.php
index cfcbebd8639..cfcbebd8639 100644
--- a/lib/public/ipreview.php
+++ b/lib/public/IPreview.php
diff --git a/lib/public/irequest.php b/lib/public/IRequest.php
index 296c70f4ecc..296c70f4ecc 100644
--- a/lib/public/irequest.php
+++ b/lib/public/IRequest.php
diff --git a/lib/public/isearch.php b/lib/public/ISearch.php
index ec6673dabbd..ec6673dabbd 100644
--- a/lib/public/isearch.php
+++ b/lib/public/ISearch.php
diff --git a/lib/public/isession.php b/lib/public/ISession.php
index 7bc8654a1b9..7bc8654a1b9 100644
--- a/lib/public/isession.php
+++ b/lib/public/ISession.php
diff --git a/lib/public/itagmanager.php b/lib/public/ITagManager.php
index e6d67ddd02c..e6d67ddd02c 100644
--- a/lib/public/itagmanager.php
+++ b/lib/public/ITagManager.php
diff --git a/lib/public/itags.php b/lib/public/ITags.php
index cbc178c37bf..cbc178c37bf 100644
--- a/lib/public/itags.php
+++ b/lib/public/ITags.php
diff --git a/lib/public/itempmanager.php b/lib/public/ITempManager.php
index 025e43d8563..025e43d8563 100644
--- a/lib/public/itempmanager.php
+++ b/lib/public/ITempManager.php
diff --git a/lib/public/iurlgenerator.php b/lib/public/IURLGenerator.php
index a702ca47bfc..a702ca47bfc 100644
--- a/lib/public/iurlgenerator.php
+++ b/lib/public/IURLGenerator.php
diff --git a/lib/public/iuser.php b/lib/public/IUser.php
index 16617a2f2f6..16617a2f2f6 100644
--- a/lib/public/iuser.php
+++ b/lib/public/IUser.php
diff --git a/lib/public/iuserbackend.php b/lib/public/IUserBackend.php
index 5cd7945dd7a..5cd7945dd7a 100644
--- a/lib/public/iuserbackend.php
+++ b/lib/public/IUserBackend.php
diff --git a/lib/public/iusermanager.php b/lib/public/IUserManager.php
index 00c0bbc8721..00c0bbc8721 100644
--- a/lib/public/iusermanager.php
+++ b/lib/public/IUserManager.php
diff --git a/lib/public/iusersession.php b/lib/public/IUserSession.php
index 2196f2c8ce0..2196f2c8ce0 100644
--- a/lib/public/iusersession.php
+++ b/lib/public/IUserSession.php
diff --git a/lib/public/image.php b/lib/public/Image.php
index 4a7ffe8bc9a..4a7ffe8bc9a 100644
--- a/lib/public/image.php
+++ b/lib/public/Image.php
diff --git a/lib/public/json.php b/lib/public/JSON.php
index fceffa0001e..fceffa0001e 100644
--- a/lib/public/json.php
+++ b/lib/public/JSON.php
diff --git a/lib/public/lock/ilockingprovider.php b/lib/public/Lock/ILockingProvider.php
index b4b579bbc7a..b4b579bbc7a 100644
--- a/lib/public/lock/ilockingprovider.php
+++ b/lib/public/Lock/ILockingProvider.php
diff --git a/lib/public/lock/lockedexception.php b/lib/public/Lock/LockedException.php
index d084046046e..d084046046e 100644
--- a/lib/public/lock/lockedexception.php
+++ b/lib/public/Lock/LockedException.php
diff --git a/lib/public/mail/imailer.php b/lib/public/Mail/IMailer.php
index e3c751277ac..e3c751277ac 100644
--- a/lib/public/mail/imailer.php
+++ b/lib/public/Mail/IMailer.php
diff --git a/lib/public/migration/ioutput.php b/lib/public/Migration/IOutput.php
index d3b43028495..d3b43028495 100644
--- a/lib/public/migration/ioutput.php
+++ b/lib/public/Migration/IOutput.php
diff --git a/lib/public/migration/irepairstep.php b/lib/public/Migration/IRepairStep.php
index 07830a935f9..07830a935f9 100644
--- a/lib/public/migration/irepairstep.php
+++ b/lib/public/Migration/IRepairStep.php
diff --git a/lib/public/notification/iaction.php b/lib/public/Notification/IAction.php
index 1f4d1d5b7fe..1f4d1d5b7fe 100644
--- a/lib/public/notification/iaction.php
+++ b/lib/public/Notification/IAction.php
diff --git a/lib/public/notification/iapp.php b/lib/public/Notification/IApp.php
index 98da265559b..98da265559b 100644
--- a/lib/public/notification/iapp.php
+++ b/lib/public/Notification/IApp.php
diff --git a/lib/public/notification/imanager.php b/lib/public/Notification/IManager.php
index a18af747b10..a18af747b10 100644
--- a/lib/public/notification/imanager.php
+++ b/lib/public/Notification/IManager.php
diff --git a/lib/public/notification/inotification.php b/lib/public/Notification/INotification.php
index 2d8557ec64d..2d8557ec64d 100644
--- a/lib/public/notification/inotification.php
+++ b/lib/public/Notification/INotification.php
diff --git a/lib/public/notification/inotifier.php b/lib/public/Notification/INotifier.php
index 0d9cecc88b8..0d9cecc88b8 100644
--- a/lib/public/notification/inotifier.php
+++ b/lib/public/Notification/INotifier.php
diff --git a/lib/public/preconditionnotmetexception.php b/lib/public/PreConditionNotMetException.php
index 212efc08ded..212efc08ded 100644
--- a/lib/public/preconditionnotmetexception.php
+++ b/lib/public/PreConditionNotMetException.php
diff --git a/lib/public/preview/iprovider.php b/lib/public/Preview/IProvider.php
index 8231e90f000..8231e90f000 100644
--- a/lib/public/preview/iprovider.php
+++ b/lib/public/Preview/IProvider.php
diff --git a/lib/public/response.php b/lib/public/Response.php
index a2a7667684a..a2a7667684a 100644
--- a/lib/public/response.php
+++ b/lib/public/Response.php
diff --git a/lib/public/route/iroute.php b/lib/public/Route/IRoute.php
index 904cb81b0bd..904cb81b0bd 100644
--- a/lib/public/route/iroute.php
+++ b/lib/public/Route/IRoute.php
diff --git a/lib/public/route/irouter.php b/lib/public/Route/IRouter.php
index b4573fb39f2..b4573fb39f2 100644
--- a/lib/public/route/irouter.php
+++ b/lib/public/Route/IRouter.php
diff --git a/lib/public/sabrepluginevent.php b/lib/public/SabrePluginEvent.php
index 11d939aee47..11d939aee47 100644
--- a/lib/public/sabrepluginevent.php
+++ b/lib/public/SabrePluginEvent.php
diff --git a/lib/public/sabrepluginexception.php b/lib/public/SabrePluginException.php
index 2c5a799c4f7..2c5a799c4f7 100644
--- a/lib/public/sabrepluginexception.php
+++ b/lib/public/SabrePluginException.php
diff --git a/lib/public/security/icontentsecuritypolicymanager.php b/lib/public/Security/IContentSecurityPolicyManager.php
index 10f1efe995f..10f1efe995f 100644
--- a/lib/public/security/icontentsecuritypolicymanager.php
+++ b/lib/public/Security/IContentSecurityPolicyManager.php
diff --git a/lib/public/security/icredentialsmanager.php b/lib/public/Security/ICredentialsManager.php
index d576bbcfbd8..d576bbcfbd8 100644
--- a/lib/public/security/icredentialsmanager.php
+++ b/lib/public/Security/ICredentialsManager.php
diff --git a/lib/public/security/icrypto.php b/lib/public/Security/ICrypto.php
index 62f27017ab7..62f27017ab7 100644
--- a/lib/public/security/icrypto.php
+++ b/lib/public/Security/ICrypto.php
diff --git a/lib/public/security/ihasher.php b/lib/public/Security/IHasher.php
index 39ba5094b12..39ba5094b12 100644
--- a/lib/public/security/ihasher.php
+++ b/lib/public/Security/IHasher.php
diff --git a/lib/public/security/isecurerandom.php b/lib/public/Security/ISecureRandom.php
index 9b346afe680..9b346afe680 100644
--- a/lib/public/security/isecurerandom.php
+++ b/lib/public/Security/ISecureRandom.php
diff --git a/lib/public/security/stringutils.php b/lib/public/Security/StringUtils.php
index ff1e290315a..ff1e290315a 100644
--- a/lib/public/security/stringutils.php
+++ b/lib/public/Security/StringUtils.php
diff --git a/lib/public/share.php b/lib/public/Share.php
index 9c62ec703e4..9c62ec703e4 100644
--- a/lib/public/share.php
+++ b/lib/public/Share.php
diff --git a/lib/public/share_backend.php b/lib/public/Share_Backend.php
index 110403c1f49..110403c1f49 100644
--- a/lib/public/share_backend.php
+++ b/lib/public/Share_Backend.php
diff --git a/lib/public/share_backend_collection.php b/lib/public/Share_Backend_Collection.php
index 185cf32ce3e..185cf32ce3e 100644
--- a/lib/public/share_backend_collection.php
+++ b/lib/public/Share_Backend_Collection.php
diff --git a/lib/public/share_backend_file_dependent.php b/lib/public/Share_Backend_File_Dependent.php
index 64b3bf43319..64b3bf43319 100644
--- a/lib/public/share_backend_file_dependent.php
+++ b/lib/public/Share_Backend_File_Dependent.php
diff --git a/lib/public/systemtag/isystemtag.php b/lib/public/SystemTag/ISystemTag.php
index 02d02037293..02d02037293 100644
--- a/lib/public/systemtag/isystemtag.php
+++ b/lib/public/SystemTag/ISystemTag.php
diff --git a/lib/public/systemtag/isystemtagmanager.php b/lib/public/SystemTag/ISystemTagManager.php
index 983bfd636ce..35447b05fdc 100644
--- a/lib/public/systemtag/isystemtagmanager.php
+++ b/lib/public/SystemTag/ISystemTagManager.php
@@ -22,6 +22,9 @@
namespace OCP\SystemTag;
+use OCP\IUser;
+use OCP\SystemTag\ISystemTag;
+
/**
* Public interface to access and manage system-wide tags.
*
@@ -113,4 +116,49 @@ interface ISystemTagManager {
*/
public function deleteTags($tagIds);
+ /**
+ * Checks whether the given user is allowed to assign/unassign the tag with the
+ * given id.
+ *
+ * @param ISystemTag $tag tag to check permission for
+ * @param IUser $user user to check permission for
+ *
+ * @return true if the user is allowed to assign/unassign the tag, false otherwise
+ *
+ * @since 9.1.0
+ */
+ public function canUserAssignTag(ISystemTag $tag, IUser $user);
+
+ /**
+ * Checks whether the given user is allowed to see the tag with the given id.
+ *
+ * @param ISystemTag $tag tag to check permission for
+ * @param IUser $user user to check permission for
+ *
+ * @return true if the user can see the tag, false otherwise
+ *
+ * @since 9.1.0
+ */
+ public function canUserSeeTag(ISystemTag $tag, IUser $userId);
+
+ /**
+ * Set groups that can assign a given tag.
+ *
+ * @param ISystemTag $tag tag for group assignment
+ * @param string[] $groupIds group ids of groups that can assign/unassign the tag
+ *
+ * @since 9.1.0
+ */
+ public function setTagGroups(ISystemTag $tag, $groupIds);
+
+ /**
+ * Get groups that can assign a given tag.
+ *
+ * @param ISystemTag $tag tag for group assignment
+ *
+ * @return string[] group ids of groups that can assign/unassign the tag
+ *
+ * @since 9.1.0
+ */
+ public function getTagGroups(ISystemTag $tag);
}
diff --git a/lib/public/systemtag/isystemtagmanagerfactory.php b/lib/public/SystemTag/ISystemTagManagerFactory.php
index ad7467633b1..ad7467633b1 100644
--- a/lib/public/systemtag/isystemtagmanagerfactory.php
+++ b/lib/public/SystemTag/ISystemTagManagerFactory.php
diff --git a/lib/public/systemtag/isystemtagobjectmapper.php b/lib/public/SystemTag/ISystemTagObjectMapper.php
index 59b988a3656..59b988a3656 100644
--- a/lib/public/systemtag/isystemtagobjectmapper.php
+++ b/lib/public/SystemTag/ISystemTagObjectMapper.php
diff --git a/lib/public/systemtag/managerevent.php b/lib/public/SystemTag/ManagerEvent.php
index a0429fc9f67..a0429fc9f67 100644
--- a/lib/public/systemtag/managerevent.php
+++ b/lib/public/SystemTag/ManagerEvent.php
diff --git a/lib/public/systemtag/mapperevent.php b/lib/public/SystemTag/MapperEvent.php
index e05a5ce09c8..e05a5ce09c8 100644
--- a/lib/public/systemtag/mapperevent.php
+++ b/lib/public/SystemTag/MapperEvent.php
diff --git a/lib/public/systemtag/tagalreadyexistsexception.php b/lib/public/SystemTag/TagAlreadyExistsException.php
index 5c3d86ad642..5c3d86ad642 100644
--- a/lib/public/systemtag/tagalreadyexistsexception.php
+++ b/lib/public/SystemTag/TagAlreadyExistsException.php
diff --git a/lib/public/systemtag/tagnotfoundexception.php b/lib/public/SystemTag/TagNotFoundException.php
index 12feda8f58a..12feda8f58a 100644
--- a/lib/public/systemtag/tagnotfoundexception.php
+++ b/lib/public/SystemTag/TagNotFoundException.php
diff --git a/lib/public/template.php b/lib/public/Template.php
index 7e46745c9d8..7e46745c9d8 100644
--- a/lib/public/template.php
+++ b/lib/public/Template.php
diff --git a/lib/public/user.php b/lib/public/User.php
index 64ac92d2100..64ac92d2100 100644
--- a/lib/public/user.php
+++ b/lib/public/User.php
diff --git a/lib/public/userinterface.php b/lib/public/UserInterface.php
index 954c2d68133..954c2d68133 100644
--- a/lib/public/userinterface.php
+++ b/lib/public/UserInterface.php
diff --git a/lib/public/util.php b/lib/public/Util.php
index 45df62ac735..45df62ac735 100644
--- a/lib/public/util.php
+++ b/lib/public/Util.php