aboutsummaryrefslogtreecommitdiffstats
path: root/lib/private
diff options
context:
space:
mode:
authorMichaIng <micha@dietpi.com>2019-12-04 12:42:55 +0100
committerGitHub <noreply@github.com>2019-12-04 12:42:55 +0100
commit4384806f616cf7b9f6a4492ba2fd094afd064f86 (patch)
treec653df3fcea2c8fce6101d066e0bf42db8026d6e /lib/private
parent5afd7abf4481f019ad0044393b4734645e40f5af (diff)
parent76b78edd40fcb5dbe7f0434cbc41d2e291acfec1 (diff)
downloadnextcloud-server-4384806f616cf7b9f6a4492ba2fd094afd064f86.tar.gz
nextcloud-server-4384806f616cf7b9f6a4492ba2fd094afd064f86.zip
Merge branch 'master' into patch-1
Diffstat (limited to 'lib/private')
-rw-r--r--lib/private/Accounts/AccountManager.php3
-rw-r--r--lib/private/Accounts/Hooks.php1
-rw-r--r--lib/private/Activity/EventMerger.php3
-rw-r--r--lib/private/Activity/Manager.php1
-rw-r--r--lib/private/App/AppManager.php16
-rw-r--r--lib/private/App/AppStore/Fetcher/AppFetcher.php3
-rw-r--r--lib/private/App/AppStore/Fetcher/Fetcher.php2
-rw-r--r--lib/private/App/CodeChecker/CodeChecker.php2
-rw-r--r--lib/private/App/CodeChecker/DeprecationCheck.php1
-rw-r--r--lib/private/App/CodeChecker/EmptyCheck.php1
-rw-r--r--lib/private/App/CodeChecker/ICheck.php1
-rw-r--r--lib/private/App/PlatformRepository.php1
-rw-r--r--lib/private/AppConfig.php13
-rw-r--r--lib/private/AppFramework/App.php7
-rw-r--r--lib/private/AppFramework/DependencyInjection/DIContainer.php8
-rw-r--r--lib/private/AppFramework/Http.php3
-rw-r--r--lib/private/AppFramework/Http/Dispatcher.php14
-rw-r--r--lib/private/AppFramework/Http/Request.php11
-rw-r--r--lib/private/AppFramework/Middleware/MiddlewareDispatcher.php1
-rw-r--r--lib/private/AppFramework/Middleware/OCSMiddleware.php3
-rw-r--r--lib/private/AppFramework/Middleware/Security/PasswordConfirmationMiddleware.php1
-rw-r--r--lib/private/AppFramework/Middleware/Security/SameSiteCookieMiddleware.php1
-rw-r--r--lib/private/AppFramework/Middleware/Security/SecurityMiddleware.php24
-rw-r--r--lib/private/AppFramework/Middleware/SessionMiddleware.php25
-rw-r--r--lib/private/AppFramework/OCS/BaseResponse.php1
-rw-r--r--lib/private/AppFramework/OCS/V1Response.php1
-rw-r--r--lib/private/AppFramework/OCS/V2Response.php3
-rw-r--r--lib/private/AppFramework/Routing/RouteActionHandler.php4
-rw-r--r--lib/private/AppFramework/Utility/ControllerMethodReflector.php13
-rw-r--r--lib/private/AppFramework/Utility/SimpleContainer.php6
-rw-r--r--lib/private/AppFramework/Utility/TimeFactory.php1
-rw-r--r--lib/private/Authentication/Exceptions/ExpiredTokenException.php1
-rw-r--r--lib/private/Authentication/Exceptions/TokenPasswordExpiredException.php (renamed from lib/private/User/Events/PostLoginEvent.php)38
-rw-r--r--lib/private/Authentication/Exceptions/WipeTokenException.php1
-rw-r--r--lib/private/Authentication/Login/CreateSessionTokenCommand.php2
-rw-r--r--lib/private/Authentication/Login/PreLoginHookCommand.php2
-rw-r--r--lib/private/Authentication/LoginCredentials/Store.php7
-rw-r--r--lib/private/Authentication/Token/DefaultTokenProvider.php5
-rw-r--r--lib/private/Authentication/Token/INamedToken.php2
-rw-r--r--lib/private/Authentication/Token/IProvider.php3
-rw-r--r--lib/private/Authentication/Token/Manager.php40
-rw-r--r--lib/private/Authentication/Token/PublicKeyTokenMapper.php3
-rw-r--r--lib/private/Authentication/Token/PublicKeyTokenProvider.php64
-rw-r--r--lib/private/Authentication/TwoFactorAuth/Registry.php7
-rw-r--r--lib/private/Avatar/Avatar.php4
-rw-r--r--lib/private/Avatar/AvatarManager.php2
-rw-r--r--lib/private/Avatar/UserAvatar.php8
-rw-r--r--lib/private/BackgroundJob/JobList.php2
-rw-r--r--lib/private/Broadcast/Events/BroadcastEvent.php59
-rw-r--r--lib/private/CapabilitiesManager.php1
-rw-r--r--lib/private/Collaboration/Collaborators/RemoteGroupPlugin.php22
-rw-r--r--lib/private/Collaboration/Collaborators/RemotePlugin.php5
-rw-r--r--lib/private/Collaboration/Collaborators/UserPlugin.php5
-rw-r--r--lib/private/Collaboration/Resources/Collection.php4
-rw-r--r--lib/private/Collaboration/Resources/Manager.php17
-rw-r--r--lib/private/Comments/Comment.php7
-rw-r--r--lib/private/Comments/Manager.php6
-rw-r--r--lib/private/Comments/ManagerFactory.php1
-rw-r--r--lib/private/Config.php1
-rw-r--r--lib/private/Console/Application.php1
-rw-r--r--lib/private/Contacts/ContactsMenu/ContactsStore.php2
-rw-r--r--lib/private/DB/AdapterMySQL.php1
-rw-r--r--lib/private/DB/AdapterOCI8.php1
-rw-r--r--lib/private/DB/AdapterPgSql.php1
-rw-r--r--lib/private/DB/AdapterSqlite.php1
-rw-r--r--lib/private/DB/Connection.php11
-rw-r--r--lib/private/DB/MigrationService.php2
-rw-r--r--lib/private/DB/Migrator.php12
-rw-r--r--lib/private/DB/MissingIndexInformation.php2
-rw-r--r--lib/private/DB/OracleMigrator.php2
-rw-r--r--lib/private/DB/QueryBuilder/FunctionBuilder/FunctionBuilder.php21
-rw-r--r--lib/private/DB/QueryBuilder/FunctionBuilder/SqliteFunctionBuilder.php9
-rw-r--r--lib/private/DB/QueryBuilder/QueryBuilder.php64
-rw-r--r--lib/private/DB/SQLiteSessionInit.php2
-rw-r--r--lib/private/Dashboard/DashboardManager.php3
-rw-r--r--lib/private/DirectEditing/Manager.php236
-rw-r--r--lib/private/DirectEditing/Token.php76
-rw-r--r--lib/private/Encryption/DecryptAll.php3
-rw-r--r--lib/private/Encryption/EncryptionWrapper.php5
-rw-r--r--lib/private/Encryption/Exceptions/DecryptionFailedException.php1
-rw-r--r--lib/private/Encryption/Exceptions/EmptyEncryptionDataException.php1
-rw-r--r--lib/private/Encryption/Exceptions/EncryptionFailedException.php1
-rw-r--r--lib/private/Encryption/Exceptions/EncryptionHeaderToLargeException.php1
-rw-r--r--lib/private/Encryption/Exceptions/UnknownCipherException.php1
-rw-r--r--lib/private/Encryption/Keys/Storage.php2
-rw-r--r--lib/private/Encryption/Update.php4
-rw-r--r--lib/private/EventDispatcher/EventDispatcher.php17
-rw-r--r--lib/private/EventDispatcher/SymfonyAdapter.php18
-rw-r--r--lib/private/Federation/CloudFederationProviderManager.php1
-rw-r--r--lib/private/Files/AppData/AppData.php4
-rw-r--r--lib/private/Files/AppData/Factory.php1
-rw-r--r--lib/private/Files/Cache/AbstractCacheEvent.php2
-rw-r--r--lib/private/Files/Cache/Cache.php436
-rw-r--r--lib/private/Files/Cache/CacheEntry.php12
-rw-r--r--lib/private/Files/Cache/CacheQueryBuilder.php92
-rw-r--r--lib/private/Files/Cache/MoveFromCacheTrait.php5
-rw-r--r--lib/private/Files/Cache/Propagator.php7
-rw-r--r--lib/private/Files/Cache/QuerySearchHelper.php11
-rw-r--r--lib/private/Files/Cache/Storage.php7
-rw-r--r--lib/private/Files/Cache/StorageGlobal.php10
-rw-r--r--lib/private/Files/Cache/Watcher.php4
-rw-r--r--lib/private/Files/Cache/Wrapper/CacheWrapper.php2
-rw-r--r--lib/private/Files/Config/CachedMountFileInfo.php2
-rw-r--r--lib/private/Files/Config/MountProviderCollection.php2
-rw-r--r--lib/private/Files/Config/UserMountCache.php2
-rw-r--r--lib/private/Files/FileInfo.php8
-rw-r--r--lib/private/Files/Mount/MountPoint.php4
-rw-r--r--lib/private/Files/Node/File.php17
-rw-r--r--lib/private/Files/Node/Folder.php58
-rw-r--r--lib/private/Files/Node/HookConnector.php22
-rw-r--r--lib/private/Files/Node/LazyRoot.php15
-rw-r--r--lib/private/Files/Node/Node.php55
-rw-r--r--lib/private/Files/Node/Root.php4
-rw-r--r--lib/private/Files/ObjectStore/HomeObjectStoreStorage.php2
-rw-r--r--lib/private/Files/ObjectStore/Mapper.php1
-rw-r--r--lib/private/Files/ObjectStore/NoopScanner.php4
-rw-r--r--lib/private/Files/ObjectStore/ObjectStoreStorage.php14
-rw-r--r--lib/private/Files/ObjectStore/SwiftFactory.php6
-rw-r--r--lib/private/Files/SimpleFS/SimpleFile.php1
-rw-r--r--lib/private/Files/SimpleFS/SimpleFolder.php1
-rw-r--r--lib/private/Files/Storage/Common.php32
-rw-r--r--lib/private/Files/Storage/DAV.php42
-rw-r--r--lib/private/Files/Storage/FailedStorage.php4
-rw-r--r--lib/private/Files/Storage/Local.php26
-rw-r--r--lib/private/Files/Storage/Wrapper/Availability.php207
-rw-r--r--lib/private/Files/Storage/Wrapper/Encoding.php2
-rw-r--r--lib/private/Files/Storage/Wrapper/Encryption.php2
-rw-r--r--lib/private/Files/Storage/Wrapper/Jail.php10
-rw-r--r--lib/private/Files/Type/Loader.php2
-rw-r--r--lib/private/Files/Type/TemplateManager.php5
-rw-r--r--lib/private/Files/Utils/Scanner.php3
-rw-r--r--lib/private/Files/View.php25
-rw-r--r--lib/private/FullTextSearch/FullTextSearchManager.php3
-rw-r--r--lib/private/FullTextSearch/Model/DocumentAccess.php3
-rw-r--r--lib/private/FullTextSearch/Model/IndexDocument.php3
-rw-r--r--lib/private/FullTextSearch/Model/SearchOption.php2
-rw-r--r--lib/private/FullTextSearch/Model/SearchRequestSimpleQuery.php2
-rw-r--r--lib/private/FullTextSearch/Model/SearchTemplate.php3
-rw-r--r--lib/private/GlobalScale/Config.php1
-rw-r--r--lib/private/Group/Database.php71
-rw-r--r--lib/private/Group/Group.php19
-rw-r--r--lib/private/Group/Manager.php63
-rw-r--r--lib/private/Group/MetaData.php2
-rw-r--r--lib/private/Http/Client/Client.php1
-rw-r--r--lib/private/L10N/Factory.php3
-rw-r--r--lib/private/L10N/LanguageNotFoundException.php1
-rw-r--r--lib/private/Lock/MemcacheLockingProvider.php2
-rw-r--r--lib/private/Log.php57
-rw-r--r--lib/private/Log/Errorlog.php1
-rw-r--r--lib/private/Log/ExceptionSerializer.php4
-rw-r--r--lib/private/Log/File.php2
-rw-r--r--lib/private/Log/LogDetails.php4
-rw-r--r--lib/private/Log/Systemdlog.php2
-rw-r--r--lib/private/Mail/Mailer.php2
-rw-r--r--lib/private/Memcache/Redis.php1
-rw-r--r--lib/private/Migration/BackgroundRepair.php1
-rw-r--r--lib/private/Migration/ConsoleOutput.php1
-rw-r--r--lib/private/Migration/SimpleOutput.php1
-rw-r--r--lib/private/NavigationManager.php2
-rw-r--r--lib/private/OCS/DiscoveryService.php1
-rw-r--r--lib/private/Preview/Bitmap.php2
-rw-r--r--lib/private/Preview/Generator.php2
-rw-r--r--lib/private/Preview/GeneratorHelper.php1
-rw-r--r--lib/private/Preview/HEIC.php2
-rw-r--r--lib/private/Preview/Image.php1
-rw-r--r--lib/private/Preview/MP3.php1
-rw-r--r--lib/private/Preview/MSOffice2003.php1
-rw-r--r--lib/private/Preview/MSOffice2007.php1
-rw-r--r--lib/private/Preview/MSOfficeDoc.php1
-rw-r--r--lib/private/Preview/MarkDown.php1
-rw-r--r--lib/private/Preview/Movie.php3
-rw-r--r--lib/private/Preview/Office.php3
-rw-r--r--lib/private/Preview/OpenDocument.php1
-rw-r--r--lib/private/Preview/Provider.php1
-rw-r--r--lib/private/Preview/ProviderV1Adapter.php4
-rw-r--r--lib/private/Preview/SVG.php3
-rw-r--r--lib/private/Preview/StarOffice.php1
-rw-r--r--lib/private/Preview/TXT.php1
-rw-r--r--lib/private/Preview/Watcher.php3
-rw-r--r--lib/private/Preview/WatcherConnector.php3
-rw-r--r--lib/private/PreviewManager.php29
-rw-r--r--lib/private/Repair.php5
-rw-r--r--lib/private/Repair/AddCleanupUpdaterBackupsJob.php1
-rw-r--r--lib/private/Repair/ClearFrontendCaches.php4
-rw-r--r--lib/private/Repair/Collation.php1
-rw-r--r--lib/private/Repair/MoveUpdaterStepFile.php1
-rw-r--r--lib/private/Repair/NC11/FixMountStorages.php1
-rw-r--r--lib/private/Repair/NC13/AddLogRotateJob.php1
-rw-r--r--lib/private/Repair/NC14/AddPreviewBackgroundCleanupJob.php1
-rw-r--r--lib/private/Repair/NC16/ClearCollectionsAccessCache.php58
-rw-r--r--lib/private/Repair/NC16/RemoveCypressFiles.php82
-rw-r--r--lib/private/Repair/NC17/SwitchUpdateChannel.php1
-rw-r--r--lib/private/Repair/Owncloud/DropAccountTermsTable.php1
-rw-r--r--lib/private/Repair/Owncloud/SaveAccountsTableData.php1
-rw-r--r--lib/private/Repair/SqliteAutoincrement.php5
-rw-r--r--lib/private/Route/CachingRouter.php4
-rw-r--r--lib/private/Route/Router.php13
-rw-r--r--lib/private/Search.php2
-rw-r--r--lib/private/Security/Bruteforce/Capabilities.php1
-rw-r--r--lib/private/Security/CSP/ContentSecurityPolicy.php1
-rw-r--r--lib/private/Security/CredentialsManager.php2
-rw-r--r--lib/private/Security/Crypto.php7
-rw-r--r--lib/private/Security/IdentityProof/Manager.php35
-rw-r--r--lib/private/Security/RateLimiting/Limiter.php14
-rw-r--r--lib/private/Security/TrustedDomainHelper.php2
-rw-r--r--lib/private/Server.php23
-rw-r--r--lib/private/ServerContainer.php3
-rw-r--r--lib/private/Settings/Manager.php27
-rw-r--r--lib/private/Setup.php93
-rw-r--r--lib/private/Setup/AbstractDatabase.php1
-rw-r--r--lib/private/Setup/MySQL.php5
-rw-r--r--lib/private/Setup/PostgreSQL.php1
-rw-r--r--lib/private/Share/Constants.php29
-rw-r--r--lib/private/Share/SearchResultSorter.php2
-rw-r--r--lib/private/Share/Share.php3
-rw-r--r--lib/private/Share20/DefaultShareProvider.php189
-rw-r--r--lib/private/Share20/Exception/BackendError.php1
-rw-r--r--lib/private/Share20/Exception/InvalidShare.php1
-rw-r--r--lib/private/Share20/Exception/ProviderException.php2
-rw-r--r--lib/private/Share20/Hooks.php1
-rw-r--r--lib/private/Share20/LegacyHooks.php2
-rw-r--r--lib/private/Share20/Manager.php172
-rw-r--r--lib/private/Share20/ProviderFactory.php11
-rw-r--r--lib/private/Share20/Share.php26
-rw-r--r--lib/private/Share20/ShareHelper.php1
-rw-r--r--lib/private/SubAdmin.php6
-rw-r--r--lib/private/SystemConfig.php15
-rw-r--r--lib/private/SystemTag/ManagerFactory.php1
-rw-r--r--lib/private/SystemTag/SystemTagManager.php6
-rw-r--r--lib/private/SystemTag/SystemTagObjectMapper.php8
-rw-r--r--lib/private/Tagging/Tag.php2
-rw-r--r--lib/private/Tagging/TagMapper.php7
-rw-r--r--lib/private/TempManager.php2
-rw-r--r--lib/private/Template/IconsCacher.php4
-rw-r--r--lib/private/Template/JSCombiner.php3
-rw-r--r--lib/private/Template/JSConfigHelper.php13
-rw-r--r--lib/private/Template/SCSSCacher.php12
-rw-r--r--lib/private/TemplateLayout.php18
-rw-r--r--lib/private/URLGenerator.php5
-rw-r--r--lib/private/Updater/VersionCheck.php8
-rw-r--r--lib/private/User/Backend.php2
-rw-r--r--lib/private/User/Database.php25
-rw-r--r--lib/private/User/Manager.php26
-rw-r--r--lib/private/User/NoUserException.php2
-rw-r--r--lib/private/User/Session.php33
-rw-r--r--lib/private/User/User.php4
-rw-r--r--lib/private/legacy/app.php6
-rw-r--r--lib/private/legacy/defaults.php6
-rw-r--r--lib/private/legacy/eventsource.php2
-rw-r--r--lib/private/legacy/files.php19
-rw-r--r--lib/private/legacy/helper.php10
-rw-r--r--lib/private/legacy/image.php8
-rw-r--r--lib/private/legacy/template.php2
-rw-r--r--lib/private/legacy/util.php16
254 files changed, 2496 insertions, 1102 deletions
diff --git a/lib/private/Accounts/AccountManager.php b/lib/private/Accounts/AccountManager.php
index 408f070dc0d..ada1228954c 100644
--- a/lib/private/Accounts/AccountManager.php
+++ b/lib/private/Accounts/AccountManager.php
@@ -23,9 +23,9 @@
*
*/
-
namespace OC\Accounts;
+use OCA\Settings\BackgroundJobs\VerifyUserData;
use OCP\Accounts\IAccount;
use OCP\Accounts\IAccountManager;
use OCP\BackgroundJob\IJobList;
@@ -33,7 +33,6 @@ use OCP\IDBConnection;
use OCP\IUser;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\EventDispatcher\GenericEvent;
-use OC\Settings\BackgroundJobs\VerifyUserData;
/**
* Class AccountManager
diff --git a/lib/private/Accounts/Hooks.php b/lib/private/Accounts/Hooks.php
index df0b80e8229..2226b1e0b55 100644
--- a/lib/private/Accounts/Hooks.php
+++ b/lib/private/Accounts/Hooks.php
@@ -21,7 +21,6 @@
*
*/
-
namespace OC\Accounts;
use OCP\ILogger;
diff --git a/lib/private/Activity/EventMerger.php b/lib/private/Activity/EventMerger.php
index ed062d094e5..6b4846164ed 100644
--- a/lib/private/Activity/EventMerger.php
+++ b/lib/private/Activity/EventMerger.php
@@ -111,7 +111,8 @@ class EventMerger implements IEventMerger {
$event->setRichSubject($newSubject, $parameters)
->setParsedSubject($parsedSubject)
- ->setChildEvent($previousEvent);
+ ->setChildEvent($previousEvent)
+ ->setTimestamp(max($event->getTimestamp(), $previousEvent->getTimestamp()));
} catch (\UnexpectedValueException $e) {
return $event;
}
diff --git a/lib/private/Activity/Manager.php b/lib/private/Activity/Manager.php
index ba2d1147bc8..29c3c7bbc4d 100644
--- a/lib/private/Activity/Manager.php
+++ b/lib/private/Activity/Manager.php
@@ -23,6 +23,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
+
namespace OC\Activity;
diff --git a/lib/private/App/AppManager.php b/lib/private/App/AppManager.php
index 322731d677c..19242245600 100644
--- a/lib/private/App/AppManager.php
+++ b/lib/private/App/AppManager.php
@@ -13,6 +13,7 @@
* @author Robin Appelman <robin@icewind.nl>
* @author Thomas Müller <thomas.mueller@tmit.eu>
* @author Vincent Petry <pvince81@owncloud.com>
+ * @author Daniel Rudolf <nextcloud.com@daniel-rudolf.de>
*
* @license AGPL-3.0
*
@@ -404,6 +405,21 @@ class AppManager implements IAppManager {
}
/**
+ * Get the web path for the given app.
+ *
+ * @param string $appId
+ * @return string
+ * @throws AppPathNotFoundException if app path can't be found
+ */
+ public function getAppWebPath(string $appId): string {
+ $appWebPath = \OC_App::getAppWebPath($appId);
+ if($appWebPath === false) {
+ throw new AppPathNotFoundException('Could not find web path for ' . $appId);
+ }
+ return $appWebPath;
+ }
+
+ /**
* Clear the cached list of apps when enabling/disabling an app
*/
public function clearAppsCache() {
diff --git a/lib/private/App/AppStore/Fetcher/AppFetcher.php b/lib/private/App/AppStore/Fetcher/AppFetcher.php
index ea69c37f32c..badc4edb444 100644
--- a/lib/private/App/AppStore/Fetcher/AppFetcher.php
+++ b/lib/private/App/AppStore/Fetcher/AppFetcher.php
@@ -115,6 +115,7 @@ class AppFetcher extends Fetcher {
if (empty($releases)) {
// Remove apps that don't have a matching release
+ $response['data'][$dataKey] = [];
continue;
}
@@ -136,7 +137,7 @@ class AppFetcher extends Fetcher {
}
}
- $response['data'] = array_values($response['data']);
+ $response['data'] = array_values(array_filter($response['data']));
return $response;
}
diff --git a/lib/private/App/AppStore/Fetcher/Fetcher.php b/lib/private/App/AppStore/Fetcher/Fetcher.php
index db8c38ac686..b7679685b40 100644
--- a/lib/private/App/AppStore/Fetcher/Fetcher.php
+++ b/lib/private/App/AppStore/Fetcher/Fetcher.php
@@ -27,8 +27,8 @@
namespace OC\App\AppStore\Fetcher;
-use OC\Files\AppData\Factory;
use GuzzleHttp\Exception\ConnectException;
+use OC\Files\AppData\Factory;
use OCP\AppFramework\Http;
use OCP\AppFramework\Utility\ITimeFactory;
use OCP\Files\IAppData;
diff --git a/lib/private/App/CodeChecker/CodeChecker.php b/lib/private/App/CodeChecker/CodeChecker.php
index 8f539897c97..ba0cac3d765 100644
--- a/lib/private/App/CodeChecker/CodeChecker.php
+++ b/lib/private/App/CodeChecker/CodeChecker.php
@@ -92,7 +92,7 @@ class CodeChecker extends BasicEmitter {
}, $excludedDirectories);
$iterator = new RecursiveDirectoryIterator($folder, RecursiveDirectoryIterator::SKIP_DOTS);
- $iterator = new RecursiveCallbackFilterIterator($iterator, function($item) use ($folder, $excludes){
+ $iterator = new RecursiveCallbackFilterIterator($iterator, function($item) use ($excludes){
/** @var SplFileInfo $item */
foreach($excludes as $exclude) {
if (substr($item->getPath(), 0, strlen($exclude)) === $exclude) {
diff --git a/lib/private/App/CodeChecker/DeprecationCheck.php b/lib/private/App/CodeChecker/DeprecationCheck.php
index e672038f347..357876e7385 100644
--- a/lib/private/App/CodeChecker/DeprecationCheck.php
+++ b/lib/private/App/CodeChecker/DeprecationCheck.php
@@ -119,7 +119,6 @@ class DeprecationCheck extends AbstractCheck {
'OCP\App::getAppInfo' => '14.0.0',
'OC_App::getAppVersion' => '14.0.0',
'OCP\App::getAppVersion' => '14.0.0',
- 'OCP\App::registerPersonal' => '14.0.0',
'OCP\AppFramework\Controller::params' => '7.0.0',
'OCP\AppFramework\Controller::getParams' => '7.0.0',
diff --git a/lib/private/App/CodeChecker/EmptyCheck.php b/lib/private/App/CodeChecker/EmptyCheck.php
index 02fbb46d7de..0a2217212a2 100644
--- a/lib/private/App/CodeChecker/EmptyCheck.php
+++ b/lib/private/App/CodeChecker/EmptyCheck.php
@@ -19,6 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
+
namespace OC\App\CodeChecker;
class EmptyCheck implements ICheck {
diff --git a/lib/private/App/CodeChecker/ICheck.php b/lib/private/App/CodeChecker/ICheck.php
index 4dfaa23c538..d34d01cd55d 100644
--- a/lib/private/App/CodeChecker/ICheck.php
+++ b/lib/private/App/CodeChecker/ICheck.php
@@ -19,6 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
+
namespace OC\App\CodeChecker;
interface ICheck {
diff --git a/lib/private/App/PlatformRepository.php b/lib/private/App/PlatformRepository.php
index f94fb3ad504..a264a4dd6c5 100644
--- a/lib/private/App/PlatformRepository.php
+++ b/lib/private/App/PlatformRepository.php
@@ -19,6 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
+
namespace OC\App;
/**
diff --git a/lib/private/AppConfig.php b/lib/private/AppConfig.php
index 8e921dbb7cf..2888cbb9dde 100644
--- a/lib/private/AppConfig.php
+++ b/lib/private/AppConfig.php
@@ -43,8 +43,21 @@ class AppConfig implements IAppConfig {
/** @var array[] */
protected $sensitiveValues = [
+ 'external' => [
+ '/^sites$/',
+ ],
'spreed' => [
+ '/^signaling_ticket_secret$/',
'/^turn_server_secret$/',
+ '/^stun_servers$/',
+ '/^turn_servers$/',
+ '/^signaling_servers$/',
+ ],
+ 'theming' => [
+ '/^imprintUrl$/',
+ '/^privacyUrl$/',
+ '/^slogan$/',
+ '/^url$/',
],
'user_ldap' => [
'/^(s..)?ldap_agent_password$/',
diff --git a/lib/private/AppFramework/App.php b/lib/private/AppFramework/App.php
index 6185a35d1d7..122f4684558 100644
--- a/lib/private/AppFramework/App.php
+++ b/lib/private/AppFramework/App.php
@@ -26,16 +26,15 @@ declare(strict_types=1);
*
*/
-
namespace OC\AppFramework;
-use OC\AppFramework\Http\Dispatcher;
use OC\AppFramework\DependencyInjection\DIContainer;
+use OC\AppFramework\Http\Dispatcher;
use OC\HintException;
use OCP\AppFramework\Http;
-use OCP\AppFramework\QueryException;
use OCP\AppFramework\Http\ICallbackResponse;
use OCP\AppFramework\Http\IOutput;
+use OCP\AppFramework\QueryException;
use OCP\IRequest;
/**
@@ -104,8 +103,6 @@ class App {
if ($appName === 'core') {
$appNameSpace = 'OC\\Core';
- } else if ($appName === 'settings') {
- $appNameSpace = 'OC\\Settings';
} else {
$appNameSpace = self::buildAppNamespace($appName);
}
diff --git a/lib/private/AppFramework/DependencyInjection/DIContainer.php b/lib/private/AppFramework/DependencyInjection/DIContainer.php
index 89ebc60b226..b41be947adb 100644
--- a/lib/private/AppFramework/DependencyInjection/DIContainer.php
+++ b/lib/private/AppFramework/DependencyInjection/DIContainer.php
@@ -32,7 +32,6 @@
*
*/
-
namespace OC\AppFramework\DependencyInjection;
use OC;
@@ -40,14 +39,15 @@ use OC\AppFramework\Http;
use OC\AppFramework\Http\Dispatcher;
use OC\AppFramework\Http\Output;
use OC\AppFramework\Middleware\MiddlewareDispatcher;
-use OC\AppFramework\Middleware\Security\CORSMiddleware;
use OC\AppFramework\Middleware\OCSMiddleware;
+use OC\AppFramework\Middleware\Security\CORSMiddleware;
use OC\AppFramework\Middleware\Security\RateLimitingMiddleware;
use OC\AppFramework\Middleware\Security\SecurityMiddleware;
use OC\AppFramework\Middleware\SessionMiddleware;
use OC\AppFramework\Utility\SimpleContainer;
use OC\Core\Middleware\TwoFactorMiddleware;
use OC\ServerContainer;
+use OCA\WorkflowEngine\Manager;
use OCP\AppFramework\Http\IOutput;
use OCP\AppFramework\IAppContainer;
use OCP\AppFramework\QueryException;
@@ -65,7 +65,6 @@ use OCP\IServerContainer;
use OCP\ISession;
use OCP\IURLGenerator;
use OCP\IUserSession;
-use OCA\WorkflowEngine\Manager;
class DIContainer extends SimpleContainer implements IAppContainer {
@@ -279,12 +278,11 @@ class DIContainer extends SimpleContainer implements IAppContainer {
);
foreach($this->middleWares as $middleWare) {
- $dispatcher->registerMiddleware($c[$middleWare]);
+ $dispatcher->registerMiddleware($c->query($middleWare));
}
$dispatcher->registerMiddleware(
new SessionMiddleware(
- $c->query(IRequest::class),
$c->query(IControllerMethodReflector::class),
$c->query(ISession::class)
)
diff --git a/lib/private/AppFramework/Http.php b/lib/private/AppFramework/Http.php
index e126c8a1cf0..0b3b31fe541 100644
--- a/lib/private/AppFramework/Http.php
+++ b/lib/private/AppFramework/Http.php
@@ -27,7 +27,6 @@
*
*/
-
namespace OC\AppFramework;
use OCP\AppFramework\Http as BaseHttp;
@@ -152,5 +151,3 @@ class Http extends BaseHttp {
}
-
-
diff --git a/lib/private/AppFramework/Http/Dispatcher.php b/lib/private/AppFramework/Http/Dispatcher.php
index 7b9ad015de6..6a04de76adc 100644
--- a/lib/private/AppFramework/Http/Dispatcher.php
+++ b/lib/private/AppFramework/Http/Dispatcher.php
@@ -27,19 +27,17 @@ declare(strict_types=1);
*
*/
-
namespace OC\AppFramework\Http;
-use \OC\AppFramework\Middleware\MiddlewareDispatcher;
-use \OC\AppFramework\Http;
-use \OC\AppFramework\Utility\ControllerMethodReflector;
+use OC\AppFramework\Http;
+use OC\AppFramework\Middleware\MiddlewareDispatcher;
+use OC\AppFramework\Utility\ControllerMethodReflector;
use OCP\AppFramework\Controller;
-use OCP\AppFramework\Http\Response;
use OCP\AppFramework\Http\DataResponse;
+use OCP\AppFramework\Http\Response;
use OCP\IRequest;
-
/**
* Class to dispatch the request to the middleware dispatcher
*/
@@ -105,6 +103,10 @@ class Dispatcher {
} catch(\Exception $exception){
$response = $this->middlewareDispatcher->afterException(
$controller, $methodName, $exception);
+ } catch(\Throwable $throwable) {
+ $exception = new \Exception($throwable->getMessage(), $throwable->getCode(), $throwable);
+ $response = $this->middlewareDispatcher->afterException(
+ $controller, $methodName, $exception);
}
$response = $this->middlewareDispatcher->afterController(
diff --git a/lib/private/AppFramework/Http/Request.php b/lib/private/AppFramework/Http/Request.php
index c205cc5f81b..9d210cd8419 100644
--- a/lib/private/AppFramework/Http/Request.php
+++ b/lib/private/AppFramework/Http/Request.php
@@ -323,11 +323,7 @@ class Request implements \ArrayAccess, \Countable, IRequest {
switch ($name) {
case 'CONTENT_TYPE' :
case 'CONTENT_LENGTH' :
- if (isset($this->server[$name])) {
- return $this->server[$name];
- }
- break;
- case 'REMOTE_ADDR' :
+ case 'REMOTE_ADDR':
if (isset($this->server[$name])) {
return $this->server[$name];
}
@@ -857,6 +853,10 @@ class Request implements \ArrayAccess, \Countable, IRequest {
* @return string Server host
*/
public function getInsecureServerHost(): string {
+ if ($this->fromTrustedProxy() && $this->getOverwriteHost() !== null) {
+ return $this->getOverwriteHost();
+ }
+
$host = 'localhost';
if ($this->fromTrustedProxy() && isset($this->server['HTTP_X_FORWARDED_HOST'])) {
if (strpos($this->server['HTTP_X_FORWARDED_HOST'], ',') !== false) {
@@ -872,6 +872,7 @@ class Request implements \ArrayAccess, \Countable, IRequest {
$host = $this->server['SERVER_NAME'];
}
}
+
return $host;
}
diff --git a/lib/private/AppFramework/Middleware/MiddlewareDispatcher.php b/lib/private/AppFramework/Middleware/MiddlewareDispatcher.php
index e1262b6c712..70440e9623f 100644
--- a/lib/private/AppFramework/Middleware/MiddlewareDispatcher.php
+++ b/lib/private/AppFramework/Middleware/MiddlewareDispatcher.php
@@ -26,7 +26,6 @@ declare(strict_types=1);
*
*/
-
namespace OC\AppFramework\Middleware;
use OCP\AppFramework\Controller;
diff --git a/lib/private/AppFramework/Middleware/OCSMiddleware.php b/lib/private/AppFramework/Middleware/OCSMiddleware.php
index ad1d953f372..2174693a1d7 100644
--- a/lib/private/AppFramework/Middleware/OCSMiddleware.php
+++ b/lib/private/AppFramework/Middleware/OCSMiddleware.php
@@ -21,6 +21,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
+
namespace OC\AppFramework\Middleware;
use OC\AppFramework\Http;
@@ -32,10 +33,10 @@ use OCP\AppFramework\Controller;
use OCP\AppFramework\Http\DataResponse;
use OCP\AppFramework\Http\JSONResponse;
use OCP\AppFramework\Http\Response;
+use OCP\AppFramework\Middleware;
use OCP\AppFramework\OCS\OCSException;
use OCP\AppFramework\OCSController;
use OCP\IRequest;
-use OCP\AppFramework\Middleware;
class OCSMiddleware extends Middleware {
diff --git a/lib/private/AppFramework/Middleware/Security/PasswordConfirmationMiddleware.php b/lib/private/AppFramework/Middleware/Security/PasswordConfirmationMiddleware.php
index d752a68cf32..9f005448387 100644
--- a/lib/private/AppFramework/Middleware/Security/PasswordConfirmationMiddleware.php
+++ b/lib/private/AppFramework/Middleware/Security/PasswordConfirmationMiddleware.php
@@ -20,6 +20,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
+
namespace OC\AppFramework\Middleware\Security;
use OC\AppFramework\Middleware\Security\Exceptions\NotConfirmedException;
diff --git a/lib/private/AppFramework/Middleware/Security/SameSiteCookieMiddleware.php b/lib/private/AppFramework/Middleware/Security/SameSiteCookieMiddleware.php
index 22a9246d661..3c011945477 100644
--- a/lib/private/AppFramework/Middleware/Security/SameSiteCookieMiddleware.php
+++ b/lib/private/AppFramework/Middleware/Security/SameSiteCookieMiddleware.php
@@ -20,6 +20,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
+
namespace OC\AppFramework\Middleware\Security;
use OC\AppFramework\Http\Request;
diff --git a/lib/private/AppFramework/Middleware/Security/SecurityMiddleware.php b/lib/private/AppFramework/Middleware/Security/SecurityMiddleware.php
index 4f380f07d91..16725b1f5d6 100644
--- a/lib/private/AppFramework/Middleware/Security/SecurityMiddleware.php
+++ b/lib/private/AppFramework/Middleware/Security/SecurityMiddleware.php
@@ -28,36 +28,30 @@ declare(strict_types=1);
*
*/
-
namespace OC\AppFramework\Middleware\Security;
use OC\AppFramework\Middleware\Security\Exceptions\AppNotEnabledException;
use OC\AppFramework\Middleware\Security\Exceptions\CrossSiteRequestForgeryException;
use OC\AppFramework\Middleware\Security\Exceptions\NotAdminException;
use OC\AppFramework\Middleware\Security\Exceptions\NotLoggedInException;
+use OC\AppFramework\Middleware\Security\Exceptions\SecurityException;
use OC\AppFramework\Middleware\Security\Exceptions\StrictCookieMissingException;
use OC\AppFramework\Utility\ControllerMethodReflector;
-use OC\Security\CSP\ContentSecurityPolicyManager;
-use OC\Security\CSP\ContentSecurityPolicyNonceManager;
-use OC\Security\CSRF\CsrfTokenManager;
use OCP\App\AppPathNotFoundException;
use OCP\App\IAppManager;
-use OCP\AppFramework\Http\ContentSecurityPolicy;
-use OCP\AppFramework\Http\EmptyContentSecurityPolicy;
+use OCP\AppFramework\Controller;
+use OCP\AppFramework\Http\JSONResponse;
use OCP\AppFramework\Http\RedirectResponse;
+use OCP\AppFramework\Http\Response;
use OCP\AppFramework\Http\TemplateResponse;
use OCP\AppFramework\Middleware;
-use OCP\AppFramework\Http\Response;
-use OCP\AppFramework\Http\JSONResponse;
use OCP\AppFramework\OCSController;
use OCP\IL10N;
+use OCP\ILogger;
use OCP\INavigationManager;
-use OCP\IURLGenerator;
use OCP\IRequest;
-use OCP\ILogger;
-use OCP\AppFramework\Controller;
+use OCP\IURLGenerator;
use OCP\Util;
-use OC\AppFramework\Middleware\Security\Exceptions\SecurityException;
/**
* Used to do all the authentication and checking stuff for a controller method
@@ -121,6 +115,8 @@ class SecurityMiddleware extends Middleware {
* @param Controller $controller the controller
* @param string $methodName the name of the method
* @throws SecurityException when a security check fails
+ *
+ * @suppress PhanUndeclaredClassConstant
*/
public function beforeController($controller, $methodName) {
@@ -128,6 +124,10 @@ class SecurityMiddleware extends Middleware {
// for normal HTML requests and not for AJAX requests
$this->navigationManager->setActiveEntry($this->appName);
+ if ($controller === \OCA\Talk\Controller\PageController::class && $methodName === 'showCall') {
+ $this->navigationManager->setActiveEntry('spreed');
+ }
+
// security checks
$isPublicPage = $this->reflector->hasAnnotation('PublicPage');
if(!$isPublicPage) {
diff --git a/lib/private/AppFramework/Middleware/SessionMiddleware.php b/lib/private/AppFramework/Middleware/SessionMiddleware.php
index 7b52cc1e319..cc927e6875c 100644
--- a/lib/private/AppFramework/Middleware/SessionMiddleware.php
+++ b/lib/private/AppFramework/Middleware/SessionMiddleware.php
@@ -27,32 +27,21 @@ namespace OC\AppFramework\Middleware;
use OC\AppFramework\Utility\ControllerMethodReflector;
use OCP\AppFramework\Controller;
-use OCP\IRequest;
use OCP\AppFramework\Http\Response;
use OCP\AppFramework\Middleware;
+use OCP\IRequest;
use OCP\ISession;
class SessionMiddleware extends Middleware {
- /**
- * @var IRequest
- */
- private $request;
-
- /**
- * @var ControllerMethodReflector
- */
+ /** @var ControllerMethodReflector */
private $reflector;
- /**
- * @param IRequest $request
- * @param ControllerMethodReflector $reflector
- */
- public function __construct(IRequest $request,
- ControllerMethodReflector $reflector,
- ISession $session
-) {
- $this->request = $request;
+ /** @var ISession */
+ private $session;
+
+ public function __construct(ControllerMethodReflector $reflector,
+ ISession $session) {
$this->reflector = $reflector;
$this->session = $session;
}
diff --git a/lib/private/AppFramework/OCS/BaseResponse.php b/lib/private/AppFramework/OCS/BaseResponse.php
index 90ea084dd99..19567f8fdaf 100644
--- a/lib/private/AppFramework/OCS/BaseResponse.php
+++ b/lib/private/AppFramework/OCS/BaseResponse.php
@@ -20,6 +20,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
+
namespace OC\AppFramework\OCS;
use OCP\AppFramework\Http;
diff --git a/lib/private/AppFramework/OCS/V1Response.php b/lib/private/AppFramework/OCS/V1Response.php
index 08b11788110..02405b5edbe 100644
--- a/lib/private/AppFramework/OCS/V1Response.php
+++ b/lib/private/AppFramework/OCS/V1Response.php
@@ -20,6 +20,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
+
namespace OC\AppFramework\OCS;
use OCP\API;
diff --git a/lib/private/AppFramework/OCS/V2Response.php b/lib/private/AppFramework/OCS/V2Response.php
index 7e98efe867d..54e9e8bd9a7 100644
--- a/lib/private/AppFramework/OCS/V2Response.php
+++ b/lib/private/AppFramework/OCS/V2Response.php
@@ -20,10 +20,11 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
+
namespace OC\AppFramework\OCS;
-use OCP\AppFramework\Http;
use OCP\API;
+use OCP\AppFramework\Http;
class V2Response extends BaseResponse {
diff --git a/lib/private/AppFramework/Routing/RouteActionHandler.php b/lib/private/AppFramework/Routing/RouteActionHandler.php
index bcbe2eb400b..7e1c089d2a8 100644
--- a/lib/private/AppFramework/Routing/RouteActionHandler.php
+++ b/lib/private/AppFramework/Routing/RouteActionHandler.php
@@ -25,8 +25,8 @@
namespace OC\AppFramework\Routing;
-use \OC\AppFramework\App;
-use \OC\AppFramework\DependencyInjection\DIContainer;
+use OC\AppFramework\App;
+use OC\AppFramework\DependencyInjection\DIContainer;
class RouteActionHandler {
private $controllerName;
diff --git a/lib/private/AppFramework/Utility/ControllerMethodReflector.php b/lib/private/AppFramework/Utility/ControllerMethodReflector.php
index ef4a1959d66..187fb43a9fc 100644
--- a/lib/private/AppFramework/Utility/ControllerMethodReflector.php
+++ b/lib/private/AppFramework/Utility/ControllerMethodReflector.php
@@ -29,7 +29,7 @@ declare(strict_types=1);
namespace OC\AppFramework\Utility;
-use \OCP\AppFramework\Utility\IControllerMethodReflector;
+use OCP\AppFramework\Utility\IControllerMethodReflector;
/**
* Reads and parses annotations from doc comments
@@ -72,13 +72,10 @@ class ControllerMethodReflector implements IControllerMethodReflector {
}
foreach ($reflection->getParameters() as $param) {
- // extract type information from PHP 7 scalar types and prefer them
- // over phpdoc annotations
- if (method_exists($param, 'getType')) {
- $type = $param->getType();
- if ($type !== null) {
- $this->types[$param->getName()] = (string) $type;
- }
+ // extract type information from PHP 7 scalar types and prefer them over phpdoc annotations
+ $type = $param->getType();
+ if ($type instanceof \ReflectionNamedType) {
+ $this->types[$param->getName()] = $type->getName();
}
$default = null;
diff --git a/lib/private/AppFramework/Utility/SimpleContainer.php b/lib/private/AppFramework/Utility/SimpleContainer.php
index 6f50523bbf6..b8398623490 100644
--- a/lib/private/AppFramework/Utility/SimpleContainer.php
+++ b/lib/private/AppFramework/Utility/SimpleContainer.php
@@ -28,12 +28,12 @@
namespace OC\AppFramework\Utility;
-use ReflectionClass;
-use ReflectionException;
use Closure;
-use Pimple\Container;
use OCP\AppFramework\QueryException;
use OCP\IContainer;
+use Pimple\Container;
+use ReflectionClass;
+use ReflectionException;
/**
* Class SimpleContainer
diff --git a/lib/private/AppFramework/Utility/TimeFactory.php b/lib/private/AppFramework/Utility/TimeFactory.php
index 4526f9b1abb..841d1838354 100644
--- a/lib/private/AppFramework/Utility/TimeFactory.php
+++ b/lib/private/AppFramework/Utility/TimeFactory.php
@@ -27,7 +27,6 @@ namespace OC\AppFramework\Utility;
use OCP\AppFramework\Utility\ITimeFactory;
-
/**
* Needed to mock calls to time()
*/
diff --git a/lib/private/Authentication/Exceptions/ExpiredTokenException.php b/lib/private/Authentication/Exceptions/ExpiredTokenException.php
index d5b2e2cbca7..ddc611b5ce3 100644
--- a/lib/private/Authentication/Exceptions/ExpiredTokenException.php
+++ b/lib/private/Authentication/Exceptions/ExpiredTokenException.php
@@ -21,6 +21,7 @@ declare(strict_types=1);
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
+
namespace OC\Authentication\Exceptions;
use OC\Authentication\Token\IToken;
diff --git a/lib/private/User/Events/PostLoginEvent.php b/lib/private/Authentication/Exceptions/TokenPasswordExpiredException.php
index d14030b5294..6719037b4a0 100644
--- a/lib/private/User/Events/PostLoginEvent.php
+++ b/lib/private/Authentication/Exceptions/TokenPasswordExpiredException.php
@@ -22,42 +22,8 @@ declare(strict_types=1);
*
*/
-namespace OC\User\Events;
+namespace OC\Authentication\Exceptions;
-use OCP\EventDispatcher\Event;
-use OCP\IUser;
+class TokenPasswordExpiredException extends ExpiredTokenException {
-class PostLoginEvent extends Event {
-
- /** @var IUser */
- private $user;
- /** @var string */
- private $password;
- /** @var bool */
- private $isTokenLogin;
-
-
- public function __construct(IUser $user, string $password, bool $isTokenLogin) {
- parent::__construct();
-
- $this->user = $user;
- $this->password = $password;
- $this->isTokenLogin = $isTokenLogin;
- }
-
- public function getUser(): IUser {
- return $this->user;
- }
-
- public function hasPassword(): bool {
- return $this->password !== '';
- }
-
- public function getPassword(): string {
- return $this->password;
- }
-
- public function getIsTokenLogin(): bool {
- return $this->isTokenLogin;
- }
}
diff --git a/lib/private/Authentication/Exceptions/WipeTokenException.php b/lib/private/Authentication/Exceptions/WipeTokenException.php
index c56059fd7b9..03b679596e2 100644
--- a/lib/private/Authentication/Exceptions/WipeTokenException.php
+++ b/lib/private/Authentication/Exceptions/WipeTokenException.php
@@ -21,6 +21,7 @@ declare(strict_types=1);
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
+
namespace OC\Authentication\Exceptions;
use OC\Authentication\Token\IToken;
diff --git a/lib/private/Authentication/Login/CreateSessionTokenCommand.php b/lib/private/Authentication/Login/CreateSessionTokenCommand.php
index 14ad6d18b30..59d5c68a24b 100644
--- a/lib/private/Authentication/Login/CreateSessionTokenCommand.php
+++ b/lib/private/Authentication/Login/CreateSessionTokenCommand.php
@@ -59,7 +59,7 @@ class CreateSessionTokenCommand extends ALoginCommand {
);
$this->userSession->updateTokens(
$loginData->getUser()->getUID(),
- $loginData->getUsername()
+ $loginData->getPassword()
);
return $this->processNextOrFinishSuccessfully($loginData);
diff --git a/lib/private/Authentication/Login/PreLoginHookCommand.php b/lib/private/Authentication/Login/PreLoginHookCommand.php
index 87c52c6fef1..e8b5c0b6aaa 100644
--- a/lib/private/Authentication/Login/PreLoginHookCommand.php
+++ b/lib/private/Authentication/Login/PreLoginHookCommand.php
@@ -51,4 +51,4 @@ class PreLoginHookCommand extends ALoginCommand {
return $this->processNextOrFinishSuccessfully($loginData);
}
-} \ No newline at end of file
+}
diff --git a/lib/private/Authentication/LoginCredentials/Store.php b/lib/private/Authentication/LoginCredentials/Store.php
index 0ed19a2dd07..5f8be9b769f 100644
--- a/lib/private/Authentication/LoginCredentials/Store.php
+++ b/lib/private/Authentication/LoginCredentials/Store.php
@@ -1,4 +1,5 @@
-<?php
+<?php declare(strict_types=1);
+
/**
* @copyright 2016 Christoph Wurst <christoph@winzerhof-wurst.at>
*
@@ -82,8 +83,8 @@ class Store implements IStore {
* @return ICredentials the login credentials of the current user
* @throws CredentialsUnavailableException
*/
- public function getLoginCredentials() {
- if (is_null($this->tokenProvider)) {
+ public function getLoginCredentials(): ICredentials {
+ if ($this->tokenProvider === null) {
throw new CredentialsUnavailableException();
}
diff --git a/lib/private/Authentication/Token/DefaultTokenProvider.php b/lib/private/Authentication/Token/DefaultTokenProvider.php
index 98609a3f14b..6bd7c2c6dc8 100644
--- a/lib/private/Authentication/Token/DefaultTokenProvider.php
+++ b/lib/private/Authentication/Token/DefaultTokenProvider.php
@@ -196,8 +196,9 @@ class DefaultTokenProvider implements IProvider {
* @param string $oldSessionId
* @param string $sessionId
* @throws InvalidTokenException
+ * @return IToken
*/
- public function renewSessionToken(string $oldSessionId, string $sessionId) {
+ public function renewSessionToken(string $oldSessionId, string $sessionId): IToken {
$token = $this->getToken($oldSessionId);
$newToken = new DefaultToken();
@@ -214,6 +215,8 @@ class DefaultTokenProvider implements IProvider {
$newToken->setLastActivity($this->time->getTime());
$this->mapper->insert($newToken);
$this->mapper->delete($token);
+
+ return $newToken;
}
/**
diff --git a/lib/private/Authentication/Token/INamedToken.php b/lib/private/Authentication/Token/INamedToken.php
index ede075a21c0..403116cb660 100644
--- a/lib/private/Authentication/Token/INamedToken.php
+++ b/lib/private/Authentication/Token/INamedToken.php
@@ -31,4 +31,4 @@ interface INamedToken extends IToken {
* @return void
*/
public function setName(string $name): void;
-} \ No newline at end of file
+}
diff --git a/lib/private/Authentication/Token/IProvider.php b/lib/private/Authentication/Token/IProvider.php
index 860b93e16c2..ba8df30eb8d 100644
--- a/lib/private/Authentication/Token/IProvider.php
+++ b/lib/private/Authentication/Token/IProvider.php
@@ -84,8 +84,9 @@ interface IProvider {
* @param string $sessionId
* @throws InvalidTokenException
* @throws \RuntimeException when OpenSSL reports a problem
+ * @return IToken The new token
*/
- public function renewSessionToken(string $oldSessionId, string $sessionId);
+ public function renewSessionToken(string $oldSessionId, string $sessionId): IToken;
/**
* Invalidate (delete) the given session token
diff --git a/lib/private/Authentication/Token/Manager.php b/lib/private/Authentication/Token/Manager.php
index 76c0dfb8695..0642d4426c4 100644
--- a/lib/private/Authentication/Token/Manager.php
+++ b/lib/private/Authentication/Token/Manager.php
@@ -23,6 +23,7 @@ declare(strict_types=1);
namespace OC\Authentication\Token;
+use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
use OC\Authentication\Exceptions\ExpiredTokenException;
use OC\Authentication\Exceptions\InvalidTokenException;
use OC\Authentication\Exceptions\PasswordlessTokenException;
@@ -60,15 +61,29 @@ class Manager implements IProvider {
string $name,
int $type = IToken::TEMPORARY_TOKEN,
int $remember = IToken::DO_NOT_REMEMBER): IToken {
- return $this->publicKeyTokenProvider->generateToken(
- $token,
- $uid,
- $loginName,
- $password,
- $name,
- $type,
- $remember
- );
+ try {
+ return $this->publicKeyTokenProvider->generateToken(
+ $token,
+ $uid,
+ $loginName,
+ $password,
+ $name,
+ $type,
+ $remember
+ );
+ } catch (UniqueConstraintViolationException $e) {
+ // It's rare, but if two requests of the same session (e.g. env-based SAML)
+ // try to create the session token they might end up here at the same time
+ // because we use the session ID as token and the db token is created anew
+ // with every request.
+ //
+ // If the UIDs match, then this should be fine.
+ $existing = $this->getToken($token);
+ if ($existing->getUID() !== $uid) {
+ throw new \Exception('Token conflict handled, but UIDs do not match. This should not happen', 0, $e);
+ }
+ return $existing;
+ }
}
/**
@@ -158,14 +173,15 @@ class Manager implements IProvider {
* @param string $oldSessionId
* @param string $sessionId
* @throws InvalidTokenException
+ * @return IToken
*/
- public function renewSessionToken(string $oldSessionId, string $sessionId) {
+ public function renewSessionToken(string $oldSessionId, string $sessionId): IToken {
try {
- $this->publicKeyTokenProvider->renewSessionToken($oldSessionId, $sessionId);
+ return $this->publicKeyTokenProvider->renewSessionToken($oldSessionId, $sessionId);
} catch (ExpiredTokenException $e) {
throw $e;
} catch (InvalidTokenException $e) {
- $this->defaultTokenProvider->renewSessionToken($oldSessionId, $sessionId);
+ return $this->defaultTokenProvider->renewSessionToken($oldSessionId, $sessionId);
}
}
diff --git a/lib/private/Authentication/Token/PublicKeyTokenMapper.php b/lib/private/Authentication/Token/PublicKeyTokenMapper.php
index df91066c44f..62fbf1c6d7a 100644
--- a/lib/private/Authentication/Token/PublicKeyTokenMapper.php
+++ b/lib/private/Authentication/Token/PublicKeyTokenMapper.php
@@ -163,7 +163,8 @@ class PublicKeyTokenMapper extends QBMapper {
$qb = $this->db->getQueryBuilder();
$qb->delete('authtoken')
- ->where($qb->expr()->eq('type', $qb->createNamedParameter(IToken::TEMPORARY_TOKEN)))
+ ->where($qb->expr()->eq('uid', $qb->createNamedParameter($except->getUID())))
+ ->andWhere($qb->expr()->eq('type', $qb->createNamedParameter(IToken::TEMPORARY_TOKEN)))
->andWhere($qb->expr()->neq('id', $qb->createNamedParameter($except->getId())))
->andWhere($qb->expr()->eq('version', $qb->createNamedParameter(PublicKeyToken::VERSION, IQueryBuilder::PARAM_INT)));
diff --git a/lib/private/Authentication/Token/PublicKeyTokenProvider.php b/lib/private/Authentication/Token/PublicKeyTokenProvider.php
index 318d4468ddc..19987bec253 100644
--- a/lib/private/Authentication/Token/PublicKeyTokenProvider.php
+++ b/lib/private/Authentication/Token/PublicKeyTokenProvider.php
@@ -25,8 +25,10 @@ namespace OC\Authentication\Token;
use OC\Authentication\Exceptions\ExpiredTokenException;
use OC\Authentication\Exceptions\InvalidTokenException;
+use OC\Authentication\Exceptions\TokenPasswordExpiredException;
use OC\Authentication\Exceptions\PasswordlessTokenException;
use OC\Authentication\Exceptions\WipeTokenException;
+use OC\Cache\CappedMemoryCache;
use OCP\AppFramework\Db\DoesNotExistException;
use OCP\AppFramework\Utility\ITimeFactory;
use OCP\IConfig;
@@ -49,6 +51,9 @@ class PublicKeyTokenProvider implements IProvider {
/** @var ITimeFactory $time */
private $time;
+ /** @var CappedMemoryCache */
+ private $cache;
+
public function __construct(PublicKeyTokenMapper $mapper,
ICrypto $crypto,
IConfig $config,
@@ -59,6 +64,8 @@ class PublicKeyTokenProvider implements IProvider {
$this->config = $config;
$this->logger = $logger;
$this->time = $time;
+
+ $this->cache = new CappedMemoryCache();
}
/**
@@ -72,17 +79,26 @@ class PublicKeyTokenProvider implements IProvider {
int $type = IToken::TEMPORARY_TOKEN,
int $remember = IToken::DO_NOT_REMEMBER): IToken {
$dbToken = $this->newToken($token, $uid, $loginName, $password, $name, $type, $remember);
-
$this->mapper->insert($dbToken);
+ // Add the token to the cache
+ $this->cache[$dbToken->getToken()] = $dbToken;
+
return $dbToken;
}
public function getToken(string $tokenId): IToken {
- try {
- $token = $this->mapper->getToken($this->hashToken($tokenId));
- } catch (DoesNotExistException $ex) {
- throw new InvalidTokenException();
+ $tokenHash = $this->hashToken($tokenId);
+
+ if (isset($this->cache[$tokenHash])) {
+ $token = $this->cache[$tokenHash];
+ } else {
+ try {
+ $token = $this->mapper->getToken($this->hashToken($tokenId));
+ $this->cache[$token->getToken()] = $token;
+ } catch (DoesNotExistException $ex) {
+ throw new InvalidTokenException();
+ }
}
if ((int)$token->getExpires() !== 0 && $token->getExpires() < $this->time->getTime()) {
@@ -93,6 +109,11 @@ class PublicKeyTokenProvider implements IProvider {
throw new WipeTokenException($token);
}
+ if ($token->getPasswordInvalid() === true) {
+ //The password is invalid we should throw an TokenPasswordExpiredException
+ throw new TokenPasswordExpiredException($token);
+ }
+
return $token;
}
@@ -111,10 +132,17 @@ class PublicKeyTokenProvider implements IProvider {
throw new WipeTokenException($token);
}
+ if ($token->getPasswordInvalid() === true) {
+ //The password is invalid we should throw an TokenPasswordExpiredException
+ throw new TokenPasswordExpiredException($token);
+ }
+
return $token;
}
- public function renewSessionToken(string $oldSessionId, string $sessionId) {
+ public function renewSessionToken(string $oldSessionId, string $sessionId): IToken {
+ $this->cache->clear();
+
$token = $this->getToken($oldSessionId);
if (!($token instanceof PublicKeyToken)) {
@@ -127,7 +155,7 @@ class PublicKeyTokenProvider implements IProvider {
$password = $this->decryptPassword($token->getPassword(), $privateKey);
}
- $this->generateToken(
+ $newToken = $this->generateToken(
$sessionId,
$token->getUID(),
$token->getLoginName(),
@@ -138,17 +166,25 @@ class PublicKeyTokenProvider implements IProvider {
);
$this->mapper->delete($token);
+
+ return $newToken;
}
public function invalidateToken(string $token) {
+ $this->cache->clear();
+
$this->mapper->invalidate($this->hashToken($token));
}
public function invalidateTokenById(string $uid, int $id) {
+ $this->cache->clear();
+
$this->mapper->deleteById($uid, $id);
}
public function invalidateOldTokens() {
+ $this->cache->clear();
+
$olderThan = $this->time->getTime() - (int) $this->config->getSystemValue('session_lifetime', 60 * 60 * 24);
$this->logger->debug('Invalidating session tokens older than ' . date('c', $olderThan), ['app' => 'cron']);
$this->mapper->invalidateOld($olderThan, IToken::DO_NOT_REMEMBER);
@@ -158,6 +194,8 @@ class PublicKeyTokenProvider implements IProvider {
}
public function updateToken(IToken $token) {
+ $this->cache->clear();
+
if (!($token instanceof PublicKeyToken)) {
throw new InvalidTokenException();
}
@@ -165,6 +203,8 @@ class PublicKeyTokenProvider implements IProvider {
}
public function updateTokenActivity(IToken $token) {
+ $this->cache->clear();
+
if (!($token instanceof PublicKeyToken)) {
throw new InvalidTokenException();
}
@@ -198,6 +238,8 @@ class PublicKeyTokenProvider implements IProvider {
}
public function setPassword(IToken $token, string $tokenId, string $password) {
+ $this->cache->clear();
+
if (!($token instanceof PublicKeyToken)) {
throw new InvalidTokenException();
}
@@ -215,6 +257,8 @@ class PublicKeyTokenProvider implements IProvider {
}
public function rotate(IToken $token, string $oldTokenId, string $newTokenId): IToken {
+ $this->cache->clear();
+
if (!($token instanceof PublicKeyToken)) {
throw new InvalidTokenException();
}
@@ -274,6 +318,8 @@ class PublicKeyTokenProvider implements IProvider {
* @throws \RuntimeException when OpenSSL reports a problem
*/
public function convertToken(DefaultToken $defaultToken, string $token, $password): PublicKeyToken {
+ $this->cache->clear();
+
$pkToken = $this->newToken(
$token,
$defaultToken->getUID(),
@@ -344,6 +390,8 @@ class PublicKeyTokenProvider implements IProvider {
}
public function markPasswordInvalid(IToken $token, string $tokenId) {
+ $this->cache->clear();
+
if (!($token instanceof PublicKeyToken)) {
throw new InvalidTokenException();
}
@@ -353,6 +401,8 @@ class PublicKeyTokenProvider implements IProvider {
}
public function updatePasswords(string $uid, string $password) {
+ $this->cache->clear();
+
if (!$this->mapper->hasExpiredTokens($uid)) {
// Nothing to do here
return;
diff --git a/lib/private/Authentication/TwoFactorAuth/Registry.php b/lib/private/Authentication/TwoFactorAuth/Registry.php
index 2f905441953..791e9eb9954 100644
--- a/lib/private/Authentication/TwoFactorAuth/Registry.php
+++ b/lib/private/Authentication/TwoFactorAuth/Registry.php
@@ -30,20 +30,19 @@ use OC\Authentication\TwoFactorAuth\Db\ProviderUserAssignmentDao;
use OCP\Authentication\TwoFactorAuth\IProvider;
use OCP\Authentication\TwoFactorAuth\IRegistry;
use OCP\Authentication\TwoFactorAuth\RegistryEvent;
+use OCP\EventDispatcher\IEventDispatcher;
use OCP\IUser;
-use Symfony\Component\EventDispatcher\EventDispatcherInterface;
-use Symfony\Component\EventDispatcher\GenericEvent;
class Registry implements IRegistry {
/** @var ProviderUserAssignmentDao */
private $assignmentDao;
- /** @var EventDispatcherInterface */
+ /** @var IEventDispatcher */
private $dispatcher;
public function __construct(ProviderUserAssignmentDao $assignmentDao,
- EventDispatcherInterface $dispatcher) {
+ IEventDispatcher $dispatcher) {
$this->assignmentDao = $assignmentDao;
$this->dispatcher = $dispatcher;
}
diff --git a/lib/private/Avatar/Avatar.php b/lib/private/Avatar/Avatar.php
index 172f47d12a8..e7baa10fbb3 100644
--- a/lib/private/Avatar/Avatar.php
+++ b/lib/private/Avatar/Avatar.php
@@ -32,12 +32,12 @@ declare(strict_types=1);
namespace OC\Avatar;
+use Imagick;
use OC\Color;
+use OC_Image;
use OCP\Files\NotFoundException;
use OCP\IAvatar;
use OCP\ILogger;
-use OC_Image;
-use Imagick;
/**
* This class gets and sets users avatars.
diff --git a/lib/private/Avatar/AvatarManager.php b/lib/private/Avatar/AvatarManager.php
index 567ed3aec1e..b3f475ac698 100644
--- a/lib/private/Avatar/AvatarManager.php
+++ b/lib/private/Avatar/AvatarManager.php
@@ -34,8 +34,8 @@ use OCP\Files\NotFoundException;
use OCP\IAvatar;
use OCP\IAvatarManager;
use OCP\IConfig;
-use OCP\ILogger;
use OCP\IL10N;
+use OCP\ILogger;
/**
* This class implements methods to access Avatar functionality
diff --git a/lib/private/Avatar/UserAvatar.php b/lib/private/Avatar/UserAvatar.php
index 2db65634e8c..f96ec93d5d0 100644
--- a/lib/private/Avatar/UserAvatar.php
+++ b/lib/private/Avatar/UserAvatar.php
@@ -97,7 +97,7 @@ class UserAvatar extends Avatar {
$this->validateAvatar($img);
- $this->remove();
+ $this->remove(true);
$type = $this->getAvatarImageType($img);
$file = $this->folder->newFile('avatar.' . $type);
$file->putContent($data);
@@ -193,7 +193,7 @@ class UserAvatar extends Avatar {
* @throws \OCP\Files\NotPermittedException
* @throws \OCP\PreConditionNotMetException
*/
- public function remove() {
+ public function remove(bool $silent = false) {
$avatars = $this->folder->getDirectoryListing();
$this->config->setUserValue($this->user->getUID(), 'avatar', 'version',
@@ -203,7 +203,9 @@ class UserAvatar extends Avatar {
$avatar->delete();
}
$this->config->setUserValue($this->user->getUID(), 'avatar', 'generated', 'true');
- $this->user->triggerChange('avatar', '');
+ if(!$silent) {
+ $this->user->triggerChange('avatar', '');
+ }
}
/**
diff --git a/lib/private/BackgroundJob/JobList.php b/lib/private/BackgroundJob/JobList.php
index 44b6786841f..7b5469c48f4 100644
--- a/lib/private/BackgroundJob/JobList.php
+++ b/lib/private/BackgroundJob/JobList.php
@@ -30,9 +30,9 @@ namespace OC\BackgroundJob;
use OCP\AppFramework\QueryException;
use OCP\AppFramework\Utility\ITimeFactory;
+use OCP\AutoloadNotAllowedException;
use OCP\BackgroundJob\IJob;
use OCP\BackgroundJob\IJobList;
-use OCP\AutoloadNotAllowedException;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\IConfig;
use OCP\IDBConnection;
diff --git a/lib/private/Broadcast/Events/BroadcastEvent.php b/lib/private/Broadcast/Events/BroadcastEvent.php
new file mode 100644
index 00000000000..f3282b5207c
--- /dev/null
+++ b/lib/private/Broadcast/Events/BroadcastEvent.php
@@ -0,0 +1,59 @@
+<?php declare(strict_types=1);
+
+/**
+ * @copyright 2019 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @author 2019 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OC\Broadcast\Events;
+
+use JsonSerializable;
+use OCP\Broadcast\Events\IBroadcastEvent;
+use OCP\EventDispatcher\ABroadcastedEvent;
+use OCP\EventDispatcher\Event;
+
+class BroadcastEvent extends Event implements IBroadcastEvent {
+
+ /** @var ABroadcastedEvent */
+ private $event;
+
+ public function __construct(ABroadcastedEvent $event) {
+ parent::__construct();
+
+ $this->event = $event;
+ }
+
+ public function getName(): string {
+ return $this->event->broadcastAs();
+ }
+
+ public function getUids(): array {
+ return $this->event->getUids();
+ }
+
+ public function getPayload(): JsonSerializable {
+ return $this->event;
+ }
+
+ public function setBroadcasted(): void {
+ $this->event->setBroadcasted();
+ }
+
+}
diff --git a/lib/private/CapabilitiesManager.php b/lib/private/CapabilitiesManager.php
index ceb8205a7bb..b7ecce144c8 100644
--- a/lib/private/CapabilitiesManager.php
+++ b/lib/private/CapabilitiesManager.php
@@ -22,7 +22,6 @@ declare(strict_types=1);
*
*/
-
namespace OC;
use OCP\AppFramework\QueryException;
diff --git a/lib/private/Collaboration/Collaborators/RemoteGroupPlugin.php b/lib/private/Collaboration/Collaborators/RemoteGroupPlugin.php
index 6e0979fe418..d9e1f2fd49a 100644
--- a/lib/private/Collaboration/Collaborators/RemoteGroupPlugin.php
+++ b/lib/private/Collaboration/Collaborators/RemoteGroupPlugin.php
@@ -57,11 +57,15 @@ class RemoteGroupPlugin implements ISearchPlugin {
$resultType = new SearchResultType('remote_groups');
if ($this->enabled && $this->cloudIdManager->isValidCloudId($search) && $offset === 0) {
+ list($remoteGroup, $serverUrl) = $this->splitGroupRemote($search);
$result['exact'][] = [
- 'label' => $search,
+ 'label' => $remoteGroup . " ($serverUrl)",
+ 'guid' => $remoteGroup,
+ 'name' => $remoteGroup,
'value' => [
'shareType' => Share::SHARE_TYPE_REMOTE_GROUP,
'shareWith' => $search,
+ 'server' => $serverUrl,
],
];
}
@@ -71,4 +75,20 @@ class RemoteGroupPlugin implements ISearchPlugin {
return true;
}
+ /**
+ * split group and remote from federated cloud id
+ *
+ * @param string $address federated share address
+ * @return array [user, remoteURL]
+ * @throws \InvalidArgumentException
+ */
+ public function splitGroupRemote($address) {
+ try {
+ $cloudId = $this->cloudIdManager->resolveCloudId($address);
+ return [$cloudId->getUser(), $cloudId->getRemote()];
+ } catch (\InvalidArgumentException $e) {
+ throw new \InvalidArgumentException('Invalid Federated Cloud ID', 0, $e);
+ }
+ }
+
}
diff --git a/lib/private/Collaboration/Collaborators/RemotePlugin.php b/lib/private/Collaboration/Collaborators/RemotePlugin.php
index d877346b155..fd14e7e03be 100644
--- a/lib/private/Collaboration/Collaborators/RemotePlugin.php
+++ b/lib/private/Collaboration/Collaborators/RemotePlugin.php
@@ -152,10 +152,13 @@ class RemotePlugin implements ISearchPlugin {
$localUser = $this->userManager->get($remoteUser);
if ($localUser === null || $search !== $localUser->getCloudId()) {
$result['exact'][] = [
- 'label' => $search,
+ 'label' => $remoteUser . " ($serverUrl)",
+ 'uuid' => $remoteUser,
+ 'name' => $remoteUser,
'value' => [
'shareType' => Share::SHARE_TYPE_REMOTE,
'shareWith' => $search,
+ 'server' => $serverUrl,
],
];
}
diff --git a/lib/private/Collaboration/Collaborators/UserPlugin.php b/lib/private/Collaboration/Collaborators/UserPlugin.php
index 971b7025564..9de269224f5 100644
--- a/lib/private/Collaboration/Collaborators/UserPlugin.php
+++ b/lib/private/Collaboration/Collaborators/UserPlugin.php
@@ -71,7 +71,7 @@ class UserPlugin implements ISearchPlugin {
foreach ($userGroups as $userGroup) {
$usersTmp = $this->groupManager->displayNamesInGroup($userGroup, $search, $limit, $offset);
foreach ($usersTmp as $uid => $userDisplayName) {
- $users[$uid] = $userDisplayName;
+ $users[(string) $uid] = $userDisplayName;
}
}
} else {
@@ -80,7 +80,7 @@ class UserPlugin implements ISearchPlugin {
foreach ($usersTmp as $user) {
if ($user->isEnabled()) { // Don't keep deactivated users
- $users[$user->getUID()] = $user->getDisplayName();
+ $users[(string) $user->getUID()] = $user->getDisplayName();
}
}
}
@@ -94,6 +94,7 @@ class UserPlugin implements ISearchPlugin {
$foundUserById = false;
$lowerSearch = strtolower($search);
foreach ($users as $uid => $userDisplayName) {
+ $uid = (string) $uid;
if (strtolower($uid) === $lowerSearch || strtolower($userDisplayName) === $lowerSearch) {
if (strtolower($uid) === $lowerSearch) {
$foundUserById = true;
diff --git a/lib/private/Collaboration/Resources/Collection.php b/lib/private/Collaboration/Resources/Collection.php
index 6d37cebdc2f..beef8ba9bd8 100644
--- a/lib/private/Collaboration/Resources/Collection.php
+++ b/lib/private/Collaboration/Resources/Collection.php
@@ -24,10 +24,10 @@ namespace OC\Collaboration\Resources;
use Doctrine\DBAL\Exception\ConstraintViolationException;
-use OCP\Collaboration\Resources\IManager;
-use OCP\Collaboration\Resources\ResourceException;
use OCP\Collaboration\Resources\ICollection;
+use OCP\Collaboration\Resources\IManager;
use OCP\Collaboration\Resources\IResource;
+use OCP\Collaboration\Resources\ResourceException;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\IDBConnection;
use OCP\IUser;
diff --git a/lib/private/Collaboration/Resources/Manager.php b/lib/private/Collaboration/Resources/Manager.php
index d670c3a846d..ef369b18fe3 100644
--- a/lib/private/Collaboration/Resources/Manager.php
+++ b/lib/private/Collaboration/Resources/Manager.php
@@ -353,12 +353,15 @@ class Manager implements IManager {
return $access;
}
- $access = false;
+ $access = null;
+ // Access is granted when a user can access all resources
foreach ($collection->getResources() as $resource) {
- if ($resource->canAccess($user)) {
- $access = true;
+ if (!$resource->canAccess($user)) {
+ $access = false;
break;
}
+
+ $access = true;
}
$this->cacheAccessForCollection($collection, $user, $access);
@@ -461,6 +464,14 @@ class Manager implements IManager {
}
}
+ public function invalidateAccessCacheForAllCollections(): void {
+ $query = $this->connection->getQueryBuilder();
+
+ $query->delete(self::TABLE_ACCESS_CACHE)
+ ->where($query->expr()->neq('collection_id', $query->createNamedParameter(0)));
+ $query->execute();
+ }
+
public function invalidateAccessCacheForCollection(ICollection $collection): void {
$query = $this->connection->getQueryBuilder();
diff --git a/lib/private/Comments/Comment.php b/lib/private/Comments/Comment.php
index c9862c64ca6..ef7538d140d 100644
--- a/lib/private/Comments/Comment.php
+++ b/lib/private/Comments/Comment.php
@@ -22,6 +22,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
+
namespace OC\Comments;
use OCP\Comments\IComment;
@@ -299,12 +300,12 @@ class Comment implements IComment {
public function setActor($actorType, $actorId) {
if(
!is_string($actorType) || !trim($actorType)
- || !is_string($actorId) || !trim($actorId)
+ || !is_string($actorId) || $actorId === ''
) {
throw new \InvalidArgumentException('String expected.');
}
$this->data['actorType'] = trim($actorType);
- $this->data['actorId'] = trim($actorId);
+ $this->data['actorId'] = $actorId;
return $this;
}
@@ -385,7 +386,7 @@ class Comment implements IComment {
public function setObject($objectType, $objectId) {
if(
!is_string($objectType) || !trim($objectType)
- || !is_string($objectId) || !trim($objectId)
+ || !is_string($objectId) || trim($objectId) === ''
) {
throw new \InvalidArgumentException('String expected.');
}
diff --git a/lib/private/Comments/Manager.php b/lib/private/Comments/Manager.php
index e54218509dc..5c36d5e2091 100644
--- a/lib/private/Comments/Manager.php
+++ b/lib/private/Comments/Manager.php
@@ -34,8 +34,8 @@ use OCP\Comments\ICommentsEventHandler;
use OCP\Comments\ICommentsManager;
use OCP\Comments\NotFoundException;
use OCP\DB\QueryBuilder\IQueryBuilder;
-use OCP\IDBConnection;
use OCP\IConfig;
+use OCP\IDBConnection;
use OCP\ILogger;
use OCP\IUser;
@@ -118,9 +118,9 @@ class Manager implements ICommentsManager {
*/
protected function prepareCommentForDatabaseWrite(IComment $comment) {
if (!$comment->getActorType()
- || !$comment->getActorId()
+ || $comment->getActorId() === ''
|| !$comment->getObjectType()
- || !$comment->getObjectId()
+ || $comment->getObjectId() === ''
|| !$comment->getVerb()
) {
throw new \UnexpectedValueException('Actor, Object and Verb information must be provided for saving');
diff --git a/lib/private/Comments/ManagerFactory.php b/lib/private/Comments/ManagerFactory.php
index 21926912b10..1fc5fb2730b 100644
--- a/lib/private/Comments/ManagerFactory.php
+++ b/lib/private/Comments/ManagerFactory.php
@@ -21,6 +21,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
+
namespace OC\Comments;
use OCP\Comments\ICommentsManager;
diff --git a/lib/private/Config.php b/lib/private/Config.php
index f462bebaf58..4d24643c22f 100644
--- a/lib/private/Config.php
+++ b/lib/private/Config.php
@@ -270,4 +270,3 @@ class Config {
}
}
}
-
diff --git a/lib/private/Console/Application.php b/lib/private/Console/Application.php
index d7c047527f1..0260d5f7a3c 100644
--- a/lib/private/Console/Application.php
+++ b/lib/private/Console/Application.php
@@ -27,6 +27,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
+
namespace OC\Console;
use OC\MemoryInfo;
diff --git a/lib/private/Contacts/ContactsMenu/ContactsStore.php b/lib/private/Contacts/ContactsMenu/ContactsStore.php
index 05ef9cca53a..b3843b17a9e 100644
--- a/lib/private/Contacts/ContactsMenu/ContactsStore.php
+++ b/lib/private/Contacts/ContactsMenu/ContactsStore.php
@@ -27,13 +27,13 @@
namespace OC\Contacts\ContactsMenu;
+use OCP\Contacts\ContactsMenu\IContactsStore;
use OCP\Contacts\ContactsMenu\IEntry;
use OCP\Contacts\IManager;
use OCP\IConfig;
use OCP\IGroupManager;
use OCP\IUser;
use OCP\IUserManager;
-use OCP\Contacts\ContactsMenu\IContactsStore;
class ContactsStore implements IContactsStore {
diff --git a/lib/private/DB/AdapterMySQL.php b/lib/private/DB/AdapterMySQL.php
index aa784bb83dc..d9af077da70 100644
--- a/lib/private/DB/AdapterMySQL.php
+++ b/lib/private/DB/AdapterMySQL.php
@@ -22,7 +22,6 @@
*
*/
-
namespace OC\DB;
class AdapterMySQL extends Adapter {
diff --git a/lib/private/DB/AdapterOCI8.php b/lib/private/DB/AdapterOCI8.php
index 359e4ba1b67..68e73ac8c44 100644
--- a/lib/private/DB/AdapterOCI8.php
+++ b/lib/private/DB/AdapterOCI8.php
@@ -23,7 +23,6 @@
*
*/
-
namespace OC\DB;
class AdapterOCI8 extends Adapter {
diff --git a/lib/private/DB/AdapterPgSql.php b/lib/private/DB/AdapterPgSql.php
index 42e57cd45f7..840d270d25f 100644
--- a/lib/private/DB/AdapterPgSql.php
+++ b/lib/private/DB/AdapterPgSql.php
@@ -21,7 +21,6 @@
*
*/
-
namespace OC\DB;
use Doctrine\DBAL\DBALException;
diff --git a/lib/private/DB/AdapterSqlite.php b/lib/private/DB/AdapterSqlite.php
index 0a482259b98..caf6a70b097 100644
--- a/lib/private/DB/AdapterSqlite.php
+++ b/lib/private/DB/AdapterSqlite.php
@@ -24,7 +24,6 @@
*
*/
-
namespace OC\DB;
use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
diff --git a/lib/private/DB/Connection.php b/lib/private/DB/Connection.php
index 506f4bcd4c9..65e1d84bfb1 100644
--- a/lib/private/DB/Connection.php
+++ b/lib/private/DB/Connection.php
@@ -30,14 +30,15 @@
namespace OC\DB;
+use Doctrine\Common\EventManager;
+use Doctrine\DBAL\Cache\QueryCacheProfile;
+use Doctrine\DBAL\Configuration;
use Doctrine\DBAL\DBALException;
use Doctrine\DBAL\Driver;
-use Doctrine\DBAL\Configuration;
-use Doctrine\DBAL\Cache\QueryCacheProfile;
-use Doctrine\Common\EventManager;
-use Doctrine\DBAL\Platforms\MySqlPlatform;
use Doctrine\DBAL\Exception\ConstraintViolationException;
+use Doctrine\DBAL\Platforms\MySqlPlatform;
use Doctrine\DBAL\Schema\Schema;
+use Doctrine\DBAL\TransactionIsolationLevel;
use OC\DB\QueryBuilder\QueryBuilder;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\IDBConnection;
@@ -148,7 +149,7 @@ class Connection extends ReconnectWrapper implements IDBConnection {
$this->adapter = new $params['adapter']($this);
$this->tablePrefix = $params['tablePrefix'];
- parent::setTransactionIsolation(parent::TRANSACTION_READ_COMMITTED);
+ $this->setTransactionIsolation(TransactionIsolationLevel::READ_COMMITTED);
}
/**
diff --git a/lib/private/DB/MigrationService.php b/lib/private/DB/MigrationService.php
index 269400c3ba9..329500fa081 100644
--- a/lib/private/DB/MigrationService.php
+++ b/lib/private/DB/MigrationService.php
@@ -30,6 +30,7 @@ use Doctrine\DBAL\Schema\Schema;
use Doctrine\DBAL\Schema\SchemaException;
use Doctrine\DBAL\Schema\Sequence;
use Doctrine\DBAL\Schema\Table;
+use Doctrine\DBAL\Types\Type;
use OC\App\InfoParser;
use OC\IntegrityCheck\Helpers\AppLocator;
use OC\Migration\SimpleOutput;
@@ -38,7 +39,6 @@ use OCP\AppFramework\QueryException;
use OCP\IDBConnection;
use OCP\Migration\IMigrationStep;
use OCP\Migration\IOutput;
-use Doctrine\DBAL\Types\Type;
class MigrationService {
diff --git a/lib/private/DB/Migrator.php b/lib/private/DB/Migrator.php
index a853ab1ea1b..7f1db4b15d2 100644
--- a/lib/private/DB/Migrator.php
+++ b/lib/private/DB/Migrator.php
@@ -29,12 +29,12 @@
namespace OC\DB;
-use \Doctrine\DBAL\DBALException;
-use \Doctrine\DBAL\Schema\Index;
-use \Doctrine\DBAL\Schema\Table;
-use \Doctrine\DBAL\Schema\Schema;
-use \Doctrine\DBAL\Schema\SchemaConfig;
-use \Doctrine\DBAL\Schema\Comparator;
+use Doctrine\DBAL\DBALException;
+use Doctrine\DBAL\Schema\Comparator;
+use Doctrine\DBAL\Schema\Index;
+use Doctrine\DBAL\Schema\Schema;
+use Doctrine\DBAL\Schema\SchemaConfig;
+use Doctrine\DBAL\Schema\Table;
use Doctrine\DBAL\Types\StringType;
use Doctrine\DBAL\Types\Type;
use OCP\IConfig;
diff --git a/lib/private/DB/MissingIndexInformation.php b/lib/private/DB/MissingIndexInformation.php
index 0cb9852d0d4..bcf8465d8aa 100644
--- a/lib/private/DB/MissingIndexInformation.php
+++ b/lib/private/DB/MissingIndexInformation.php
@@ -36,4 +36,4 @@ class MissingIndexInformation {
public function getListOfMissingIndexes(): array {
return $this->listOfMissingIndexes;
}
-} \ No newline at end of file
+}
diff --git a/lib/private/DB/OracleMigrator.php b/lib/private/DB/OracleMigrator.php
index be90a4bb97f..9c6c9fd156a 100644
--- a/lib/private/DB/OracleMigrator.php
+++ b/lib/private/DB/OracleMigrator.php
@@ -31,10 +31,10 @@ namespace OC\DB;
use Doctrine\DBAL\DBALException;
use Doctrine\DBAL\Schema\Column;
use Doctrine\DBAL\Schema\ColumnDiff;
+use Doctrine\DBAL\Schema\ForeignKeyConstraint;
use Doctrine\DBAL\Schema\Index;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\DBAL\Schema\Table;
-use Doctrine\DBAL\Schema\ForeignKeyConstraint;
class OracleMigrator extends Migrator {
diff --git a/lib/private/DB/QueryBuilder/FunctionBuilder/FunctionBuilder.php b/lib/private/DB/QueryBuilder/FunctionBuilder/FunctionBuilder.php
index a9d2f6f9a35..ffa758e4da7 100644
--- a/lib/private/DB/QueryBuilder/FunctionBuilder/FunctionBuilder.php
+++ b/lib/private/DB/QueryBuilder/FunctionBuilder/FunctionBuilder.php
@@ -72,8 +72,25 @@ class FunctionBuilder implements IFunctionBuilder {
return new QueryFunction($this->helper->quoteColumnName($x) . ' - ' . $this->helper->quoteColumnName($y));
}
- public function count($count, $alias = '') {
+ public function count($count = '', $alias = '') {
$alias = $alias ? (' AS ' . $this->helper->quoteColumnName($alias)) : '';
- return new QueryFunction('COUNT(' . $this->helper->quoteColumnName($count) . ')' . $alias);
+ $quotedName = $count === '' ? '*' : $this->helper->quoteColumnName($count);
+ return new QueryFunction('COUNT(' . $quotedName . ')' . $alias);
+ }
+
+ public function max($field) {
+ return new QueryFunction('MAX(' . $this->helper->quoteColumnName($field) . ')');
+ }
+
+ public function min($field) {
+ return new QueryFunction('MIN(' . $this->helper->quoteColumnName($field) . ')');
+ }
+
+ public function greatest($x, $y) {
+ return new QueryFunction('GREATEST(' . $this->helper->quoteColumnName($x) . ', ' . $this->helper->quoteColumnName($y) . ')');
+ }
+
+ public function least($x, $y) {
+ return new QueryFunction('LEAST(' . $this->helper->quoteColumnName($x) . ', ' . $this->helper->quoteColumnName($y) . ')');
}
}
diff --git a/lib/private/DB/QueryBuilder/FunctionBuilder/SqliteFunctionBuilder.php b/lib/private/DB/QueryBuilder/FunctionBuilder/SqliteFunctionBuilder.php
index 21898cf3f93..f37ac20ecab 100644
--- a/lib/private/DB/QueryBuilder/FunctionBuilder/SqliteFunctionBuilder.php
+++ b/lib/private/DB/QueryBuilder/FunctionBuilder/SqliteFunctionBuilder.php
@@ -30,4 +30,13 @@ class SqliteFunctionBuilder extends FunctionBuilder {
public function concat($x, $y) {
return new QueryFunction('(' . $this->helper->quoteColumnName($x) . ' || ' . $this->helper->quoteColumnName($y) . ')');
}
+
+ public function greatest($x, $y) {
+ return new QueryFunction('MAX(' . $this->helper->quoteColumnName($x) . ', ' . $this->helper->quoteColumnName($y) . ')');
+ }
+
+ public function least($x, $y) {
+ return new QueryFunction('MIN(' . $this->helper->quoteColumnName($x) . ', ' . $this->helper->quoteColumnName($y) . ')');
+ }
+
}
diff --git a/lib/private/DB/QueryBuilder/QueryBuilder.php b/lib/private/DB/QueryBuilder/QueryBuilder.php
index 25d59fb7d7d..b9fada8c4f0 100644
--- a/lib/private/DB/QueryBuilder/QueryBuilder.php
+++ b/lib/private/DB/QueryBuilder/QueryBuilder.php
@@ -39,9 +39,9 @@ use OC\DB\QueryBuilder\FunctionBuilder\OCIFunctionBuilder;
use OC\DB\QueryBuilder\FunctionBuilder\PgSqlFunctionBuilder;
use OC\DB\QueryBuilder\FunctionBuilder\SqliteFunctionBuilder;
use OC\SystemConfig;
+use OCP\DB\QueryBuilder\IParameter;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\DB\QueryBuilder\IQueryFunction;
-use OCP\DB\QueryBuilder\IParameter;
use OCP\IDBConnection;
use OCP\ILogger;
@@ -245,7 +245,7 @@ class QueryBuilder implements IQueryBuilder {
* @param mixed $value The parameter value.
* @param string|null|int $type One of the IQueryBuilder::PARAM_* constants.
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
*/
public function setParameter($key, $value, $type = null) {
$this->queryBuilder->setParameter($key, $value, $type);
@@ -270,7 +270,7 @@ class QueryBuilder implements IQueryBuilder {
* @param array $params The query parameters to set.
* @param array $types The query parameters types to set.
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
*/
public function setParameters(array $params, array $types = array()) {
$this->queryBuilder->setParameters($params, $types);
@@ -323,7 +323,7 @@ class QueryBuilder implements IQueryBuilder {
*
* @param integer $firstResult The first result to return.
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
*/
public function setFirstResult($firstResult) {
$this->queryBuilder->setFirstResult($firstResult);
@@ -350,7 +350,7 @@ class QueryBuilder implements IQueryBuilder {
*
* @param integer $maxResults The maximum number of results to retrieve.
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
*/
public function setMaxResults($maxResults) {
$this->queryBuilder->setMaxResults($maxResults);
@@ -381,7 +381,7 @@ class QueryBuilder implements IQueryBuilder {
*
* @param mixed ...$selects The selection expressions.
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * '@return $this This QueryBuilder instance.
*/
public function select(...$selects) {
if (count($selects) === 1 && is_array($selects[0])) {
@@ -408,7 +408,7 @@ class QueryBuilder implements IQueryBuilder {
* @param mixed $select The selection expressions.
* @param string $alias The column alias used in the constructed query.
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
*/
public function selectAlias($select, $alias) {
@@ -430,7 +430,7 @@ class QueryBuilder implements IQueryBuilder {
*
* @param mixed $select The selection expressions.
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
*/
public function selectDistinct($select) {
@@ -454,7 +454,7 @@ class QueryBuilder implements IQueryBuilder {
*
* @param mixed ...$selects The selection expression.
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
*/
public function addSelect(...$selects) {
if (count($selects) === 1 && is_array($selects[0])) {
@@ -482,7 +482,7 @@ class QueryBuilder implements IQueryBuilder {
* @param string $delete The table whose rows are subject to the deletion.
* @param string $alias The table alias used in the constructed query.
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
*/
public function delete($delete = null, $alias = null) {
$this->queryBuilder->delete(
@@ -507,7 +507,7 @@ class QueryBuilder implements IQueryBuilder {
* @param string $update The table whose rows are subject to the update.
* @param string $alias The table alias used in the constructed query.
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
*/
public function update($update = null, $alias = null) {
$this->queryBuilder->update(
@@ -535,7 +535,7 @@ class QueryBuilder implements IQueryBuilder {
*
* @param string $insert The table into which the rows should be inserted.
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
*/
public function insert($insert = null) {
$this->queryBuilder->insert(
@@ -560,7 +560,7 @@ class QueryBuilder implements IQueryBuilder {
* @param string $from The table.
* @param string|null $alias The alias of the table.
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
*/
public function from($from, $alias = null) {
$this->queryBuilder->from(
@@ -586,7 +586,7 @@ class QueryBuilder implements IQueryBuilder {
* @param string $alias The alias of the join table.
* @param string $condition The condition for the join.
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
*/
public function join($fromAlias, $join, $alias, $condition = null) {
$this->queryBuilder->join(
@@ -614,7 +614,7 @@ class QueryBuilder implements IQueryBuilder {
* @param string $alias The alias of the join table.
* @param string $condition The condition for the join.
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
*/
public function innerJoin($fromAlias, $join, $alias, $condition = null) {
$this->queryBuilder->innerJoin(
@@ -642,7 +642,7 @@ class QueryBuilder implements IQueryBuilder {
* @param string $alias The alias of the join table.
* @param string $condition The condition for the join.
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
*/
public function leftJoin($fromAlias, $join, $alias, $condition = null) {
$this->queryBuilder->leftJoin(
@@ -670,7 +670,7 @@ class QueryBuilder implements IQueryBuilder {
* @param string $alias The alias of the join table.
* @param string $condition The condition for the join.
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
*/
public function rightJoin($fromAlias, $join, $alias, $condition = null) {
$this->queryBuilder->rightJoin(
@@ -696,7 +696,7 @@ class QueryBuilder implements IQueryBuilder {
* @param string $key The column to set.
* @param string $value The value, expression, placeholder, etc.
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
*/
public function set($key, $value) {
$this->queryBuilder->set(
@@ -731,7 +731,7 @@ class QueryBuilder implements IQueryBuilder {
*
* @param mixed ...$predicates The restriction predicates.
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
*/
public function where(...$predicates) {
call_user_func_array(
@@ -756,7 +756,7 @@ class QueryBuilder implements IQueryBuilder {
*
* @param mixed ...$where The query restrictions.
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
*
* @see where()
*/
@@ -783,7 +783,7 @@ class QueryBuilder implements IQueryBuilder {
*
* @param mixed ...$where The WHERE statement.
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
*
* @see where()
*/
@@ -809,7 +809,7 @@ class QueryBuilder implements IQueryBuilder {
*
* @param mixed ...$groupBys The grouping expression.
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
*/
public function groupBy(...$groupBys) {
if (count($groupBys) === 1 && is_array($groupBys[0])) {
@@ -837,7 +837,7 @@ class QueryBuilder implements IQueryBuilder {
*
* @param mixed ...$groupBy The grouping expression.
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
*/
public function addGroupBy(...$groupBys) {
if (count($groupBys) === 1 && is_array($groupBys[0])) {
@@ -869,7 +869,7 @@ class QueryBuilder implements IQueryBuilder {
* @param string $column The column into which the value should be inserted.
* @param string $value The value that should be inserted into the column.
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
*/
public function setValue($column, $value) {
$this->queryBuilder->setValue(
@@ -897,7 +897,7 @@ class QueryBuilder implements IQueryBuilder {
*
* @param array $values The values to specify for the insert query indexed by column names.
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
*/
public function values(array $values) {
$quotedValues = [];
@@ -916,7 +916,7 @@ class QueryBuilder implements IQueryBuilder {
*
* @param mixed ...$having The restriction over the groups.
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
*/
public function having(...$having) {
call_user_func_array(
@@ -933,7 +933,7 @@ class QueryBuilder implements IQueryBuilder {
*
* @param mixed ...$having The restriction to append.
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
*/
public function andHaving(...$having) {
call_user_func_array(
@@ -950,7 +950,7 @@ class QueryBuilder implements IQueryBuilder {
*
* @param mixed ...$having The restriction to add.
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
*/
public function orHaving(...$having) {
call_user_func_array(
@@ -968,7 +968,7 @@ class QueryBuilder implements IQueryBuilder {
* @param string $sort The ordering expression.
* @param string $order The ordering direction.
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
*/
public function orderBy($sort, $order = null) {
$this->queryBuilder->orderBy(
@@ -985,7 +985,7 @@ class QueryBuilder implements IQueryBuilder {
* @param string $sort The ordering expression.
* @param string $order The ordering direction.
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
*/
public function addOrderBy($sort, $order = null) {
$this->queryBuilder->addOrderBy(
@@ -1021,7 +1021,7 @@ class QueryBuilder implements IQueryBuilder {
*
* @param array|null $queryPartNames
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
*/
public function resetQueryParts($queryPartNames = null) {
$this->queryBuilder->resetQueryParts($queryPartNames);
@@ -1034,7 +1034,7 @@ class QueryBuilder implements IQueryBuilder {
*
* @param string $queryPartName
*
- * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
+ * @return $this This QueryBuilder instance.
*/
public function resetQueryPart($queryPartName) {
$this->queryBuilder->resetQueryPart($queryPartName);
diff --git a/lib/private/DB/SQLiteSessionInit.php b/lib/private/DB/SQLiteSessionInit.php
index 635a5d98a9e..826bf8e1952 100644
--- a/lib/private/DB/SQLiteSessionInit.php
+++ b/lib/private/DB/SQLiteSessionInit.php
@@ -24,9 +24,9 @@
namespace OC\DB;
+use Doctrine\Common\EventSubscriber;
use Doctrine\DBAL\Event\ConnectionEventArgs;
use Doctrine\DBAL\Events;
-use Doctrine\Common\EventSubscriber;
class SQLiteSessionInit implements EventSubscriber {
/**
diff --git a/lib/private/Dashboard/DashboardManager.php b/lib/private/Dashboard/DashboardManager.php
index 712d56641fa..c2ec8f25288 100644
--- a/lib/private/Dashboard/DashboardManager.php
+++ b/lib/private/Dashboard/DashboardManager.php
@@ -27,7 +27,6 @@ declare(strict_types=1);
*
*/
-
namespace OC\Dashboard;
@@ -37,7 +36,6 @@ use OCP\Dashboard\Model\IWidgetConfig;
use OCP\Dashboard\Service\IEventsService;
use OCP\Dashboard\Service\IWidgetsService;
-
/**
* Class DashboardManager
*
@@ -145,4 +143,3 @@ class DashboardManager implements IDashboardManager {
}
}
-
diff --git a/lib/private/DirectEditing/Manager.php b/lib/private/DirectEditing/Manager.php
new file mode 100644
index 00000000000..26adad9e572
--- /dev/null
+++ b/lib/private/DirectEditing/Manager.php
@@ -0,0 +1,236 @@
+<?php
+/**
+ * @copyright Copyright (c) 2019 Julius Härtl <jus@bitgrid.net>
+ *
+ * @author Julius Härtl <jus@bitgrid.net>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OC\DirectEditing;
+
+use Doctrine\DBAL\FetchMode;
+use OCP\AppFramework\Http\NotFoundResponse;
+use OCP\AppFramework\Http\Response;
+use OCP\AppFramework\Http\TemplateResponse;
+use OCP\DB\QueryBuilder\IQueryBuilder;
+use OCP\DirectEditing\ACreateFromTemplate;
+use OCP\DirectEditing\IEditor;
+use \OCP\DirectEditing\IManager;
+use OCP\DirectEditing\IToken;
+use OCP\DirectEditing\RegisterDirectEditorEvent;
+use OCP\EventDispatcher\IEventDispatcher;
+use OCP\Files\File;
+use OCP\Files\IRootFolder;
+use OCP\Files\NotFoundException;
+use OCP\IDBConnection;
+use OCP\IUserSession;
+use OCP\Security\ISecureRandom;
+use OCP\Share\IShare;
+
+class Manager implements IManager {
+
+ private const TOKEN_CLEANUP_TIME = 12 * 60 * 60 ;
+
+ public const TABLE_TOKENS = 'direct_edit';
+
+ /** @var IEditor[] */
+ private $editors = [];
+
+ /** @var IDBConnection */
+ private $connection;
+ /**
+ * @var ISecureRandom
+ */
+ private $random;
+ private $userId;
+ private $rootFolder;
+
+ public function __construct(
+ ISecureRandom $random,
+ IDBConnection $connection,
+ IUserSession $userSession,
+ IRootFolder $rootFolder
+ ) {
+ $this->random = $random;
+ $this->connection = $connection;
+ $this->userId = $userSession->getUser() ? $userSession->getUser()->getUID() : null;
+ $this->rootFolder = $rootFolder;
+ }
+
+ public function registerDirectEditor(IEditor $directEditor): void {
+ $this->editors[$directEditor->getId()] = $directEditor;
+ }
+
+ public function getEditors(): array {
+ return $this->editors;
+ }
+
+ public function getTemplates(string $editor, string $type): array {
+ if (!array_key_exists($editor, $this->editors)) {
+ throw new \RuntimeException('No matching editor found');
+ }
+ $templates = [];
+ foreach ($this->editors[$editor]->getCreators() as $creator) {
+ if ($creator instanceof ACreateFromTemplate && $creator->getId() === $type) {
+ $templates = $creator->getTemplates();
+ }
+ }
+ $return = [];
+ $return['templates'] = $templates;
+ return $return;
+ }
+
+ public function create(string $path, string $editorId, string $creatorId, $templateId = null): string {
+ $userFolder = $this->rootFolder->getUserFolder($this->userId);
+ $file = $userFolder->newFile($path);
+ $editor = $this->getEditor($editorId);
+ $creators = $editor->getCreators();
+ foreach ($creators as $creator) {
+ if ($creator->getId() === $creatorId) {
+ $creator->create($file, $creatorId, $templateId);
+ return $this->createToken($editorId, $file);
+ }
+ }
+ throw new \RuntimeException('No creator found');
+ }
+
+ public function open(int $fileId, string $editorId = null): string {
+ $file = $this->rootFolder->getUserFolder($this->userId)->getById($fileId);
+ if (count($file) === 0 || !($file[0] instanceof File) || $file === null) {
+ throw new NotFoundException();
+ }
+ /** @var File $file */
+ $file = $file[0];
+
+ if ($editorId === null) {
+ $editorId = $this->findEditorForFile($file);
+ }
+
+ return $this->createToken($editorId, $file);
+ }
+
+ private function findEditorForFile(File $file) {
+ foreach ($this->editors as $editor) {
+ if (in_array($file->getMimeType(), $editor->getMimetypes())) {
+ return $editor->getId();
+ }
+ }
+ throw new \RuntimeException('No default editor found for files mimetype');
+ }
+
+ public function edit(string $token): Response {
+ try {
+ /** @var IEditor $editor */
+ $tokenObject = $this->getToken($token);
+ if ($tokenObject->hasBeenAccessed()) {
+ throw new \RuntimeException('Token has already been used and can only be used for followup requests');
+ }
+ $editor = $this->getEditor($tokenObject->getEditor());
+ $this->accessToken($token);
+
+ } catch (\Throwable $throwable) {
+ $this->invalidateToken($token);
+ return new NotFoundResponse();
+ }
+ return $editor->open($tokenObject);
+ }
+
+ public function editSecure(File $file, string $editorId): TemplateResponse {
+ // TODO: Implementation in follow up
+ }
+
+ private function getEditor($editorId): IEditor {
+ if (!array_key_exists($editorId, $this->editors)) {
+ throw new \RuntimeException('No editor found');
+ }
+ return $this->editors[$editorId];
+ }
+
+ public function getToken(string $token): IToken {
+ $query = $this->connection->getQueryBuilder();
+ $query->select('*')->from(self::TABLE_TOKENS)
+ ->where($query->expr()->eq('token', $query->createNamedParameter($token, IQueryBuilder::PARAM_STR)));
+ $result = $query->execute();
+ if ($tokenRow = $result->fetch(FetchMode::ASSOCIATIVE)) {
+ return new Token($this, $tokenRow);
+ }
+ throw new \RuntimeException('Failed to validate the token');
+ }
+
+ public function cleanup(): int {
+ $query = $this->connection->getQueryBuilder();
+ $query->delete(self::TABLE_TOKENS)
+ ->where($query->expr()->lt('timestamp', $query->createNamedParameter(time() - self::TOKEN_CLEANUP_TIME)));
+ return $query->execute();
+ }
+
+ public function refreshToken(string $token): bool {
+ $query = $this->connection->getQueryBuilder();
+ $query->update(self::TABLE_TOKENS)
+ ->set('timestamp', $query->createNamedParameter(time(), IQueryBuilder::PARAM_INT))
+ ->where($query->expr()->eq('token', $query->createNamedParameter($token, IQueryBuilder::PARAM_STR)));
+ $result = $query->execute();
+ return $result !== 0;
+ }
+
+
+ public function invalidateToken(string $token): bool {
+ $query = $this->connection->getQueryBuilder();
+ $query->delete(self::TABLE_TOKENS)
+ ->where($query->expr()->eq('token', $query->createNamedParameter($token, IQueryBuilder::PARAM_STR)));
+ $result = $query->execute();
+ return $result !== 0;
+ }
+
+ public function accessToken(string $token): bool {
+ $query = $this->connection->getQueryBuilder();
+ $query->update(self::TABLE_TOKENS)
+ ->set('accessed', $query->createNamedParameter(true, IQueryBuilder::PARAM_BOOL))
+ ->set('timestamp', $query->createNamedParameter(time(), IQueryBuilder::PARAM_INT))
+ ->where($query->expr()->eq('token', $query->createNamedParameter($token, IQueryBuilder::PARAM_STR)));
+ $result = $query->execute();
+ return $result !== 0;
+ }
+
+ public function invokeTokenScope($userId): void {
+ \OC_User::setIncognitoMode(true);
+ \OC_User::setUserId($userId);
+ }
+
+ public function createToken($editorId, File $file, IShare $share = null): string {
+ $token = $this->random->generate(64, ISecureRandom::CHAR_HUMAN_READABLE);
+ $query = $this->connection->getQueryBuilder();
+ $query->insert(self::TABLE_TOKENS)
+ ->values([
+ 'token' => $query->createNamedParameter($token),
+ 'editor_id' => $query->createNamedParameter($editorId),
+ 'file_id' => $query->createNamedParameter($file->getId()),
+ 'user_id' => $query->createNamedParameter($this->userId),
+ 'share_id' => $query->createNamedParameter($share !== null ? $share->getId(): null),
+ 'timestamp' => $query->createNamedParameter(time())
+ ]);
+ $query->execute();
+ return $token;
+ }
+
+ public function getFileForToken($userId, $fileId) {
+ $userFolder = $this->rootFolder->getUserFolder($userId);
+ return $userFolder->getById($fileId)[0];
+ }
+
+}
diff --git a/lib/private/DirectEditing/Token.php b/lib/private/DirectEditing/Token.php
new file mode 100644
index 00000000000..148621a2cf3
--- /dev/null
+++ b/lib/private/DirectEditing/Token.php
@@ -0,0 +1,76 @@
+<?php
+/**
+ * @copyright Copyright (c) 2019 Julius Härtl <jus@bitgrid.net>
+ *
+ * @author Julius Härtl <jus@bitgrid.net>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OC\DirectEditing;
+
+
+use OCP\DirectEditing\IToken;
+use OCP\Files\File;
+
+class Token implements IToken {
+
+ /** @var Manager */
+ private $manager;
+ private $data;
+
+ public function __construct(Manager $manager, $data) {
+ $this->manager = $manager;
+ $this->data = $data;
+ }
+
+ public function extend(): void {
+ $this->manager->refreshToken($this->data['token']);
+ }
+
+ public function invalidate(): void {
+ $this->manager->invalidateToken($this->data['token']);
+ }
+
+ public function getFile(): File {
+ if ($this->data['share_id'] !== null) {
+ return $this->manager->getShareForToken($this->data['share_id']);
+ }
+ return $this->manager->getFileForToken($this->data['user_id'], $this->data['file_id']);
+ }
+
+ public function getToken(): string {
+ return $this->data['token'];
+ }
+
+ public function useTokenScope(): void {
+ $this->manager->invokeTokenScope($this->data['user_id']);
+ }
+
+ public function hasBeenAccessed(): bool {
+ return (bool) $this->data['accessed'];
+ }
+
+ public function getEditor(): string {
+ return $this->data['editor_id'];
+ }
+
+ public function getUser(): string {
+ return $this->data['user_id'];
+ }
+
+}
diff --git a/lib/private/Encryption/DecryptAll.php b/lib/private/Encryption/DecryptAll.php
index d95a8660762..86164f072d2 100644
--- a/lib/private/Encryption/DecryptAll.php
+++ b/lib/private/Encryption/DecryptAll.php
@@ -24,12 +24,11 @@
*
*/
-
namespace OC\Encryption;
use OC\Encryption\Exceptions\DecryptionFailedException;
use OC\Files\View;
-use \OCP\Encryption\IEncryptionModule;
+use OCP\Encryption\IEncryptionModule;
use OCP\IUserManager;
use Symfony\Component\Console\Helper\ProgressBar;
use Symfony\Component\Console\Input\InputInterface;
diff --git a/lib/private/Encryption/EncryptionWrapper.php b/lib/private/Encryption/EncryptionWrapper.php
index c4650d39ee3..30fee808097 100644
--- a/lib/private/Encryption/EncryptionWrapper.php
+++ b/lib/private/Encryption/EncryptionWrapper.php
@@ -21,15 +21,14 @@
*
*/
-
namespace OC\Encryption;
-use OC\Memcache\ArrayCache;
use OC\Files\Filesystem;
use OC\Files\Storage\Wrapper\Encryption;
-use OCP\Files\Mount\IMountPoint;
use OC\Files\View;
+use OC\Memcache\ArrayCache;
+use OCP\Files\Mount\IMountPoint;
use OCP\Files\Storage;
use OCP\ILogger;
diff --git a/lib/private/Encryption/Exceptions/DecryptionFailedException.php b/lib/private/Encryption/Exceptions/DecryptionFailedException.php
index de13536b0c5..946bd47b2c4 100644
--- a/lib/private/Encryption/Exceptions/DecryptionFailedException.php
+++ b/lib/private/Encryption/Exceptions/DecryptionFailedException.php
@@ -21,7 +21,6 @@
*
*/
-
namespace OC\Encryption\Exceptions;
use OCP\Encryption\Exceptions\GenericEncryptionException;
diff --git a/lib/private/Encryption/Exceptions/EmptyEncryptionDataException.php b/lib/private/Encryption/Exceptions/EmptyEncryptionDataException.php
index 3e93e633ce1..73c02ac8d4c 100644
--- a/lib/private/Encryption/Exceptions/EmptyEncryptionDataException.php
+++ b/lib/private/Encryption/Exceptions/EmptyEncryptionDataException.php
@@ -21,7 +21,6 @@
*
*/
-
namespace OC\Encryption\Exceptions;
use OCP\Encryption\Exceptions\GenericEncryptionException;
diff --git a/lib/private/Encryption/Exceptions/EncryptionFailedException.php b/lib/private/Encryption/Exceptions/EncryptionFailedException.php
index fefd8d4f0ba..d351476ffcd 100644
--- a/lib/private/Encryption/Exceptions/EncryptionFailedException.php
+++ b/lib/private/Encryption/Exceptions/EncryptionFailedException.php
@@ -21,7 +21,6 @@
*
*/
-
namespace OC\Encryption\Exceptions;
use OCP\Encryption\Exceptions\GenericEncryptionException;
diff --git a/lib/private/Encryption/Exceptions/EncryptionHeaderToLargeException.php b/lib/private/Encryption/Exceptions/EncryptionHeaderToLargeException.php
index 00bb0cf4262..b06087f0829 100644
--- a/lib/private/Encryption/Exceptions/EncryptionHeaderToLargeException.php
+++ b/lib/private/Encryption/Exceptions/EncryptionHeaderToLargeException.php
@@ -21,7 +21,6 @@
*
*/
-
namespace OC\Encryption\Exceptions;
use OCP\Encryption\Exceptions\GenericEncryptionException;
diff --git a/lib/private/Encryption/Exceptions/UnknownCipherException.php b/lib/private/Encryption/Exceptions/UnknownCipherException.php
index d2c2eb6289c..21dc6639f0d 100644
--- a/lib/private/Encryption/Exceptions/UnknownCipherException.php
+++ b/lib/private/Encryption/Exceptions/UnknownCipherException.php
@@ -21,7 +21,6 @@
*
*/
-
namespace OC\Encryption\Exceptions;
use OCP\Encryption\Exceptions\GenericEncryptionException;
diff --git a/lib/private/Encryption/Keys/Storage.php b/lib/private/Encryption/Keys/Storage.php
index 223b959e661..77284be1b9d 100644
--- a/lib/private/Encryption/Keys/Storage.php
+++ b/lib/private/Encryption/Keys/Storage.php
@@ -29,8 +29,8 @@ namespace OC\Encryption\Keys;
use OC\Encryption\Util;
use OC\Files\Filesystem;
use OC\Files\View;
-use OCP\Encryption\Keys\IStorage;
use OC\User\NoUserException;
+use OCP\Encryption\Keys\IStorage;
class Storage implements IStorage {
diff --git a/lib/private/Encryption/Update.php b/lib/private/Encryption/Update.php
index 9d9f5e4d954..65788424906 100644
--- a/lib/private/Encryption/Update.php
+++ b/lib/private/Encryption/Update.php
@@ -25,8 +25,8 @@
namespace OC\Encryption;
use OC\Files\Filesystem;
-use \OC\Files\Mount;
-use \OC\Files\View;
+use OC\Files\Mount;
+use OC\Files\View;
/**
* update encrypted files, e.g. because a file was shared
diff --git a/lib/private/EventDispatcher/EventDispatcher.php b/lib/private/EventDispatcher/EventDispatcher.php
index 8db2f3101be..1f4a1ba9ab4 100644
--- a/lib/private/EventDispatcher/EventDispatcher.php
+++ b/lib/private/EventDispatcher/EventDispatcher.php
@@ -25,6 +25,10 @@ declare(strict_types=1);
namespace OC\EventDispatcher;
+use function get_class;
+use OC\Broadcast\Events\BroadcastEvent;
+use OCP\Broadcast\Events\IBroadcastEvent;
+use OCP\EventDispatcher\ABroadcastedEvent;
use OCP\EventDispatcher\Event;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\IContainer;
@@ -71,8 +75,19 @@ class EventDispatcher implements IEventDispatcher {
public function dispatch(string $eventName,
Event $event): void {
+ $this->dispatcher->dispatch($event, $eventName);
+
+ if ($event instanceof ABroadcastedEvent && !$event->isPropagationStopped()) {
+ // Propagate broadcast
+ $this->dispatch(
+ IBroadcastEvent::class,
+ new BroadcastEvent($event)
+ );
+ }
+ }
- $this->dispatcher->dispatch($eventName, $event);
+ public function dispatchTyped(Event $event): void {
+ $this->dispatch(get_class($event), $event);
}
/**
diff --git a/lib/private/EventDispatcher/SymfonyAdapter.php b/lib/private/EventDispatcher/SymfonyAdapter.php
index f2f2fbf59fd..70c03fcb1ff 100644
--- a/lib/private/EventDispatcher/SymfonyAdapter.php
+++ b/lib/private/EventDispatcher/SymfonyAdapter.php
@@ -27,7 +27,7 @@ namespace OC\EventDispatcher;
use function is_callable;
use OCP\EventDispatcher\Event;
-use Symfony\Component\EventDispatcher\Event as SymfonyEvent;
+use OCP\ILogger;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
@@ -35,9 +35,12 @@ class SymfonyAdapter implements EventDispatcherInterface {
/** @var EventDispatcher */
private $eventDispatcher;
+ /** @var ILogger */
+ private $logger;
- public function __construct(EventDispatcher $eventDispatcher) {
+ public function __construct(EventDispatcher $eventDispatcher, ILogger $logger) {
$this->eventDispatcher = $eventDispatcher;
+ $this->logger = $logger;
}
/**
@@ -46,16 +49,21 @@ class SymfonyAdapter implements EventDispatcherInterface {
* @param string $eventName The name of the event to dispatch. The name of
* the event is the name of the method that is
* invoked on listeners.
- * @param SymfonyEvent|null $event The event to pass to the event handlers/listeners
+ * @param Event|null $event The event to pass to the event handlers/listeners
* If not supplied, an empty Event instance is created
*
- * @return SymfonyEvent
+ * @return void
*/
- public function dispatch($eventName, SymfonyEvent $event = null) {
+ public function dispatch($eventName, $event = null) {
+ // type hinting is not possible, due to usage of GenericEvent
if ($event instanceof Event) {
$this->eventDispatcher->dispatch($eventName, $event);
} else {
// Legacy event
+ $this->logger->info(
+ 'Deprecated event type for {name}: {class}',
+ [ 'name' => $eventName, 'class' => is_object($event) ? get_class($event) : 'null' ]
+ );
$this->eventDispatcher->getSymfonyDispatcher()->dispatch($eventName, $event);
}
}
diff --git a/lib/private/Federation/CloudFederationProviderManager.php b/lib/private/Federation/CloudFederationProviderManager.php
index c2944f410b3..772bc0aeb05 100644
--- a/lib/private/Federation/CloudFederationProviderManager.php
+++ b/lib/private/Federation/CloudFederationProviderManager.php
@@ -19,7 +19,6 @@
*
*/
-
namespace OC\Federation;
use OC\AppFramework\Http;
diff --git a/lib/private/Files/AppData/AppData.php b/lib/private/Files/AppData/AppData.php
index 7ce29bd0e00..4f526bf04cf 100644
--- a/lib/private/Files/AppData/AppData.php
+++ b/lib/private/Files/AppData/AppData.php
@@ -26,10 +26,10 @@ namespace OC\Files\AppData;
use OC\Cache\CappedMemoryCache;
use OC\Files\SimpleFS\SimpleFolder;
+use OC\SystemConfig;
+use OCP\Files\Folder;
use OCP\Files\IAppData;
use OCP\Files\IRootFolder;
-use OCP\Files\Folder;
-use OC\SystemConfig;
use OCP\Files\Node;
use OCP\Files\NotFoundException;
use OCP\Files\NotPermittedException;
diff --git a/lib/private/Files/AppData/Factory.php b/lib/private/Files/AppData/Factory.php
index 5c7d554ba5b..3a880d5e29b 100644
--- a/lib/private/Files/AppData/Factory.php
+++ b/lib/private/Files/AppData/Factory.php
@@ -21,6 +21,7 @@ declare(strict_types=1);
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
+
namespace OC\Files\AppData;
use OC\SystemConfig;
diff --git a/lib/private/Files/Cache/AbstractCacheEvent.php b/lib/private/Files/Cache/AbstractCacheEvent.php
index c8a41ce54d8..d4990f17743 100644
--- a/lib/private/Files/Cache/AbstractCacheEvent.php
+++ b/lib/private/Files/Cache/AbstractCacheEvent.php
@@ -21,9 +21,9 @@
namespace OC\Files\Cache;
+use OCP\EventDispatcher\Event;
use OCP\Files\Cache\ICacheEvent;
use OCP\Files\Storage\IStorage;
-use Symfony\Component\EventDispatcher\Event;
class AbstractCacheEvent extends Event implements ICacheEvent {
protected $storage;
diff --git a/lib/private/Files/Cache/Cache.php b/lib/private/Files/Cache/Cache.php
index f6139d8abed..a90617f5c53 100644
--- a/lib/private/Files/Cache/Cache.php
+++ b/lib/private/Files/Cache/Cache.php
@@ -38,14 +38,15 @@
namespace OC\Files\Cache;
+use Doctrine\DBAL\Driver\Statement;
use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
use OCP\DB\QueryBuilder\IQueryBuilder;
-use Doctrine\DBAL\Driver\Statement;
use OCP\Files\Cache\CacheInsertEvent;
use OCP\Files\Cache\CacheUpdateEvent;
use OCP\Files\Cache\ICache;
use OCP\Files\Cache\ICacheEntry;
-use \OCP\Files\IMimeTypeLoader;
+use OCP\Files\FileInfo;
+use OCP\Files\IMimeTypeLoader;
use OCP\Files\Search\ISearchQuery;
use OCP\Files\Storage\IStorage;
use OCP\IDBConnection;
@@ -68,7 +69,7 @@ class Cache implements ICache {
/**
* @var array partial data for the cache
*/
- protected $partial = array();
+ protected $partial = [];
/**
* @var string
@@ -112,6 +113,15 @@ class Cache implements ICache {
$this->querySearchHelper = new QuerySearchHelper($this->mimetypeLoader);
}
+ private function getQueryBuilder() {
+ return new CacheQueryBuilder(
+ $this->connection,
+ \OC::$server->getSystemConfig(),
+ \OC::$server->getLogger(),
+ $this
+ );
+ }
+
/**
* Get the numeric storage id for this cache's storage
*
@@ -128,34 +138,24 @@ class Cache implements ICache {
* @return ICacheEntry|false the cache entry as array of false if the file is not found in the cache
*/
public function get($file) {
+ $query = $this->getQueryBuilder();
+ $query->selectFileCache();
+
if (is_string($file) or $file == '') {
// normalize file
$file = $this->normalize($file);
- $where = 'WHERE `storage` = ? AND `path_hash` = ?';
- $params = array($this->getNumericStorageId(), md5($file));
+ $query->whereStorageId()
+ ->wherePath($file);
} else { //file id
- $where = 'WHERE `fileid` = ?';
- $params = array($file);
+ $query->whereFileId($file);
}
- $sql = 'SELECT `fileid`, `storage`, `path`, `path_hash`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`,
- `storage_mtime`, `encrypted`, `etag`, `permissions`, `checksum`
- FROM `*PREFIX*filecache` ' . $where;
- $result = $this->connection->executeQuery($sql, $params);
- $data = $result->fetch();
- //FIXME hide this HACK in the next database layer, or just use doctrine and get rid of MDB2 and PDO
- //PDO returns false, MDB2 returns null, oracle always uses MDB2, so convert null to false
- if ($data === null) {
- $data = false;
- }
+ $data = $query->execute()->fetch();
//merge partial data
- if (!$data and is_string($file)) {
- if (isset($this->partial[$file])) {
- $data = $this->partial[$file];
- }
- return $data;
+ if (!$data and is_string($file) and isset($this->partial[$file])) {
+ return $this->partial[$file];
} else if (!$data) {
return $data;
} else {
@@ -187,6 +187,12 @@ class Cache implements ICache {
$data['storage_mtime'] = $data['mtime'];
}
$data['permissions'] = (int)$data['permissions'];
+ if (isset($data['creation_time'])) {
+ $data['creation_time'] = (int) $data['creation_time'];
+ }
+ if (isset($data['upload_time'])) {
+ $data['upload_time'] = (int) $data['upload_time'];
+ }
return new CacheEntry($data);
}
@@ -209,11 +215,12 @@ class Cache implements ICache {
*/
public function getFolderContentsById($fileId) {
if ($fileId > -1) {
- $sql = 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`,
- `storage_mtime`, `encrypted`, `etag`, `permissions`, `checksum`
- FROM `*PREFIX*filecache` WHERE `parent` = ? ORDER BY `name` ASC';
- $result = $this->connection->executeQuery($sql, [$fileId]);
- $files = $result->fetchAll();
+ $query = $this->getQueryBuilder();
+ $query->selectFileCache()
+ ->whereParent($fileId)
+ ->orderBy('name', 'ASC');
+
+ $files = $query->execute()->fetchAll();
return array_map(function (array $data) {
return self::cacheEntryFromData($data, $this->mimetypeLoader);
}, $files);
@@ -259,7 +266,7 @@ class Cache implements ICache {
unset($this->partial[$file]);
}
- $requiredFields = array('size', 'mtime', 'mimetype');
+ $requiredFields = ['size', 'mtime', 'mimetype'];
foreach ($requiredFields as $field) {
if (!isset($data[$field])) { //data not complete save as partial and return
$this->partial[$file] = $data;
@@ -271,14 +278,8 @@ class Cache implements ICache {
$data['parent'] = $this->getParentId($file);
$data['name'] = basename($file);
- list($queryParts, $params) = $this->buildParts($data);
- $queryParts[] = '`storage`';
- $params[] = $this->getNumericStorageId();
-
- $queryParts = array_map(function ($item) {
- return trim($item, "`");
- }, $queryParts);
- $values = array_combine($queryParts, $params);
+ [$values, $extensionValues] = $this->normalizeData($data);
+ $values['storage'] = $this->getNumericStorageId();
try {
$builder = $this->connection->getQueryBuilder();
@@ -289,7 +290,19 @@ class Cache implements ICache {
}
if ($builder->execute()) {
- $fileId = (int)$this->connection->lastInsertId('*PREFIX*filecache');
+ $fileId = $builder->getLastInsertId();
+
+ if (count($extensionValues)) {
+ $query = $this->getQueryBuilder();
+ $query->insert('filecache_extended');
+
+ $query->setValue('fileid', $query->createNamedParameter($fileId, IQueryBuilder::PARAM_INT));
+ foreach ($extensionValues as $column => $value) {
+ $query->setValue($column, $query->createNamedParameter($value));
+ }
+ $query->execute();
+ }
+
$this->eventDispatcher->dispatch(CacheInsertEvent::class, new CacheInsertEvent($this->storage, $file, $fileId));
return $fileId;
}
@@ -324,20 +337,56 @@ class Cache implements ICache {
$data['name'] = $this->normalize($data['name']);
}
- list($queryParts, $params) = $this->buildParts($data);
- // duplicate $params because we need the parts twice in the SQL statement
- // once for the SET part, once in the WHERE clause
- $params = array_merge($params, $params);
- $params[] = $id;
+ [$values, $extensionValues] = $this->normalizeData($data);
+
+ if (count($values)) {
+ $query = $this->getQueryBuilder();
+
+ $query->update('filecache')
+ ->whereFileId($id)
+ ->andWhere($query->expr()->orX(...array_map(function ($key, $value) use ($query) {
+ return $query->expr()->orX(
+ $query->expr()->neq($key, $query->createNamedParameter($value)),
+ $query->expr()->isNull($key)
+ );
+ }, array_keys($values), array_values($values))));
+
+ foreach ($values as $key => $value) {
+ $query->set($key, $query->createNamedParameter($value));
+ }
+
+ $query->execute();
+ }
+
+ if (count($extensionValues)) {
+ try {
+ $query = $this->getQueryBuilder();
+ $query->insert('filecache_extended');
- // don't update if the data we try to set is the same as the one in the record
- // some databases (Postgres) don't like superfluous updates
- $sql = 'UPDATE `*PREFIX*filecache` SET ' . implode(' = ?, ', $queryParts) . '=? ' .
- 'WHERE (' .
- implode(' <> ? OR ', $queryParts) . ' <> ? OR ' .
- implode(' IS NULL OR ', $queryParts) . ' IS NULL' .
- ') AND `fileid` = ? ';
- $this->connection->executeQuery($sql, $params);
+ $query->setValue('fileid', $query->createNamedParameter($id, IQueryBuilder::PARAM_INT));
+ foreach ($extensionValues as $column => $value) {
+ $query->setValue($column, $query->createNamedParameter($value));
+ }
+
+ $query->execute();
+ } catch (UniqueConstraintViolationException $e) {
+ $query = $this->getQueryBuilder();
+ $query->update('filecache_extended')
+ ->whereFileId($id)
+ ->andWhere($query->expr()->orX(...array_map(function ($key, $value) use ($query) {
+ return $query->expr()->orX(
+ $query->expr()->neq($key, $query->createNamedParameter($value)),
+ $query->expr()->isNull($key)
+ );
+ }, array_keys($extensionValues), array_values($extensionValues))));
+
+ foreach ($extensionValues as $key => $value) {
+ $query->set($key, $query->createNamedParameter($value));
+ }
+
+ $query->execute();
+ }
+ }
$path = $this->getPathById($id);
// path can still be null if the file doesn't exist
@@ -350,14 +399,13 @@ class Cache implements ICache {
* extract query parts and params array from data array
*
* @param array $data
- * @return array [$queryParts, $params]
- * $queryParts: string[], the (escaped) column names to be set in the query
- * $params: mixed[], the new values for the columns, to be passed as params to the query
+ * @return array
*/
- protected function buildParts(array $data) {
- $fields = array(
+ protected function normalizeData(array $data): array {
+ $fields = [
'path', 'parent', 'name', 'mimetype', 'size', 'mtime', 'storage_mtime', 'encrypted',
- 'etag', 'permissions', 'checksum', 'storage');
+ 'etag', 'permissions', 'checksum', 'storage'];
+ $extensionFields = ['metadata_etag', 'creation_time', 'upload_time'];
$doNotCopyStorageMTime = false;
if (array_key_exists('mtime', $data) && $data['mtime'] === null) {
@@ -366,23 +414,20 @@ class Cache implements ICache {
$doNotCopyStorageMTime = true;
}
- $params = array();
- $queryParts = array();
+ $params = [];
+ $extensionParams = [];
foreach ($data as $name => $value) {
if (array_search($name, $fields) !== false) {
if ($name === 'path') {
- $params[] = md5($value);
- $queryParts[] = '`path_hash`';
- } elseif ($name === 'mimetype') {
- $params[] = $this->mimetypeLoader->getId(substr($value, 0, strpos($value, '/')));
- $queryParts[] = '`mimepart`';
+ $params['path_hash'] = md5($value);
+ } else if ($name === 'mimetype') {
+ $params['mimepart'] = $this->mimetypeLoader->getId(substr($value, 0, strpos($value, '/')));
$value = $this->mimetypeLoader->getId($value);
- } elseif ($name === 'storage_mtime') {
+ } else if ($name === 'storage_mtime') {
if (!$doNotCopyStorageMTime && !isset($data['mtime'])) {
- $params[] = $value;
- $queryParts[] = '`mtime`';
+ $params['mtime'] = $value;
}
- } elseif ($name === 'encrypted') {
+ } else if ($name === 'encrypted') {
if (isset($data['encryptedVersion'])) {
$value = $data['encryptedVersion'];
} else {
@@ -390,11 +435,13 @@ class Cache implements ICache {
$value = $value ? 1 : 0;
}
}
- $params[] = $value;
- $queryParts[] = '`' . $name . '`';
+ $params[$name] = $value;
+ }
+ if (array_search($name, $extensionFields) !== false) {
+ $extensionParams[$name] = $value;
}
}
- return array($queryParts, $params);
+ return [$params, array_filter($extensionParams)];
}
/**
@@ -411,15 +458,14 @@ class Cache implements ICache {
// normalize file
$file = $this->normalize($file);
- $pathHash = md5($file);
+ $query = $this->getQueryBuilder();
+ $query->select('fileid')
+ ->from('filecache')
+ ->whereStorageId()
+ ->wherePath($file);
- $sql = 'SELECT `fileid` FROM `*PREFIX*filecache` WHERE `storage` = ? AND `path_hash` = ?';
- $result = $this->connection->executeQuery($sql, array($this->getNumericStorageId(), $pathHash));
- if ($row = $result->fetch()) {
- return (int)$row['fileid'];
- } else {
- return -1;
- }
+ $id = $query->execute()->fetchColumn();
+ return $id === false ? -1 : (int)$id;
}
/**
@@ -464,39 +510,64 @@ class Cache implements ICache {
*/
public function remove($file) {
$entry = $this->get($file);
- $sql = 'DELETE FROM `*PREFIX*filecache` WHERE `fileid` = ?';
- $this->connection->executeQuery($sql, array($entry['fileid']));
- if ($entry['mimetype'] === 'httpd/unix-directory') {
- $this->removeChildren($entry);
+
+ if ($entry) {
+ $query = $this->getQueryBuilder();
+ $query->delete('filecache')
+ ->whereFileId($entry->getId());
+ $query->execute();
+
+ $query = $this->getQueryBuilder();
+ $query->delete('filecache_extended')
+ ->whereFileId($entry->getId());
+ $query->execute();
+
+ if ($entry->getMimeType() == FileInfo::MIMETYPE_FOLDER) {
+ $this->removeChildren($entry);
+ }
}
}
/**
* Get all sub folders of a folder
*
- * @param array $entry the cache entry of the folder to get the subfolders for
- * @return array[] the cache entries for the subfolders
+ * @param ICacheEntry $entry the cache entry of the folder to get the subfolders for
+ * @return ICacheEntry[] the cache entries for the subfolders
*/
- private function getSubFolders($entry) {
- $children = $this->getFolderContentsById($entry['fileid']);
+ private function getSubFolders(ICacheEntry $entry) {
+ $children = $this->getFolderContentsById($entry->getId());
return array_filter($children, function ($child) {
- return $child['mimetype'] === 'httpd/unix-directory';
+ return $child->getMimeType() == FileInfo::MIMETYPE_FOLDER;
});
}
/**
* Recursively remove all children of a folder
*
- * @param array $entry the cache entry of the folder to remove the children of
+ * @param ICacheEntry $entry the cache entry of the folder to remove the children of
* @throws \OC\DatabaseException
*/
- private function removeChildren($entry) {
- $subFolders = $this->getSubFolders($entry);
- foreach ($subFolders as $folder) {
+ private function removeChildren(ICacheEntry $entry) {
+ $children = $this->getFolderContentsById($entry->getId());
+ $childIds = array_map(function(ICacheEntry $cacheEntry) {
+ return $cacheEntry->getId();
+ }, $children);
+ $childFolders = array_filter($children, function ($child) {
+ return $child->getMimeType() == FileInfo::MIMETYPE_FOLDER;
+ });
+ foreach ($childFolders as $folder) {
$this->removeChildren($folder);
}
- $sql = 'DELETE FROM `*PREFIX*filecache` WHERE `parent` = ?';
- $this->connection->executeQuery($sql, array($entry['fileid']));
+
+ $query = $this->getQueryBuilder();
+ $query->delete('filecache')
+ ->whereParent($entry->getId());
+ $query->execute();
+
+ $query = $this->getQueryBuilder();
+ $query->delete('filecache_extended')
+ ->where($query->expr()->in('fileid', $query->createNamedParameter($childIds, IQueryBuilder::PARAM_INT_ARRAY)));
+ $query->execute();
}
/**
@@ -575,8 +646,16 @@ class Cache implements ICache {
}
}
- $sql = 'UPDATE `*PREFIX*filecache` SET `storage` = ?, `path` = ?, `path_hash` = ?, `name` = ?, `parent` = ? WHERE `fileid` = ?';
- $this->connection->executeQuery($sql, array($targetStorageId, $targetPath, md5($targetPath), basename($targetPath), $newParentId, $sourceId));
+ $query = $this->getQueryBuilder();
+ $query->update('filecache')
+ ->set('storage', $query->createNamedParameter($targetStorageId))
+ ->set('path', $query->createNamedParameter($targetPath))
+ ->set('path_hash', $query->createNamedParameter(md5($targetPath)))
+ ->set('name', $query->createNamedParameter(basename($targetPath)))
+ ->set('parent', $query->createNamedParameter($newParentId, IQueryBuilder::PARAM_INT))
+ ->whereFileId($sourceId);
+ $query->execute();
+
$this->connection->commit();
} else {
$this->moveFromCacheFallback($sourceCache, $sourcePath, $targetPath);
@@ -587,11 +666,15 @@ class Cache implements ICache {
* remove all entries for files that are stored on the storage from the cache
*/
public function clear() {
- $sql = 'DELETE FROM `*PREFIX*filecache` WHERE `storage` = ?';
- $this->connection->executeQuery($sql, array($this->getNumericStorageId()));
+ $query = $this->getQueryBuilder();
+ $query->delete('filecache')
+ ->whereStorageId();
+ $query->execute();
- $sql = 'DELETE FROM `*PREFIX*storages` WHERE `id` = ?';
- $this->connection->executeQuery($sql, array($this->storageId));
+ $query = $this->connection->getQueryBuilder();
+ $query->delete('storages')
+ ->where($query->expr()->eq('id', $query->createNamedParameter($this->storageId)));
+ $query->execute();
}
/**
@@ -610,11 +693,14 @@ class Cache implements ICache {
// normalize file
$file = $this->normalize($file);
- $pathHash = md5($file);
- $sql = 'SELECT `size` FROM `*PREFIX*filecache` WHERE `storage` = ? AND `path_hash` = ?';
- $result = $this->connection->executeQuery($sql, array($this->getNumericStorageId(), $pathHash));
- if ($row = $result->fetch()) {
- if ((int)$row['size'] === -1) {
+ $query = $this->getQueryBuilder();
+ $query->select('size')
+ ->from('filecache')
+ ->whereStorageId()
+ ->wherePath($file);
+ $size = $query->execute()->fetchColumn();
+ if ($size !== false) {
+ if ((int)$size === -1) {
return self::SHALLOW;
} else {
return self::COMPLETE;
@@ -642,18 +728,14 @@ class Cache implements ICache {
return [];
}
+ $query = $this->getQueryBuilder();
+ $query->selectFileCache()
+ ->whereStorageId()
+ ->andWhere($query->expr()->iLike('name', $query->createNamedParameter($pattern)));
- $sql = '
- SELECT `fileid`, `storage`, `path`, `parent`, `name`,
- `mimetype`, `storage_mtime`, `mimepart`, `size`, `mtime`,
- `encrypted`, `etag`, `permissions`, `checksum`
- FROM `*PREFIX*filecache`
- WHERE `storage` = ? AND `name` ILIKE ?';
- $result = $this->connection->executeQuery($sql,
- [$this->getNumericStorageId(), $pattern]
- );
-
- return $this->searchResultToCacheEntries($result);
+ return array_map(function (array $data) {
+ return self::cacheEntryFromData($data, $this->mimetypeLoader);
+ }, $query->execute()->fetchAll());
}
/**
@@ -676,26 +758,29 @@ class Cache implements ICache {
* @return ICacheEntry[] an array of cache entries where the mimetype matches the search
*/
public function searchByMime($mimetype) {
+ $mimeId = $this->mimetypeLoader->getId($mimetype);
+
+ $query = $this->getQueryBuilder();
+ $query->selectFileCache()
+ ->whereStorageId();
+
if (strpos($mimetype, '/')) {
- $where = '`mimetype` = ?';
+ $query->andWhere($query->expr()->eq('mimetype', $query->createNamedParameter($mimeId, IQueryBuilder::PARAM_INT)));
} else {
- $where = '`mimepart` = ?';
+ $query->andWhere($query->expr()->eq('mimepart', $query->createNamedParameter($mimeId, IQueryBuilder::PARAM_INT)));
}
- $sql = 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `storage_mtime`, `mtime`, `encrypted`, `etag`, `permissions`, `checksum`
- FROM `*PREFIX*filecache` WHERE ' . $where . ' AND `storage` = ?';
- $mimetype = $this->mimetypeLoader->getId($mimetype);
- $result = $this->connection->executeQuery($sql, array($mimetype, $this->getNumericStorageId()));
- return $this->searchResultToCacheEntries($result);
+ return array_map(function (array $data) {
+ return self::cacheEntryFromData($data, $this->mimetypeLoader);
+ }, $query->execute()->fetchAll());
}
public function searchQuery(ISearchQuery $searchQuery) {
- $builder = \OC::$server->getDatabaseConnection()->getQueryBuilder();
+ $builder = $this->getQueryBuilder();
- $query = $builder->select(['fileid', 'storage', 'path', 'parent', 'name', 'mimetype', 'mimepart', 'size', 'mtime', 'storage_mtime', 'encrypted', 'etag', 'permissions', 'checksum'])
- ->from('filecache', 'file');
+ $query = $builder->selectFileCache('file');
- $query->where($builder->expr()->eq('storage', $builder->createNamedParameter($this->getNumericStorageId())));
+ $query->whereStorageId();
if ($this->querySearchHelper->shouldJoinTags($searchQuery->getSearchOperation())) {
$query
@@ -755,10 +840,13 @@ class Cache implements ICache {
*/
public function getIncompleteChildrenCount($fileId) {
if ($fileId > -1) {
- $sql = 'SELECT count(*)
- FROM `*PREFIX*filecache` WHERE `parent` = ? AND size = -1';
- $result = $this->connection->executeQuery($sql, [$fileId]);
- return (int)$result->fetchColumn();
+ $query = $this->getQueryBuilder();
+ $query->select($query->func()->count())
+ ->from('filecache')
+ ->whereParent($fileId)
+ ->andWhere($query->expr()->lt('size', $query->createNamedParameter(0, IQueryBuilder::PARAM_INT)));
+
+ return (int)$query->execute()->fetchColumn();
}
return -1;
}
@@ -775,14 +863,17 @@ class Cache implements ICache {
if (is_null($entry) or !isset($entry['fileid'])) {
$entry = $this->get($path);
}
- if (isset($entry['mimetype']) && $entry['mimetype'] === 'httpd/unix-directory') {
+ if (isset($entry['mimetype']) && $entry['mimetype'] === FileInfo::MIMETYPE_FOLDER) {
$id = $entry['fileid'];
- $sql = 'SELECT SUM(`size`) AS f1, MIN(`size`) AS f2 ' .
- 'FROM `*PREFIX*filecache` ' .
- 'WHERE `parent` = ? AND `storage` = ?';
- $result = $this->connection->executeQuery($sql, array($id, $this->getNumericStorageId()));
- if ($row = $result->fetch()) {
- $result->closeCursor();
+
+ $query = $this->getQueryBuilder();
+ $query->selectAlias($query->func()->sum('size'), 'f1')
+ ->selectAlias($query->func()->min('size'), 'f2')
+ ->from('filecache')
+ ->whereStorageId()
+ ->whereParent($id);
+
+ if ($row = $query->execute()->fetch()) {
list($sum, $min) = array_values($row);
$sum = 0 + $sum;
$min = 0 + $min;
@@ -791,15 +882,9 @@ class Cache implements ICache {
} else {
$totalSize = $sum;
}
- $update = array();
if ($entry['size'] !== $totalSize) {
- $update['size'] = $totalSize;
- }
- if (count($update) > 0) {
- $this->update($id, $update);
+ $this->update($id, ['size' => $totalSize]);
}
- } else {
- $result->closeCursor();
}
}
return $totalSize;
@@ -811,13 +896,14 @@ class Cache implements ICache {
* @return int[]
*/
public function getAll() {
- $sql = 'SELECT `fileid` FROM `*PREFIX*filecache` WHERE `storage` = ?';
- $result = $this->connection->executeQuery($sql, array($this->getNumericStorageId()));
- $ids = array();
- while ($row = $result->fetch()) {
- $ids[] = $row['fileid'];
- }
- return $ids;
+ $query = $this->getQueryBuilder();
+ $query->select('fileid')
+ ->from('filecache')
+ ->whereStorageId();
+
+ return array_map(function ($id) {
+ return (int)$id;
+ }, $query->execute()->fetchAll(\PDO::FETCH_COLUMN));
}
/**
@@ -830,14 +916,14 @@ class Cache implements ICache {
* @return string|bool the path of the folder or false when no folder matched
*/
public function getIncomplete() {
- $query = $this->connection->prepare('SELECT `path` FROM `*PREFIX*filecache`'
- . ' WHERE `storage` = ? AND `size` = -1 ORDER BY `fileid` DESC', 1);
- $query->execute([$this->getNumericStorageId()]);
- if ($row = $query->fetch()) {
- return $row['path'];
- } else {
- return false;
- }
+ $query = $this->getQueryBuilder();
+ $query->select('path')
+ ->from('filecache')
+ ->whereStorageId()
+ ->andWhere($query->expr()->lt('size', $query->createNamedParameter(0, IQueryBuilder::PARAM_INT)))
+ ->orderBy('fileid', 'DESC');
+
+ return $query->execute()->fetchColumn();
}
/**
@@ -847,17 +933,14 @@ class Cache implements ICache {
* @return string|null the path of the file (relative to the storage) or null if a file with the given id does not exists within this cache
*/
public function getPathById($id) {
- $sql = 'SELECT `path` FROM `*PREFIX*filecache` WHERE `fileid` = ? AND `storage` = ?';
- $result = $this->connection->executeQuery($sql, array($id, $this->getNumericStorageId()));
- if ($row = $result->fetch()) {
- // Oracle stores empty strings as null...
- if ($row['path'] === null) {
- return '';
- }
- return $row['path'];
- } else {
- return null;
- }
+ $query = $this->getQueryBuilder();
+ $query->select('path')
+ ->from('filecache')
+ ->whereStorageId()
+ ->whereFileId($id);
+
+ $path = $query->execute()->fetchColumn();
+ return $path === false ? null : $path;
}
/**
@@ -866,14 +949,15 @@ class Cache implements ICache {
* instead does a global search in the cache table
*
* @param int $id
- * @deprecated use getPathById() instead
* @return array first element holding the storage id, second the path
+ * @deprecated use getPathById() instead
*/
static public function getById($id) {
- $connection = \OC::$server->getDatabaseConnection();
- $sql = 'SELECT `storage`, `path` FROM `*PREFIX*filecache` WHERE `fileid` = ?';
- $result = $connection->executeQuery($sql, array($id));
- if ($row = $result->fetch()) {
+ $query = \OC::$server->getDatabaseConnection()->getQueryBuilder();
+ $query->select('path', 'storage')
+ ->from('filecache')
+ ->where($query->expr()->eq('fileid', $query->createNamedParameter($id, IQueryBuilder::PARAM_INT)));
+ if ($row = $query->execute()->fetch()) {
$numericId = $row['storage'];
$path = $row['path'];
} else {
@@ -881,7 +965,7 @@ class Cache implements ICache {
}
if ($id = Storage::getStorageId($numericId)) {
- return array($id, $path);
+ return [$id, $path];
} else {
return null;
}
diff --git a/lib/private/Files/Cache/CacheEntry.php b/lib/private/Files/Cache/CacheEntry.php
index 4a2579a88f8..176a0bf27ed 100644
--- a/lib/private/Files/Cache/CacheEntry.php
+++ b/lib/private/Files/Cache/CacheEntry.php
@@ -109,6 +109,18 @@ class CacheEntry implements ICacheEntry, \ArrayAccess {
return isset($this->data['encrypted']) && $this->data['encrypted'];
}
+ public function getMetadataEtag(): ?string {
+ return $this->data['metadata_etag'];
+ }
+
+ public function getCreationTime(): ?int {
+ return $this->data['creation_time'];
+ }
+
+ public function getUploadTime(): ?int {
+ return $this->data['upload_time'];
+ }
+
public function getData() {
return $this->data;
}
diff --git a/lib/private/Files/Cache/CacheQueryBuilder.php b/lib/private/Files/Cache/CacheQueryBuilder.php
new file mode 100644
index 00000000000..a5ff2129de8
--- /dev/null
+++ b/lib/private/Files/Cache/CacheQueryBuilder.php
@@ -0,0 +1,92 @@
+<?php declare(strict_types=1);
+/**
+ * @copyright Copyright (c) 2019 Robin Appelman <robin@icewind.nl>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OC\Files\Cache;
+
+use OC\DB\QueryBuilder\QueryBuilder;
+use OC\SystemConfig;
+use OCP\DB\QueryBuilder\IQueryBuilder;
+use OCP\IDBConnection;
+use OCP\ILogger;
+
+/**
+ * Query builder with commonly used helpers for filecache queries
+ */
+class CacheQueryBuilder extends QueryBuilder {
+ private $cache;
+ private $alias = null;
+
+ public function __construct(IDBConnection $connection, SystemConfig $systemConfig, ILogger $logger, Cache $cache) {
+ parent::__construct($connection, $systemConfig, $logger);
+
+ $this->cache = $cache;
+ }
+
+ public function selectFileCache(string $alias = null) {
+ $name = $alias ? $alias : 'filecache';
+ $this->select("$name.fileid", 'storage', 'path', 'path_hash', "$name.parent", 'name', 'mimetype', 'mimepart', 'size', 'mtime',
+ 'storage_mtime', 'encrypted', 'etag', 'permissions', 'checksum', 'metadata_etag', 'creation_time', 'upload_time')
+ ->from('filecache', $name)
+ ->leftJoin($name, 'filecache_extended', 'fe', $this->expr()->eq("$name.fileid", 'fe.fileid'));
+
+ $this->alias = $name;
+
+ return $this;
+ }
+
+ public function whereStorageId() {
+ $this->andWhere($this->expr()->eq('storage', $this->createNamedParameter($this->cache->getNumericStorageId(), IQueryBuilder::PARAM_INT)));
+
+ return $this;
+ }
+
+ public function whereFileId(int $fileId) {
+ $alias = $this->alias;
+ if ($alias) {
+ $alias .= '.';
+ } else {
+ $alias = '';
+ }
+
+ $this->andWhere($this->expr()->eq("{$alias}fileid", $this->createNamedParameter($fileId, IQueryBuilder::PARAM_INT)));
+
+ return $this;
+ }
+
+ public function wherePath(string $path) {
+ $this->andWhere($this->expr()->eq('path_hash', $this->createNamedParameter(md5($path))));
+
+ return $this;
+ }
+
+ public function whereParent(int $parent) {
+ $alias = $this->alias;
+ if ($alias) {
+ $alias .= '.';
+ } else {
+ $alias = '';
+ }
+
+ $this->andWhere($this->expr()->eq("{$alias}parent", $this->createNamedParameter($parent, IQueryBuilder::PARAM_INT)));
+
+ return $this;
+ }
+}
diff --git a/lib/private/Files/Cache/MoveFromCacheTrait.php b/lib/private/Files/Cache/MoveFromCacheTrait.php
index a814a081dca..e9b41bd9b37 100644
--- a/lib/private/Files/Cache/MoveFromCacheTrait.php
+++ b/lib/private/Files/Cache/MoveFromCacheTrait.php
@@ -82,7 +82,10 @@ trait MoveFromCacheTrait {
'mimepart' => $entry->getMimePart(),
'etag' => $entry->getEtag(),
'permissions' => $entry->getPermissions(),
- 'encrypted' => $entry->isEncrypted()
+ 'encrypted' => $entry->isEncrypted(),
+ 'creation_time' => $entry->getCreationTime(),
+ 'upload_time' => $entry->getUploadTime(),
+ 'metadata_etag' => $entry->getMetadataEtag(),
];
}
}
diff --git a/lib/private/Files/Cache/Propagator.php b/lib/private/Files/Cache/Propagator.php
index 989a4d0c7d5..41b4c2bb070 100644
--- a/lib/private/Files/Cache/Propagator.php
+++ b/lib/private/Files/Cache/Propagator.php
@@ -91,7 +91,7 @@ class Propagator implements IPropagator {
}, $parentHashes);
$builder->update('filecache')
- ->set('mtime', $builder->createFunction('GREATEST(' . $builder->getColumnName('mtime') . ', ' . $builder->createNamedParameter((int)$time, IQueryBuilder::PARAM_INT) . ')'))
+ ->set('mtime', $builder->func()->greatest('mtime', $builder->createNamedParameter((int)$time, IQueryBuilder::PARAM_INT)))
->set('etag', $builder->createNamedParameter($etag, IQueryBuilder::PARAM_STR))
->where($builder->expr()->eq('storage', $builder->createNamedParameter($storageId, IQueryBuilder::PARAM_INT)))
->andWhere($builder->expr()->in('path_hash', $hashParams));
@@ -102,7 +102,10 @@ class Propagator implements IPropagator {
// we need to do size separably so we can ignore entries with uncalculated size
$builder = $this->connection->getQueryBuilder();
$builder->update('filecache')
- ->set('size', $builder->func()->add('size', $builder->createNamedParameter($sizeDifference)))
+ ->set('size', $builder->func()->greatest(
+ $builder->createNamedParameter(-1, IQueryBuilder::PARAM_INT),
+ $builder->func()->add('size', $builder->createNamedParameter($sizeDifference)))
+ )
->where($builder->expr()->eq('storage', $builder->createNamedParameter($storageId, IQueryBuilder::PARAM_INT)))
->andWhere($builder->expr()->in('path_hash', $hashParams))
->andWhere($builder->expr()->gt('size', $builder->expr()->literal(-1, IQueryBuilder::PARAM_INT)));
diff --git a/lib/private/Files/Cache/QuerySearchHelper.php b/lib/private/Files/Cache/QuerySearchHelper.php
index ac64ba5c592..2d9d8f374f7 100644
--- a/lib/private/Files/Cache/QuerySearchHelper.php
+++ b/lib/private/Files/Cache/QuerySearchHelper.php
@@ -136,16 +136,19 @@ class QuerySearchHelper {
$type = $operator->getType();
if ($field === 'mimetype') {
if ($operator->getType() === ISearchComparison::COMPARE_EQUAL) {
- $value = $this->mimetypeLoader->getId($value);
+ $value = (int)$this->mimetypeLoader->getId($value);
} else if ($operator->getType() === ISearchComparison::COMPARE_LIKE) {
// transform "mimetype='foo/%'" to "mimepart='foo'"
if (preg_match('|(.+)/%|', $value, $matches)) {
$field = 'mimepart';
- $value = $this->mimetypeLoader->getId($matches[1]);
+ $value = (int)$this->mimetypeLoader->getId($matches[1]);
$type = ISearchComparison::COMPARE_EQUAL;
- }
- if (strpos($value, '%') !== false) {
+ } else if (strpos($value, '%') !== false) {
throw new \InvalidArgumentException('Unsupported query value for mimetype: ' . $value . ', only values in the format "mime/type" or "mime/%" are supported');
+ } else {
+ $field = 'mimetype';
+ $value = (int)$this->mimetypeLoader->getId($value);
+ $type = ISearchComparison::COMPARE_EQUAL;
}
}
} else if ($field === 'favorite') {
diff --git a/lib/private/Files/Cache/Storage.php b/lib/private/Files/Cache/Storage.php
index 5b37c1f43f8..c076cc28359 100644
--- a/lib/private/Files/Cache/Storage.php
+++ b/lib/private/Files/Cache/Storage.php
@@ -81,7 +81,7 @@ class Storage {
if ($row = self::getStorageById($this->storageId)) {
$this->numericId = (int)$row['numeric_id'];
} else {
- throw new \RuntimeException('Storage could neither be inserted nor be selected from the database');
+ throw new \RuntimeException('Storage could neither be inserted nor be selected from the database: ' . $this->storageId);
}
}
}
@@ -166,11 +166,12 @@ class Storage {
/**
* @param bool $isAvailable
+ * @param int $delay amount of seconds to delay reconsidering that storage further
*/
- public function setAvailability($isAvailable) {
+ public function setAvailability($isAvailable, int $delay = 0) {
$sql = 'UPDATE `*PREFIX*storages` SET `available` = ?, `last_checked` = ? WHERE `id` = ?';
$available = $isAvailable ? 1 : 0;
- \OC_DB::executeAudited($sql, array($available, time(), $this->storageId));
+ \OC_DB::executeAudited($sql, [$available, time() + $delay, $this->storageId]);
}
/**
diff --git a/lib/private/Files/Cache/StorageGlobal.php b/lib/private/Files/Cache/StorageGlobal.php
index 65f689f1874..076b5b8f53d 100644
--- a/lib/private/Files/Cache/StorageGlobal.php
+++ b/lib/private/Files/Cache/StorageGlobal.php
@@ -69,7 +69,15 @@ class StorageGlobal {
*/
public function getStorageInfo($storageId) {
if (!isset($this->cache[$storageId])) {
- $this->loadForStorageIds([$storageId]);
+ $builder = $this->connection->getQueryBuilder();
+ $query = $builder->select(['id', 'numeric_id', 'available', 'last_checked'])
+ ->from('storages')
+ ->where($builder->expr()->eq('id', $builder->createNamedParameter($storageId)));
+
+ $row = $query->execute()->fetch();
+ if ($row) {
+ $this->cache[$storageId] = $row;
+ }
}
return isset($this->cache[$storageId]) ? $this->cache[$storageId] : null;
}
diff --git a/lib/private/Files/Cache/Watcher.php b/lib/private/Files/Cache/Watcher.php
index 47dde26d7b7..8c5cb0db182 100644
--- a/lib/private/Files/Cache/Watcher.php
+++ b/lib/private/Files/Cache/Watcher.php
@@ -85,7 +85,7 @@ class Watcher implements IWatcher {
if (is_null($cachedEntry)) {
$cachedEntry = $this->cache->get($path);
}
- if ($this->needsUpdate($path, $cachedEntry)) {
+ if ($cachedEntry === false || $this->needsUpdate($path, $cachedEntry)) {
$this->update($path, $cachedEntry);
return true;
} else {
@@ -105,7 +105,7 @@ class Watcher implements IWatcher {
} else {
$this->scanner->scanFile($path);
}
- if ($cachedData['mimetype'] === 'httpd/unix-directory') {
+ if (is_array($cachedData) && $cachedData['mimetype'] === 'httpd/unix-directory') {
$this->cleanFolder($path);
}
if ($this->cache instanceof Cache) {
diff --git a/lib/private/Files/Cache/Wrapper/CacheWrapper.php b/lib/private/Files/Cache/Wrapper/CacheWrapper.php
index 6d7f1876e29..157bb083b73 100644
--- a/lib/private/Files/Cache/Wrapper/CacheWrapper.php
+++ b/lib/private/Files/Cache/Wrapper/CacheWrapper.php
@@ -28,8 +28,8 @@
namespace OC\Files\Cache\Wrapper;
use OC\Files\Cache\Cache;
-use OCP\Files\Cache\ICacheEntry;
use OCP\Files\Cache\ICache;
+use OCP\Files\Cache\ICacheEntry;
use OCP\Files\Search\ISearchQuery;
class CacheWrapper extends Cache {
diff --git a/lib/private/Files/Config/CachedMountFileInfo.php b/lib/private/Files/Config/CachedMountFileInfo.php
index e315493a693..331e28d3d5e 100644
--- a/lib/private/Files/Config/CachedMountFileInfo.php
+++ b/lib/private/Files/Config/CachedMountFileInfo.php
@@ -45,4 +45,4 @@ class CachedMountFileInfo extends CachedMountInfo implements ICachedMountFileInf
public function getPath() {
return $this->getMountPoint() . $this->getInternalPath();
}
-} \ No newline at end of file
+}
diff --git a/lib/private/Files/Config/MountProviderCollection.php b/lib/private/Files/Config/MountProviderCollection.php
index a3c88dd6b4b..fbb455c5063 100644
--- a/lib/private/Files/Config/MountProviderCollection.php
+++ b/lib/private/Files/Config/MountProviderCollection.php
@@ -26,8 +26,8 @@ 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\IMountProviderCollection;
use OCP\Files\Config\IUserMountCache;
use OCP\Files\Mount\IMountManager;
use OCP\Files\Mount\IMountPoint;
diff --git a/lib/private/Files/Config/UserMountCache.php b/lib/private/Files/Config/UserMountCache.php
index 63abdf5fdeb..53bd52a2e6c 100644
--- a/lib/private/Files/Config/UserMountCache.php
+++ b/lib/private/Files/Config/UserMountCache.php
@@ -25,6 +25,7 @@
namespace OC\Files\Config;
+use OC\Cache\CappedMemoryCache;
use OCA\Files_Sharing\SharedMount;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\Files\Config\ICachedMountFileInfo;
@@ -37,7 +38,6 @@ use OCP\IDBConnection;
use OCP\ILogger;
use OCP\IUser;
use OCP\IUserManager;
-use OC\Cache\CappedMemoryCache;
/**
* Cache mounts points per user in the cache so we can easilly look them up
diff --git a/lib/private/Files/FileInfo.php b/lib/private/Files/FileInfo.php
index 19b95cd0355..93f876db17b 100644
--- a/lib/private/Files/FileInfo.php
+++ b/lib/private/Files/FileInfo.php
@@ -406,4 +406,12 @@ class FileInfo implements \OCP\Files\FileInfo, \ArrayAccess {
public function getExtension(): string {
return pathinfo($this->getName(), PATHINFO_EXTENSION);
}
+
+ public function getCreationTime(): int {
+ return (int) $this->data['creation_time'];
+ }
+
+ public function getUploadTime(): int {
+ return (int) $this->data['upload_time'];
+ }
}
diff --git a/lib/private/Files/Mount/MountPoint.php b/lib/private/Files/Mount/MountPoint.php
index 36e10bfb45a..1e67eecb9dc 100644
--- a/lib/private/Files/Mount/MountPoint.php
+++ b/lib/private/Files/Mount/MountPoint.php
@@ -29,9 +29,9 @@
namespace OC\Files\Mount;
-use \OC\Files\Filesystem;
-use OC\Files\Storage\StorageFactory;
+use OC\Files\Filesystem;
use OC\Files\Storage\Storage;
+use OC\Files\Storage\StorageFactory;
use OCP\Files\Mount\IMountPoint;
use OCP\ILogger;
diff --git a/lib/private/Files/Node/File.php b/lib/private/Files/Node/File.php
index a3eabbcc446..e4669f70709 100644
--- a/lib/private/Files/Node/File.php
+++ b/lib/private/Files/Node/File.php
@@ -28,6 +28,7 @@ namespace OC\Files\Node;
use OCP\Files\GenericFileException;
use OCP\Files\NotPermittedException;
+use OCP\Lock\LockedException;
class File extends Node implements \OCP\Files\File {
/**
@@ -42,7 +43,8 @@ class File extends Node implements \OCP\Files\File {
/**
* @return string
- * @throws \OCP\Files\NotPermittedException
+ * @throws NotPermittedException
+ * @throws LockedException
*/
public function getContent() {
if ($this->checkPermissions(\OCP\Constants::PERMISSION_READ)) {
@@ -57,8 +59,9 @@ class File extends Node implements \OCP\Files\File {
/**
* @param string|resource $data
- * @throws \OCP\Files\NotPermittedException
+ * @throws NotPermittedException
* @throws \OCP\Files\GenericFileException
+ * @throws LockedException
*/
public function putContent($data) {
if ($this->checkPermissions(\OCP\Constants::PERMISSION_UPDATE)) {
@@ -76,7 +79,8 @@ class File extends Node implements \OCP\Files\File {
/**
* @param string $mode
* @return resource
- * @throws \OCP\Files\NotPermittedException
+ * @throws NotPermittedException
+ * @throws LockedException
*/
public function fopen($mode) {
$preHooks = array();
@@ -113,13 +117,18 @@ class File extends Node implements \OCP\Files\File {
}
}
+ /**
+ * @throws NotPermittedException
+ * @throws \OCP\Files\InvalidPathException
+ * @throws \OCP\Files\NotFoundException
+ */
public function delete() {
if ($this->checkPermissions(\OCP\Constants::PERMISSION_DELETE)) {
$this->sendHooks(array('preDelete'));
$fileInfo = $this->getFileInfo();
$this->view->unlink($this->path);
$nonExisting = new NonExistingFile($this->root, $this->view, $this->path, $fileInfo);
- $this->root->emit('\OC\Files', 'postDelete', array($nonExisting));
+ $this->sendHooks(['postDelete'], [$nonExisting]);
$this->exists = false;
$this->fileInfo = null;
} else {
diff --git a/lib/private/Files/Node/Folder.php b/lib/private/Files/Node/Folder.php
index 19f04048779..4a134cdcdbf 100644
--- a/lib/private/Files/Node/Folder.php
+++ b/lib/private/Files/Node/Folder.php
@@ -156,14 +156,12 @@ class Folder extends Node implements \OCP\Files\Folder {
if ($this->checkPermissions(\OCP\Constants::PERMISSION_CREATE)) {
$fullPath = $this->getFullPath($path);
$nonExisting = new NonExistingFolder($this->root, $this->view, $fullPath);
- $this->root->emit('\OC\Files', 'preWrite', array($nonExisting));
- $this->root->emit('\OC\Files', 'preCreate', array($nonExisting));
+ $this->sendHooks(['preWrite', 'preCreate'], [$nonExisting]);
if(!$this->view->mkdir($fullPath)) {
throw new NotPermittedException('Could not create folder');
}
$node = new Folder($this->root, $this->view, $fullPath);
- $this->root->emit('\OC\Files', 'postWrite', array($node));
- $this->root->emit('\OC\Files', 'postCreate', array($node));
+ $this->sendHooks(['postWrite', 'postCreate'], [$node]);
return $node;
} else {
throw new NotPermittedException('No create permission for folder');
@@ -179,14 +177,12 @@ class Folder extends Node implements \OCP\Files\Folder {
if ($this->checkPermissions(\OCP\Constants::PERMISSION_CREATE)) {
$fullPath = $this->getFullPath($path);
$nonExisting = new NonExistingFile($this->root, $this->view, $fullPath);
- $this->root->emit('\OC\Files', 'preWrite', array($nonExisting));
- $this->root->emit('\OC\Files', 'preCreate', array($nonExisting));
+ $this->sendHooks(['preWrite', 'preCreate'], [$nonExisting]);
if (!$this->view->touch($fullPath)) {
throw new NotPermittedException('Could not create path');
}
$node = new File($this->root, $this->view, $fullPath);
- $this->root->emit('\OC\Files', 'postWrite', array($node));
- $this->root->emit('\OC\Files', 'postCreate', array($node));
+ $this->sendHooks(['postWrite', 'postCreate'], [$node]);
return $node;
}
throw new NotPermittedException('No create permission for path');
@@ -303,6 +299,9 @@ class Folder extends Node implements \OCP\Files\Folder {
}));
if (count($mountsContainingFile) === 0) {
+ if ($user === $this->getAppDataDirectoryName()) {
+ return $this->getByIdInRootMount((int) $id);
+ }
return [];
}
@@ -331,6 +330,47 @@ class Folder extends Node implements \OCP\Files\Folder {
});
}
+ protected function getAppDataDirectoryName(): string {
+ $instanceId = \OC::$server->getConfig()->getSystemValueString('instanceid');
+ return 'appdata_' . $instanceId;
+ }
+
+ /**
+ * In case the path we are currently in is inside the appdata_* folder,
+ * the original getById method does not work, because it can only look inside
+ * the user's mount points. But the user has no mount point for the root storage.
+ *
+ * So in that case we directly check the mount of the root if it contains
+ * the id. If it does we check if the path is inside the path we are working
+ * in.
+ *
+ * @param int $id
+ * @return array
+ */
+ protected function getByIdInRootMount(int $id): array {
+ $mount = $this->root->getMount('');
+ $cacheEntry = $mount->getStorage()->getCache($this->path)->get($id);
+ if (!$cacheEntry) {
+ return [];
+ }
+
+ $absolutePath = '/' . ltrim($cacheEntry->getPath(), '/');
+ $currentPath = rtrim($this->path, '/') . '/';
+
+ if (strpos($absolutePath, $currentPath) !== 0) {
+ return [];
+ }
+
+ return [$this->root->createNode(
+ $absolutePath, new \OC\Files\FileInfo(
+ $absolutePath,
+ $mount->getStorage(),
+ $cacheEntry->getPath(),
+ $cacheEntry,
+ $mount
+ ))];
+ }
+
public function getFreeSpace() {
return $this->view->free_space($this->path);
}
@@ -341,7 +381,7 @@ class Folder extends Node implements \OCP\Files\Folder {
$fileInfo = $this->getFileInfo();
$this->view->rmdir($this->path);
$nonExisting = new NonExistingFolder($this->root, $this->view, $this->path, $fileInfo);
- $this->root->emit('\OC\Files', 'postDelete', array($nonExisting));
+ $this->sendHooks(['postDelete'], [$nonExisting]);
$this->exists = false;
} else {
throw new NotPermittedException('No delete permission for path');
diff --git a/lib/private/Files/Node/HookConnector.php b/lib/private/Files/Node/HookConnector.php
index f5adcde4a00..417bb4980ee 100644
--- a/lib/private/Files/Node/HookConnector.php
+++ b/lib/private/Files/Node/HookConnector.php
@@ -22,10 +22,12 @@
namespace OC\Files\Node;
-use OCP\Files\FileInfo;
use OC\Files\Filesystem;
use OC\Files\View;
+use OCP\EventDispatcher\GenericEvent;
+use OCP\Files\FileInfo;
use OCP\Util;
+use Symfony\Component\EventDispatcher\EventDispatcherInterface;
class HookConnector {
/**
@@ -42,6 +44,8 @@ class HookConnector {
* @var FileInfo[]
*/
private $deleteMetaCache = [];
+ /** @var EventDispatcherInterface */
+ private $dispatcher;
/**
* HookConnector constructor.
@@ -49,9 +53,10 @@ class HookConnector {
* @param Root $root
* @param View $view
*/
- public function __construct(Root $root, View $view) {
+ public function __construct(Root $root, View $view, EventDispatcherInterface $dispatcher) {
$this->root = $root;
$this->view = $view;
+ $this->dispatcher = $dispatcher;
}
public function viewToNode() {
@@ -79,72 +84,85 @@ class HookConnector {
public function write($arguments) {
$node = $this->getNodeForPath($arguments['path']);
$this->root->emit('\OC\Files', 'preWrite', [$node]);
+ $this->dispatcher->dispatch('\OCP\Files::preWrite', new GenericEvent($node));
}
public function postWrite($arguments) {
$node = $this->getNodeForPath($arguments['path']);
$this->root->emit('\OC\Files', 'postWrite', [$node]);
+ $this->dispatcher->dispatch('\OCP\Files::postWrite', new GenericEvent($node));
}
public function create($arguments) {
$node = $this->getNodeForPath($arguments['path']);
$this->root->emit('\OC\Files', 'preCreate', [$node]);
+ $this->dispatcher->dispatch('\OCP\Files::preCreate', new GenericEvent($node));
}
public function postCreate($arguments) {
$node = $this->getNodeForPath($arguments['path']);
$this->root->emit('\OC\Files', 'postCreate', [$node]);
+ $this->dispatcher->dispatch('\OCP\Files::postCreate', new GenericEvent($node));
}
public function delete($arguments) {
$node = $this->getNodeForPath($arguments['path']);
$this->deleteMetaCache[$node->getPath()] = $node->getFileInfo();
$this->root->emit('\OC\Files', 'preDelete', [$node]);
+ $this->dispatcher->dispatch('\OCP\Files::preDelete', new GenericEvent($node));
}
public function postDelete($arguments) {
$node = $this->getNodeForPath($arguments['path']);
unset($this->deleteMetaCache[$node->getPath()]);
$this->root->emit('\OC\Files', 'postDelete', [$node]);
+ $this->dispatcher->dispatch('\OCP\Files::postDelete', new GenericEvent($node));
}
public function touch($arguments) {
$node = $this->getNodeForPath($arguments['path']);
$this->root->emit('\OC\Files', 'preTouch', [$node]);
+ $this->dispatcher->dispatch('\OCP\Files::preTouch', new GenericEvent($node));
}
public function postTouch($arguments) {
$node = $this->getNodeForPath($arguments['path']);
$this->root->emit('\OC\Files', 'postTouch', [$node]);
+ $this->dispatcher->dispatch('\OCP\Files::postTouch', new GenericEvent($node));
}
public function rename($arguments) {
$source = $this->getNodeForPath($arguments['oldpath']);
$target = $this->getNodeForPath($arguments['newpath']);
$this->root->emit('\OC\Files', 'preRename', [$source, $target]);
+ $this->dispatcher->dispatch('\OCP\Files::preRename', new GenericEvent([$source, $target]));
}
public function postRename($arguments) {
$source = $this->getNodeForPath($arguments['oldpath']);
$target = $this->getNodeForPath($arguments['newpath']);
$this->root->emit('\OC\Files', 'postRename', [$source, $target]);
+ $this->dispatcher->dispatch('\OCP\Files::postRename', new GenericEvent([$source, $target]));
}
public function copy($arguments) {
$source = $this->getNodeForPath($arguments['oldpath']);
$target = $this->getNodeForPath($arguments['newpath']);
$this->root->emit('\OC\Files', 'preCopy', [$source, $target]);
+ $this->dispatcher->dispatch('\OCP\Files::preCopy', new GenericEvent([$source, $target]));
}
public function postCopy($arguments) {
$source = $this->getNodeForPath($arguments['oldpath']);
$target = $this->getNodeForPath($arguments['newpath']);
$this->root->emit('\OC\Files', 'postCopy', [$source, $target]);
+ $this->dispatcher->dispatch('\OCP\Files::postCopy', new GenericEvent([$source, $target]));
}
public function read($arguments) {
$node = $this->getNodeForPath($arguments['path']);
$this->root->emit('\OC\Files', 'read', [$node]);
+ $this->dispatcher->dispatch('\OCP\Files::read', new GenericEvent([$node]));
}
private function getNodeForPath($path) {
diff --git a/lib/private/Files/Node/LazyRoot.php b/lib/private/Files/Node/LazyRoot.php
index 01b4ca52765..acf288860d9 100644
--- a/lib/private/Files/Node/LazyRoot.php
+++ b/lib/private/Files/Node/LazyRoot.php
@@ -20,6 +20,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
+
namespace OC\Files\Node;
use OCP\Files\IRootFolder;
@@ -480,4 +481,18 @@ class LazyRoot implements IRootFolder {
public function getRecent($limit, $offset = 0) {
return $this->__call(__FUNCTION__, func_get_args());
}
+
+ /**
+ * @inheritDoc
+ */
+ public function getCreationTime(): int {
+ return $this->__call(__FUNCTION__, func_get_args());
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function getUploadTime(): int {
+ return $this->__call(__FUNCTION__, func_get_args());
+ }
}
diff --git a/lib/private/Files/Node/Node.php b/lib/private/Files/Node/Node.php
index dc025b79575..7f50524f28d 100644
--- a/lib/private/Files/Node/Node.php
+++ b/lib/private/Files/Node/Node.php
@@ -33,6 +33,8 @@ use OCP\Files\FileInfo;
use OCP\Files\InvalidPathException;
use OCP\Files\NotFoundException;
use OCP\Files\NotPermittedException;
+use OCP\Lock\LockedException;
+use Symfony\Component\EventDispatcher\GenericEvent;
// FIXME: this class really should be abstract
class Node implements \OCP\Files\Node {
@@ -74,6 +76,7 @@ class Node implements \OCP\Files\Node {
*
* @param string $path path
* @return string non-existing node class
+ * @throws \Exception
*/
protected function createNonExistingNode($path) {
throw new \Exception('Must be implemented by subclasses');
@@ -104,15 +107,20 @@ class Node implements \OCP\Files\Node {
/**
* @param string[] $hooks
*/
- protected function sendHooks($hooks) {
+ protected function sendHooks($hooks, array $args = null) {
+ $args = !empty($args) ? $args : [$this];
+ $dispatcher = \OC::$server->getEventDispatcher();
foreach ($hooks as $hook) {
- $this->root->emit('\OC\Files', $hook, array($this));
+ $this->root->emit('\OC\Files', $hook, $args);
+ $dispatcher->dispatch('\OCP\Files::' . $hook, new GenericEvent($args));
}
}
/**
* @param int $permissions
* @return bool
+ * @throws InvalidPathException
+ * @throws NotFoundException
*/
protected function checkPermissions($permissions) {
return ($this->getPermissions() & $permissions) === $permissions;
@@ -123,7 +131,9 @@ class Node implements \OCP\Files\Node {
/**
* @param int $mtime
- * @throws \OCP\Files\NotPermittedException
+ * @throws InvalidPathException
+ * @throws NotFoundException
+ * @throws NotPermittedException
*/
public function touch($mtime = null) {
if ($this->checkPermissions(\OCP\Constants::PERMISSION_UPDATE)) {
@@ -362,7 +372,7 @@ class Node implements \OCP\Files\Node {
/**
* @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
- * @throws \OCP\Lock\LockedException
+ * @throws LockedException
*/
public function lock($type) {
$this->view->lockFile($this->path, $type);
@@ -370,7 +380,7 @@ class Node implements \OCP\Files\Node {
/**
* @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
- * @throws \OCP\Lock\LockedException
+ * @throws LockedException
*/
public function changeLock($type) {
$this->view->changeLock($this->path, $type);
@@ -378,7 +388,7 @@ class Node implements \OCP\Files\Node {
/**
* @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
- * @throws \OCP\Lock\LockedException
+ * @throws LockedException
*/
public function unlock($type) {
$this->view->unlockFile($this->path, $type);
@@ -386,22 +396,24 @@ class Node implements \OCP\Files\Node {
/**
* @param string $targetPath
- * @throws \OCP\Files\NotPermittedException if copy not allowed or failed
* @return \OC\Files\Node\Node
+ * @throws InvalidPathException
+ * @throws NotFoundException
+ * @throws NotPermittedException if copy not allowed or failed
*/
public function copy($targetPath) {
$targetPath = $this->normalizePath($targetPath);
$parent = $this->root->get(dirname($targetPath));
if ($parent instanceof Folder and $this->isValidPath($targetPath) and $parent->isCreatable()) {
$nonExisting = $this->createNonExistingNode($targetPath);
- $this->root->emit('\OC\Files', 'preCopy', [$this, $nonExisting]);
- $this->root->emit('\OC\Files', 'preWrite', [$nonExisting]);
+ $this->sendHooks(['preCopy'], [$this, $nonExisting]);
+ $this->sendHooks(['preWrite'], [$nonExisting]);
if (!$this->view->copy($this->path, $targetPath)) {
throw new NotPermittedException('Could not copy ' . $this->path . ' to ' . $targetPath);
}
$targetNode = $this->root->get($targetPath);
- $this->root->emit('\OC\Files', 'postCopy', [$this, $targetNode]);
- $this->root->emit('\OC\Files', 'postWrite', [$targetNode]);
+ $this->sendHooks(['postCopy'], [$this, $targetNode]);
+ $this->sendHooks(['postWrite'], [$targetNode]);
return $targetNode;
} else {
throw new NotPermittedException('No permission to copy to path ' . $targetPath);
@@ -410,8 +422,11 @@ class Node implements \OCP\Files\Node {
/**
* @param string $targetPath
- * @throws \OCP\Files\NotPermittedException if move not allowed or failed
* @return \OC\Files\Node\Node
+ * @throws InvalidPathException
+ * @throws NotFoundException
+ * @throws NotPermittedException if move not allowed or failed
+ * @throws LockedException
*/
public function move($targetPath) {
$targetPath = $this->normalizePath($targetPath);
@@ -425,14 +440,14 @@ class Node implements \OCP\Files\Node {
)
) {
$nonExisting = $this->createNonExistingNode($targetPath);
- $this->root->emit('\OC\Files', 'preRename', [$this, $nonExisting]);
- $this->root->emit('\OC\Files', 'preWrite', [$nonExisting]);
+ $this->sendHooks(['preRename'], [$this, $nonExisting]);
+ $this->sendHooks(['preWrite'], [$nonExisting]);
if (!$this->view->rename($this->path, $targetPath)) {
throw new NotPermittedException('Could not move ' . $this->path . ' to ' . $targetPath);
}
$targetNode = $this->root->get($targetPath);
- $this->root->emit('\OC\Files', 'postRename', [$this, $targetNode]);
- $this->root->emit('\OC\Files', 'postWrite', [$targetNode]);
+ $this->sendHooks(['postRename'], [$this, $targetNode]);
+ $this->sendHooks(['postWrite'], [$targetNode]);
$this->path = $targetPath;
return $targetNode;
} else {
@@ -440,4 +455,12 @@ class Node implements \OCP\Files\Node {
}
}
+ public function getCreationTime(): int {
+ return $this->getFileInfo()->getCreationTime();
+ }
+
+ public function getUploadTime(): int {
+ return $this->getFileInfo()->getUploadTime();
+ }
+
}
diff --git a/lib/private/Files/Node/Root.php b/lib/private/Files/Node/Root.php
index 390d29edb31..ad0935ebaf7 100644
--- a/lib/private/Files/Node/Root.php
+++ b/lib/private/Files/Node/Root.php
@@ -33,11 +33,11 @@ namespace OC\Files\Node;
use OC\Cache\CappedMemoryCache;
use OC\Files\Mount\Manager;
use OC\Files\Mount\MountPoint;
+use OC\Hooks\PublicEmitter;
use OCP\Files\Config\IUserMountCache;
+use OCP\Files\IRootFolder;
use OCP\Files\NotFoundException;
use OCP\Files\NotPermittedException;
-use OC\Hooks\PublicEmitter;
-use OCP\Files\IRootFolder;
use OCP\ILogger;
use OCP\IUserManager;
diff --git a/lib/private/Files/ObjectStore/HomeObjectStoreStorage.php b/lib/private/Files/ObjectStore/HomeObjectStoreStorage.php
index fb5e8d83ab1..fd6c9a2ebc1 100644
--- a/lib/private/Files/ObjectStore/HomeObjectStoreStorage.php
+++ b/lib/private/Files/ObjectStore/HomeObjectStoreStorage.php
@@ -66,4 +66,4 @@ class HomeObjectStoreStorage extends ObjectStoreStorage implements \OCP\Files\IH
}
-} \ No newline at end of file
+}
diff --git a/lib/private/Files/ObjectStore/Mapper.php b/lib/private/Files/ObjectStore/Mapper.php
index 2b5cf6ea4ab..c4b5e5d7778 100644
--- a/lib/private/Files/ObjectStore/Mapper.php
+++ b/lib/private/Files/ObjectStore/Mapper.php
@@ -20,6 +20,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
+
namespace OC\Files\ObjectStore;
use OCP\IUser;
diff --git a/lib/private/Files/ObjectStore/NoopScanner.php b/lib/private/Files/ObjectStore/NoopScanner.php
index a3a396651a2..1ee868c49d4 100644
--- a/lib/private/Files/ObjectStore/NoopScanner.php
+++ b/lib/private/Files/ObjectStore/NoopScanner.php
@@ -24,8 +24,8 @@
*/
namespace OC\Files\ObjectStore;
-use \OC\Files\Cache\Scanner;
-use \OC\Files\Storage\Storage;
+use OC\Files\Cache\Scanner;
+use OC\Files\Storage\Storage;
class NoopScanner extends Scanner {
diff --git a/lib/private/Files/ObjectStore/ObjectStoreStorage.php b/lib/private/Files/ObjectStore/ObjectStoreStorage.php
index fbfbcfaa409..80f438d762c 100644
--- a/lib/private/Files/ObjectStore/ObjectStoreStorage.php
+++ b/lib/private/Files/ObjectStore/ObjectStoreStorage.php
@@ -161,7 +161,9 @@ class ObjectStoreStorage extends \OC\Files\Storage\Common {
return false;
}
- $this->rmObjects($path);
+ if (!$this->rmObjects($path)) {
+ return false;
+ }
$this->getCache()->remove($path);
@@ -172,11 +174,17 @@ class ObjectStoreStorage extends \OC\Files\Storage\Common {
$children = $this->getCache()->getFolderContents($path);
foreach ($children as $child) {
if ($child['mimetype'] === 'httpd/unix-directory') {
- $this->rmObjects($child['path']);
+ if (!$this->rmObjects($child['path'])) {
+ return false;
+ }
} else {
- $this->unlink($child['path']);
+ if(!$this->unlink($child['path'])) {
+ return false;
+ }
}
}
+
+ return true;
}
public function unlink($path) {
diff --git a/lib/private/Files/ObjectStore/SwiftFactory.php b/lib/private/Files/ObjectStore/SwiftFactory.php
index f6270d36e7a..430d628d3ce 100644
--- a/lib/private/Files/ObjectStore/SwiftFactory.php
+++ b/lib/private/Files/ObjectStore/SwiftFactory.php
@@ -31,15 +31,15 @@ use OCP\Files\StorageAuthException;
use OCP\Files\StorageNotAvailableException;
use OCP\ICache;
use OCP\ILogger;
-use OpenStack\Common\Error\BadResponseError;
use OpenStack\Common\Auth\Token;
+use OpenStack\Common\Error\BadResponseError;
+use OpenStack\Common\Transport\Utils as TransportUtils;
use OpenStack\Identity\v2\Models\Catalog;
use OpenStack\Identity\v2\Service as IdentityV2Service;
use OpenStack\Identity\v3\Service as IdentityV3Service;
+use OpenStack\ObjectStore\v1\Models\Container;
use OpenStack\OpenStack;
-use OpenStack\Common\Transport\Utils as TransportUtils;
use Psr\Http\Message\RequestInterface;
-use OpenStack\ObjectStore\v1\Models\Container;
class SwiftFactory {
private $cache;
diff --git a/lib/private/Files/SimpleFS/SimpleFile.php b/lib/private/Files/SimpleFS/SimpleFile.php
index 9c9ca10650c..85a1a64a854 100644
--- a/lib/private/Files/SimpleFS/SimpleFile.php
+++ b/lib/private/Files/SimpleFS/SimpleFile.php
@@ -20,6 +20,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
+
namespace OC\Files\SimpleFS;
use OCP\Files\File;
diff --git a/lib/private/Files/SimpleFS/SimpleFolder.php b/lib/private/Files/SimpleFS/SimpleFolder.php
index 5b55fe0f157..9375a3c5545 100644
--- a/lib/private/Files/SimpleFS/SimpleFolder.php
+++ b/lib/private/Files/SimpleFS/SimpleFolder.php
@@ -20,6 +20,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
+
namespace OC\Files\SimpleFS;
use OCP\Files\File;
diff --git a/lib/private/Files/Storage/Common.php b/lib/private/Files/Storage/Common.php
index 4e95c594cfa..3bc14d35cd0 100644
--- a/lib/private/Files/Storage/Common.php
+++ b/lib/private/Files/Storage/Common.php
@@ -44,8 +44,10 @@ use OC\Files\Cache\Cache;
use OC\Files\Cache\Propagator;
use OC\Files\Cache\Scanner;
use OC\Files\Cache\Updater;
-use OC\Files\Filesystem;
use OC\Files\Cache\Watcher;
+use OC\Files\Filesystem;
+use OC\Files\Storage\Wrapper\Jail;
+use OC\Files\Storage\Wrapper\Wrapper;
use OCP\Files\EmptyFileNameException;
use OCP\Files\FileNameTooLongException;
use OCP\Files\InvalidCharacterInPathException;
@@ -636,13 +638,39 @@ abstract class Common implements Storage, ILockingStorage, IWriteStreamStorage {
}
/**
+ * Check if a storage is the same as the current one, including wrapped storages
+ *
+ * @param IStorage $storage
+ * @return bool
+ */
+ private function isSameStorage(IStorage $storage): bool {
+ while ($storage->instanceOfStorage(Wrapper::class)) {
+ /**
+ * @var Wrapper $sourceStorage
+ */
+ $storage = $storage->getWrapperStorage();
+ }
+
+ return $storage === $this;
+ }
+
+ /**
* @param IStorage $sourceStorage
* @param string $sourceInternalPath
* @param string $targetInternalPath
* @return bool
*/
public function moveFromStorage(IStorage $sourceStorage, $sourceInternalPath, $targetInternalPath) {
- if ($sourceStorage === $this) {
+ if ($this->isSameStorage($sourceStorage)) {
+ // resolve any jailed paths
+ while ($sourceStorage->instanceOfStorage(Jail::class)) {
+ /**
+ * @var Jail $sourceStorage
+ */
+ $sourceInternalPath = $sourceStorage->getUnjailedPath($sourceInternalPath);
+ $sourceStorage = $sourceStorage->getUnjailedStorage();
+ }
+
return $this->rename($sourceInternalPath, $targetInternalPath);
}
diff --git a/lib/private/Files/Storage/DAV.php b/lib/private/Files/Storage/DAV.php
index 52ed8900569..ca96e6b7434 100644
--- a/lib/private/Files/Storage/DAV.php
+++ b/lib/private/Files/Storage/DAV.php
@@ -34,19 +34,21 @@
namespace OC\Files\Storage;
use Exception;
-use GuzzleHttp\Exception\RequestException;
-use OCP\ILogger;
-use Psr\Http\Message\ResponseInterface;
use Icewind\Streams\CallbackWrapper;
-use OC\Files\Filesystem;
use Icewind\Streams\IteratorDirectory;
+use OC\Files\Filesystem;
use OC\MemCache\ArrayCache;
use OCP\AppFramework\Http;
use OCP\Constants;
use OCP\Files\FileInfo;
+use OCP\Files\ForbiddenException;
use OCP\Files\StorageInvalidException;
use OCP\Files\StorageNotAvailableException;
+use OCP\Http\Client\IClientService;
+use OCP\ICertificateManager;
+use OCP\ILogger;
use OCP\Util;
+use Psr\Http\Message\ResponseInterface;
use Sabre\DAV\Client;
use Sabre\DAV\Xml\Property\ResourceType;
use Sabre\HTTP\ClientException;
@@ -78,8 +80,10 @@ class DAV extends Common {
protected $client;
/** @var ArrayCache */
protected $statCache;
- /** @var \OCP\Http\Client\IClientService */
+ /** @var IClientService */
protected $httpClientService;
+ /** @var ICertificateManager */
+ protected $certManager;
/**
* @param array $params
@@ -110,13 +114,9 @@ class DAV extends Common {
}
if ($this->secure === true) {
// inject mock for testing
- $certManager = \OC::$server->getCertificateManager();
- if (is_null($certManager)) { //no user
- $certManager = \OC::$server->getCertificateManager(null);
- }
- $certPath = $certManager->getAbsoluteBundlePath();
- if (file_exists($certPath)) {
- $this->certPath = $certPath;
+ $this->certManager = \OC::$server->getCertificateManager();
+ if (is_null($this->certManager)) { //no user
+ $this->certManager = \OC::$server->getCertificateManager(null);
}
}
$this->root = $params['root'] ?? '/';
@@ -149,8 +149,15 @@ class DAV extends Common {
$this->client = new Client($settings);
$this->client->setThrowExceptions(true);
- if ($this->secure === true && $this->certPath) {
- $this->client->addCurlSetting(CURLOPT_CAINFO, $this->certPath);
+
+ if($this->secure === true) {
+ $certPath = $this->certManager->getAbsoluteBundlePath();
+ if (file_exists($certPath)) {
+ $this->certPath = $certPath;
+ }
+ if ($this->certPath) {
+ $this->client->addCurlSetting(CURLOPT_CAINFO, $this->certPath);
+ }
}
}
@@ -268,7 +275,7 @@ class DAV extends Common {
);
$this->statCache->set($path, $response);
} catch (ClientHttpException $e) {
- if ($e->getHttpStatus() === 404) {
+ if ($e->getHttpStatus() === 404 || $e->getHttpStatus() === 405) {
$this->statCache->clear($path . '/');
$this->statCache->set($path, false);
return false;
@@ -829,6 +836,7 @@ class DAV extends Common {
* when the authentication expired or is invalid
* @throws StorageNotAvailableException if the storage is not available,
* which might be temporary
+ * @throws ForbiddenException if the action is not allowed
*/
protected function convertException(Exception $e, $path = '') {
\OC::$server->getLogger()->logException($e, ['app' => 'files_external', 'level' => ILogger::DEBUG]);
@@ -842,6 +850,9 @@ class DAV extends Common {
} else if ($e->getHttpStatus() === Http::STATUS_METHOD_NOT_ALLOWED) {
// ignore exception for MethodNotAllowed, false will be returned
return;
+ } else if ($e->getHttpStatus() === Http::STATUS_FORBIDDEN){
+ // The operation is forbidden. Fail somewhat gracefully
+ throw new ForbiddenException(get_class($e) . ':' . $e->getMessage());
}
throw new StorageNotAvailableException(get_class($e) . ': ' . $e->getMessage());
} else if ($e instanceof ClientException) {
@@ -859,4 +870,3 @@ class DAV extends Common {
// TODO: only log for now, but in the future need to wrap/rethrow exception
}
}
-
diff --git a/lib/private/Files/Storage/FailedStorage.php b/lib/private/Files/Storage/FailedStorage.php
index 9ed09e82e7d..4ee9b21694a 100644
--- a/lib/private/Files/Storage/FailedStorage.php
+++ b/lib/private/Files/Storage/FailedStorage.php
@@ -27,8 +27,8 @@ namespace OC\Files\Storage;
use OC\Files\Cache\FailedCache;
use OCP\Files\Storage\IStorage;
-use \OCP\Lock\ILockingProvider;
-use \OCP\Files\StorageNotAvailableException;
+use OCP\Files\StorageNotAvailableException;
+use OCP\Lock\ILockingProvider;
/**
* Storage placeholder to represent a missing precondition, storage unavailable
diff --git a/lib/private/Files/Storage/Local.php b/lib/private/Files/Storage/Local.php
index e9a9e8e9885..aade0cdaf25 100644
--- a/lib/private/Files/Storage/Local.php
+++ b/lib/private/Files/Storage/Local.php
@@ -424,12 +424,26 @@ class Local extends \OC\Files\Storage\Common {
public function getETag($path) {
if ($this->is_file($path)) {
$stat = $this->stat($path);
- return md5(
- $stat['mtime'] .
- $stat['ino'] .
- $stat['dev'] .
- $stat['size']
- );
+
+ if ($stat === false) {
+ return md5('');
+ }
+
+ $toHash = '';
+ if (isset($stat['mtime'])) {
+ $toHash .= $stat['mtime'];
+ }
+ if (isset($stat['ino'])) {
+ $toHash .= $stat['ino'];
+ }
+ if (isset($stat['dev'])) {
+ $toHash .= $stat['dev'];
+ }
+ if (isset($stat['size'])) {
+ $toHash .= $stat['size'];
+ }
+
+ return md5($toHash);
} else {
return parent::getETag($path);
}
diff --git a/lib/private/Files/Storage/Wrapper/Availability.php b/lib/private/Files/Storage/Wrapper/Availability.php
index 5b957ae036b..0c01595d306 100644
--- a/lib/private/Files/Storage/Wrapper/Availability.php
+++ b/lib/private/Files/Storage/Wrapper/Availability.php
@@ -21,9 +21,13 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
+
namespace OC\Files\Storage\Wrapper;
use OCP\Files\Storage\IStorage;
+use OCP\Files\StorageAuthException;
+use OCP\Files\StorageNotAvailableException;
+use OCP\IConfig;
/**
* Availability checker for storages
@@ -33,6 +37,14 @@ use OCP\Files\Storage\IStorage;
class Availability extends Wrapper {
const RECHECK_TTL_SEC = 600; // 10 minutes
+ /** @var IConfig */
+ protected $config;
+
+ public function __construct($parameters) {
+ $this->config = $parameters['config'] ?? \OC::$server->getConfig();
+ parent::__construct($parameters);
+ }
+
public static function shouldRecheck($availability) {
if (!$availability['available']) {
// trigger a recheck if TTL reached
@@ -72,11 +84,11 @@ class Availability extends Wrapper {
}
/**
- * @throws \OCP\Files\StorageNotAvailableException
+ * @throws StorageNotAvailableException
*/
private function checkAvailability() {
if (!$this->isAvailable()) {
- throw new \OCP\Files\StorageNotAvailableException();
+ throw new StorageNotAvailableException();
}
}
@@ -85,9 +97,8 @@ class Availability extends Wrapper {
$this->checkAvailability();
try {
return parent::mkdir($path);
- } catch (\OCP\Files\StorageNotAvailableException $e) {
- $this->setAvailability(false);
- throw $e;
+ } catch (StorageNotAvailableException $e) {
+ $this->setUnavailable($e);
}
}
@@ -96,9 +107,8 @@ class Availability extends Wrapper {
$this->checkAvailability();
try {
return parent::rmdir($path);
- } catch (\OCP\Files\StorageNotAvailableException $e) {
- $this->setAvailability(false);
- throw $e;
+ } catch (StorageNotAvailableException $e) {
+ $this->setUnavailable($e);
}
}
@@ -107,9 +117,8 @@ class Availability extends Wrapper {
$this->checkAvailability();
try {
return parent::opendir($path);
- } catch (\OCP\Files\StorageNotAvailableException $e) {
- $this->setAvailability(false);
- throw $e;
+ } catch (StorageNotAvailableException $e) {
+ $this->setUnavailable($e);
}
}
@@ -118,9 +127,8 @@ class Availability extends Wrapper {
$this->checkAvailability();
try {
return parent::is_dir($path);
- } catch (\OCP\Files\StorageNotAvailableException $e) {
- $this->setAvailability(false);
- throw $e;
+ } catch (StorageNotAvailableException $e) {
+ $this->setUnavailable($e);
}
}
@@ -129,9 +137,8 @@ class Availability extends Wrapper {
$this->checkAvailability();
try {
return parent::is_file($path);
- } catch (\OCP\Files\StorageNotAvailableException $e) {
- $this->setAvailability(false);
- throw $e;
+ } catch (StorageNotAvailableException $e) {
+ $this->setUnavailable($e);
}
}
@@ -140,9 +147,8 @@ class Availability extends Wrapper {
$this->checkAvailability();
try {
return parent::stat($path);
- } catch (\OCP\Files\StorageNotAvailableException $e) {
- $this->setAvailability(false);
- throw $e;
+ } catch (StorageNotAvailableException $e) {
+ $this->setUnavailable($e);
}
}
@@ -151,9 +157,8 @@ class Availability extends Wrapper {
$this->checkAvailability();
try {
return parent::filetype($path);
- } catch (\OCP\Files\StorageNotAvailableException $e) {
- $this->setAvailability(false);
- throw $e;
+ } catch (StorageNotAvailableException $e) {
+ $this->setUnavailable($e);
}
}
@@ -162,9 +167,8 @@ class Availability extends Wrapper {
$this->checkAvailability();
try {
return parent::filesize($path);
- } catch (\OCP\Files\StorageNotAvailableException $e) {
- $this->setAvailability(false);
- throw $e;
+ } catch (StorageNotAvailableException $e) {
+ $this->setUnavailable($e);
}
}
@@ -173,9 +177,8 @@ class Availability extends Wrapper {
$this->checkAvailability();
try {
return parent::isCreatable($path);
- } catch (\OCP\Files\StorageNotAvailableException $e) {
- $this->setAvailability(false);
- throw $e;
+ } catch (StorageNotAvailableException $e) {
+ $this->setUnavailable($e);
}
}
@@ -184,9 +187,8 @@ class Availability extends Wrapper {
$this->checkAvailability();
try {
return parent::isReadable($path);
- } catch (\OCP\Files\StorageNotAvailableException $e) {
- $this->setAvailability(false);
- throw $e;
+ } catch (StorageNotAvailableException $e) {
+ $this->setUnavailable($e);
}
}
@@ -195,9 +197,8 @@ class Availability extends Wrapper {
$this->checkAvailability();
try {
return parent::isUpdatable($path);
- } catch (\OCP\Files\StorageNotAvailableException $e) {
- $this->setAvailability(false);
- throw $e;
+ } catch (StorageNotAvailableException $e) {
+ $this->setUnavailable($e);
}
}
@@ -206,9 +207,8 @@ class Availability extends Wrapper {
$this->checkAvailability();
try {
return parent::isDeletable($path);
- } catch (\OCP\Files\StorageNotAvailableException $e) {
- $this->setAvailability(false);
- throw $e;
+ } catch (StorageNotAvailableException $e) {
+ $this->setUnavailable($e);
}
}
@@ -217,9 +217,8 @@ class Availability extends Wrapper {
$this->checkAvailability();
try {
return parent::isSharable($path);
- } catch (\OCP\Files\StorageNotAvailableException $e) {
- $this->setAvailability(false);
- throw $e;
+ } catch (StorageNotAvailableException $e) {
+ $this->setUnavailable($e);
}
}
@@ -228,9 +227,8 @@ class Availability extends Wrapper {
$this->checkAvailability();
try {
return parent::getPermissions($path);
- } catch (\OCP\Files\StorageNotAvailableException $e) {
- $this->setAvailability(false);
- throw $e;
+ } catch (StorageNotAvailableException $e) {
+ $this->setUnavailable($e);
}
}
@@ -242,9 +240,8 @@ class Availability extends Wrapper {
$this->checkAvailability();
try {
return parent::file_exists($path);
- } catch (\OCP\Files\StorageNotAvailableException $e) {
- $this->setAvailability(false);
- throw $e;
+ } catch (StorageNotAvailableException $e) {
+ $this->setUnavailable($e);
}
}
@@ -253,9 +250,8 @@ class Availability extends Wrapper {
$this->checkAvailability();
try {
return parent::filemtime($path);
- } catch (\OCP\Files\StorageNotAvailableException $e) {
- $this->setAvailability(false);
- throw $e;
+ } catch (StorageNotAvailableException $e) {
+ $this->setUnavailable($e);
}
}
@@ -264,9 +260,8 @@ class Availability extends Wrapper {
$this->checkAvailability();
try {
return parent::file_get_contents($path);
- } catch (\OCP\Files\StorageNotAvailableException $e) {
- $this->setAvailability(false);
- throw $e;
+ } catch (StorageNotAvailableException $e) {
+ $this->setUnavailable($e);
}
}
@@ -275,9 +270,8 @@ class Availability extends Wrapper {
$this->checkAvailability();
try {
return parent::file_put_contents($path, $data);
- } catch (\OCP\Files\StorageNotAvailableException $e) {
- $this->setAvailability(false);
- throw $e;
+ } catch (StorageNotAvailableException $e) {
+ $this->setUnavailable($e);
}
}
@@ -286,9 +280,8 @@ class Availability extends Wrapper {
$this->checkAvailability();
try {
return parent::unlink($path);
- } catch (\OCP\Files\StorageNotAvailableException $e) {
- $this->setAvailability(false);
- throw $e;
+ } catch (StorageNotAvailableException $e) {
+ $this->setUnavailable($e);
}
}
@@ -297,9 +290,8 @@ class Availability extends Wrapper {
$this->checkAvailability();
try {
return parent::rename($path1, $path2);
- } catch (\OCP\Files\StorageNotAvailableException $e) {
- $this->setAvailability(false);
- throw $e;
+ } catch (StorageNotAvailableException $e) {
+ $this->setUnavailable($e);
}
}
@@ -308,9 +300,8 @@ class Availability extends Wrapper {
$this->checkAvailability();
try {
return parent::copy($path1, $path2);
- } catch (\OCP\Files\StorageNotAvailableException $e) {
- $this->setAvailability(false);
- throw $e;
+ } catch (StorageNotAvailableException $e) {
+ $this->setUnavailable($e);
}
}
@@ -319,9 +310,8 @@ class Availability extends Wrapper {
$this->checkAvailability();
try {
return parent::fopen($path, $mode);
- } catch (\OCP\Files\StorageNotAvailableException $e) {
- $this->setAvailability(false);
- throw $e;
+ } catch (StorageNotAvailableException $e) {
+ $this->setUnavailable($e);
}
}
@@ -330,9 +320,8 @@ class Availability extends Wrapper {
$this->checkAvailability();
try {
return parent::getMimeType($path);
- } catch (\OCP\Files\StorageNotAvailableException $e) {
- $this->setAvailability(false);
- throw $e;
+ } catch (StorageNotAvailableException $e) {
+ $this->setUnavailable($e);
}
}
@@ -341,9 +330,8 @@ class Availability extends Wrapper {
$this->checkAvailability();
try {
return parent::hash($type, $path, $raw);
- } catch (\OCP\Files\StorageNotAvailableException $e) {
- $this->setAvailability(false);
- throw $e;
+ } catch (StorageNotAvailableException $e) {
+ $this->setUnavailable($e);
}
}
@@ -352,9 +340,8 @@ class Availability extends Wrapper {
$this->checkAvailability();
try {
return parent::free_space($path);
- } catch (\OCP\Files\StorageNotAvailableException $e) {
- $this->setAvailability(false);
- throw $e;
+ } catch (StorageNotAvailableException $e) {
+ $this->setUnavailable($e);
}
}
@@ -363,9 +350,8 @@ class Availability extends Wrapper {
$this->checkAvailability();
try {
return parent::search($query);
- } catch (\OCP\Files\StorageNotAvailableException $e) {
- $this->setAvailability(false);
- throw $e;
+ } catch (StorageNotAvailableException $e) {
+ $this->setUnavailable($e);
}
}
@@ -374,9 +360,8 @@ class Availability extends Wrapper {
$this->checkAvailability();
try {
return parent::touch($path, $mtime);
- } catch (\OCP\Files\StorageNotAvailableException $e) {
- $this->setAvailability(false);
- throw $e;
+ } catch (StorageNotAvailableException $e) {
+ $this->setUnavailable($e);
}
}
@@ -385,9 +370,8 @@ class Availability extends Wrapper {
$this->checkAvailability();
try {
return parent::getLocalFile($path);
- } catch (\OCP\Files\StorageNotAvailableException $e) {
- $this->setAvailability(false);
- throw $e;
+ } catch (StorageNotAvailableException $e) {
+ $this->setUnavailable($e);
}
}
@@ -396,9 +380,8 @@ class Availability extends Wrapper {
$this->checkAvailability();
try {
return parent::hasUpdated($path, $time);
- } catch (\OCP\Files\StorageNotAvailableException $e) {
- $this->setAvailability(false);
- throw $e;
+ } catch (StorageNotAvailableException $e) {
+ $this->setUnavailable($e);
}
}
@@ -406,9 +389,8 @@ class Availability extends Wrapper {
public function getOwner($path) {
try {
return parent::getOwner($path);
- } catch (\OCP\Files\StorageNotAvailableException $e) {
- $this->setAvailability(false);
- throw $e;
+ } catch (StorageNotAvailableException $e) {
+ $this->setUnavailable($e);
}
}
@@ -417,9 +399,8 @@ class Availability extends Wrapper {
$this->checkAvailability();
try {
return parent::getETag($path);
- } catch (\OCP\Files\StorageNotAvailableException $e) {
- $this->setAvailability(false);
- throw $e;
+ } catch (StorageNotAvailableException $e) {
+ $this->setUnavailable($e);
}
}
@@ -428,9 +409,8 @@ class Availability extends Wrapper {
$this->checkAvailability();
try {
return parent::getDirectDownload($path);
- } catch (\OCP\Files\StorageNotAvailableException $e) {
- $this->setAvailability(false);
- throw $e;
+ } catch (StorageNotAvailableException $e) {
+ $this->setUnavailable($e);
}
}
@@ -439,9 +419,8 @@ class Availability extends Wrapper {
$this->checkAvailability();
try {
return parent::copyFromStorage($sourceStorage, $sourceInternalPath, $targetInternalPath);
- } catch (\OCP\Files\StorageNotAvailableException $e) {
- $this->setAvailability(false);
- throw $e;
+ } catch (StorageNotAvailableException $e) {
+ $this->setUnavailable($e);
}
}
@@ -450,9 +429,8 @@ class Availability extends Wrapper {
$this->checkAvailability();
try {
return parent::moveFromStorage($sourceStorage, $sourceInternalPath, $targetInternalPath);
- } catch (\OCP\Files\StorageNotAvailableException $e) {
- $this->setAvailability(false);
- throw $e;
+ } catch (StorageNotAvailableException $e) {
+ $this->setUnavailable($e);
}
}
@@ -461,9 +439,24 @@ class Availability extends Wrapper {
$this->checkAvailability();
try {
return parent::getMetaData($path);
- } catch (\OCP\Files\StorageNotAvailableException $e) {
- $this->setAvailability(false);
- throw $e;
+ } catch (StorageNotAvailableException $e) {
+ $this->setUnavailable($e);
}
}
+
+ /**
+ * @throws StorageNotAvailableException
+ */
+ protected function setUnavailable(StorageNotAvailableException $e) {
+ $delay = self::RECHECK_TTL_SEC;
+ if($e instanceof StorageAuthException) {
+ $delay = max(
+ // 30min
+ $this->config->getSystemValueInt('external_storage.auth_availability_delay', 1800),
+ self::RECHECK_TTL_SEC
+ );
+ }
+ $this->getStorageCache()->setAvailability(false, $delay);
+ throw $e;
+ }
}
diff --git a/lib/private/Files/Storage/Wrapper/Encoding.php b/lib/private/Files/Storage/Wrapper/Encoding.php
index bc8519bf42c..f143c8b8c92 100644
--- a/lib/private/Files/Storage/Wrapper/Encoding.php
+++ b/lib/private/Files/Storage/Wrapper/Encoding.php
@@ -23,9 +23,9 @@
namespace OC\Files\Storage\Wrapper;
+use OC\Cache\CappedMemoryCache;
use OCP\Files\Storage\IStorage;
use OCP\ICache;
-use OC\Cache\CappedMemoryCache;
/**
* Encoding wrapper that deals with file names that use unsupported encodings like NFD.
diff --git a/lib/private/Files/Storage/Wrapper/Encryption.php b/lib/private/Files/Storage/Wrapper/Encryption.php
index 5485b80985b..7741f820c63 100644
--- a/lib/private/Files/Storage/Wrapper/Encryption.php
+++ b/lib/private/Files/Storage/Wrapper/Encryption.php
@@ -41,10 +41,10 @@ use OCP\Encryption\Exceptions\GenericEncryptionException;
use OCP\Encryption\IFile;
use OCP\Encryption\IManager;
use OCP\Encryption\Keys\IStorage;
+use OCP\Files\Cache\ICacheEntry;
use OCP\Files\Mount\IMountPoint;
use OCP\Files\Storage;
use OCP\ILogger;
-use OCP\Files\Cache\ICacheEntry;
class Encryption extends Wrapper {
diff --git a/lib/private/Files/Storage/Wrapper/Jail.php b/lib/private/Files/Storage/Wrapper/Jail.php
index f21b5716467..35bf8449fd7 100644
--- a/lib/private/Files/Storage/Wrapper/Jail.php
+++ b/lib/private/Files/Storage/Wrapper/Jail.php
@@ -62,10 +62,18 @@ class Jail extends Wrapper {
}
}
+ /**
+ * This is separate from Wrapper::getWrapperStorage so we can get the jailed storage consistently even if the jail is inside another wrapper
+ */
+ public function getUnjailedStorage() {
+ return $this->storage;
+ }
+
+
public function getJailedPath($path) {
$root = rtrim($this->rootPath, '/') . '/';
- if (strpos($path, $root) !== 0) {
+ if ($path !== $this->rootPath && strpos($path, $root) !== 0) {
return null;
} else {
$path = substr($path, strlen($this->rootPath));
diff --git a/lib/private/Files/Type/Loader.php b/lib/private/Files/Type/Loader.php
index d1419dca4dc..46588a74d0d 100644
--- a/lib/private/Files/Type/Loader.php
+++ b/lib/private/Files/Type/Loader.php
@@ -25,9 +25,9 @@
namespace OC\Files\Type;
+use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
use OCP\Files\IMimeTypeLoader;
use OCP\IDBConnection;
-use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
/**
* Mimetype database loader
diff --git a/lib/private/Files/Type/TemplateManager.php b/lib/private/Files/Type/TemplateManager.php
index 8b30eb6b4e8..08c4593bf87 100644
--- a/lib/private/Files/Type/TemplateManager.php
+++ b/lib/private/Files/Type/TemplateManager.php
@@ -24,6 +24,9 @@
namespace OC\Files\Type;
+/**
+ * @deprecated 18.0.0
+ */
class TemplateManager {
protected $templates = array();
@@ -34,6 +37,7 @@ class TemplateManager {
/**
* get the path of the template for a mimetype
*
+ * @deprecated 18.0.0
* @param string $mimetype
* @return string|null
*/
@@ -48,6 +52,7 @@ class TemplateManager {
/**
* get the template content for a mimetype
*
+ * @deprecated 18.0.0
* @param string $mimetype
* @return string
*/
diff --git a/lib/private/Files/Utils/Scanner.php b/lib/private/Files/Utils/Scanner.php
index 28921973fcf..8dee7bf7423 100644
--- a/lib/private/Files/Utils/Scanner.php
+++ b/lib/private/Files/Utils/Scanner.php
@@ -30,6 +30,7 @@ namespace OC\Files\Utils;
use OC\Files\Cache\Cache;
use OC\Files\Filesystem;
+use OC\Files\Storage\FailedStorage;
use OC\ForbiddenException;
use OC\Hooks\PublicEmitter;
use OC\Lock\DBLockingProvider;
@@ -38,7 +39,6 @@ use OCP\Files\NotFoundException;
use OCP\Files\Storage\IStorage;
use OCP\Files\StorageNotAvailableException;
use OCP\ILogger;
-use OC\Files\Storage\FailedStorage;
/**
* Class Scanner
@@ -279,4 +279,3 @@ class Scanner extends PublicEmitter {
}
}
}
-
diff --git a/lib/private/Files/View.php b/lib/private/Files/View.php
index 8322576c5c2..ed962bde1a4 100644
--- a/lib/private/Files/View.php
+++ b/lib/private/Files/View.php
@@ -42,7 +42,6 @@
*
*/
-
namespace OC\Files;
use Icewind\Streams\CallbackWrapper;
@@ -590,6 +589,7 @@ class View {
/**
* @param string $path
* @return mixed
+ * @throws LockedException
*/
public function file_get_contents($path) {
return $this->basicOperation('file_get_contents', $path, array('read'));
@@ -641,7 +641,7 @@ class View {
* @param string $path
* @param string|resource $data
* @return bool|mixed
- * @throws \Exception
+ * @throws LockedException
*/
public function file_put_contents($path, $data) {
if (is_resource($data)) { //not having to deal with streams in file_put_contents makes life easier
@@ -740,6 +740,7 @@ class View {
* @param string $path2 target path
*
* @return bool|mixed
+ * @throws LockedException
*/
public function rename($path1, $path2) {
$absolutePath1 = Filesystem::normalizePath($this->getAbsolutePath($path1));
@@ -963,6 +964,7 @@ class View {
* @param string $path
* @param string $mode 'r' or 'w'
* @return resource
+ * @throws LockedException
*/
public function fopen($path, $mode) {
$mode = str_replace('b', '', $mode); // the binary flag is a windows only feature which we do not support
@@ -1118,7 +1120,7 @@ class View {
* @param array $hooks (optional)
* @param mixed $extraParam (optional)
* @return mixed
- * @throws \Exception
+ * @throws LockedException
*
* This method takes requests for basic filesystem functions (e.g. reading & writing
* files), processes hooks and proxies, sanitises paths, and finally passes them on to
@@ -1920,7 +1922,7 @@ class View {
* @param bool $lockMountPoint true to lock the mount point, false to lock the attached mount/storage
*
* @return bool False if the path is excluded from locking, true otherwise
- * @throws \OCP\Lock\LockedException if the path is already locked
+ * @throws LockedException if the path is already locked
*/
private function lockPath($path, $type, $lockMountPoint = false) {
$absolutePath = $this->getAbsolutePath($path);
@@ -1940,9 +1942,9 @@ class View {
$this->lockingProvider
);
}
- } catch (\OCP\Lock\LockedException $e) {
+ } catch (LockedException $e) {
// rethrow with the a human-readable path
- throw new \OCP\Lock\LockedException(
+ throw new LockedException(
$this->getPathRelativeToFiles($absolutePath),
$e
);
@@ -1960,7 +1962,7 @@ class View {
* @param bool $lockMountPoint true to lock the mount point, false to lock the attached mount/storage
*
* @return bool False if the path is excluded from locking, true otherwise
- * @throws \OCP\Lock\LockedException if the path is already locked
+ * @throws LockedException if the path is already locked
*/
public function changeLock($path, $type, $lockMountPoint = false) {
$path = Filesystem::normalizePath($path);
@@ -1981,15 +1983,15 @@ class View {
$this->lockingProvider
);
}
- } catch (\OCP\Lock\LockedException $e) {
+ } catch (LockedException $e) {
try {
// rethrow with the a human-readable path
- throw new \OCP\Lock\LockedException(
+ throw new LockedException(
$this->getPathRelativeToFiles($absolutePath),
$e
);
} catch (\InvalidArgumentException $e) {
- throw new \OCP\Lock\LockedException(
+ throw new LockedException(
$absolutePath,
$e
);
@@ -2008,6 +2010,7 @@ class View {
* @param bool $lockMountPoint true to lock the mount point, false to lock the attached mount/storage
*
* @return bool False if the path is excluded from locking, true otherwise
+ * @throws LockedException
*/
private function unlockPath($path, $type, $lockMountPoint = false) {
$absolutePath = $this->getAbsolutePath($path);
@@ -2039,6 +2042,7 @@ class View {
* @param bool $lockMountPoint true to lock the mount point, false to lock the attached mount/storage
*
* @return bool False if the path is excluded from locking, true otherwise
+ * @throws LockedException
*/
public function lockFile($path, $type, $lockMountPoint = false) {
$absolutePath = $this->getAbsolutePath($path);
@@ -2065,6 +2069,7 @@ class View {
* @param bool $lockMountPoint true to lock the mount point, false to lock the attached mount/storage
*
* @return bool False if the path is excluded from locking, true otherwise
+ * @throws LockedException
*/
public function unlockFile($path, $type, $lockMountPoint = false) {
$absolutePath = $this->getAbsolutePath($path);
diff --git a/lib/private/FullTextSearch/FullTextSearchManager.php b/lib/private/FullTextSearch/FullTextSearchManager.php
index 8ab1af05b0e..3aec4638a21 100644
--- a/lib/private/FullTextSearch/FullTextSearchManager.php
+++ b/lib/private/FullTextSearch/FullTextSearchManager.php
@@ -27,7 +27,6 @@ declare(strict_types=1);
*
*/
-
namespace OC\FullTextSearch;
@@ -39,7 +38,6 @@ use OCP\FullTextSearch\Service\IIndexService;
use OCP\FullTextSearch\Service\IProviderService;
use OCP\FullTextSearch\Service\ISearchService;
-
/**
* Class FullTextSearchManager
*
@@ -239,4 +237,3 @@ class FullTextSearchManager implements IFullTextSearchManager {
}
-
diff --git a/lib/private/FullTextSearch/Model/DocumentAccess.php b/lib/private/FullTextSearch/Model/DocumentAccess.php
index 088bf075ae6..ce195eb8a2e 100644
--- a/lib/private/FullTextSearch/Model/DocumentAccess.php
+++ b/lib/private/FullTextSearch/Model/DocumentAccess.php
@@ -27,14 +27,12 @@ declare(strict_types=1);
*
*/
-
namespace OC\FullTextSearch\Model;
use JsonSerializable;
use OCP\FullTextSearch\Model\IDocumentAccess;
-
/**
* Class IDocumentAccess
*
@@ -362,4 +360,3 @@ final class DocumentAccess implements IDocumentAccess, JsonSerializable {
];
}
}
-
diff --git a/lib/private/FullTextSearch/Model/IndexDocument.php b/lib/private/FullTextSearch/Model/IndexDocument.php
index d5bef906021..1efa55b5ca1 100644
--- a/lib/private/FullTextSearch/Model/IndexDocument.php
+++ b/lib/private/FullTextSearch/Model/IndexDocument.php
@@ -27,7 +27,6 @@ declare(strict_types=1);
*
*/
-
namespace OC\FullTextSearch\Model;
@@ -36,7 +35,6 @@ use OCP\FullTextSearch\Model\IDocumentAccess;
use OCP\FullTextSearch\Model\IIndex;
use OCP\FullTextSearch\Model\IIndexDocument;
-
/**
* Class IndexDocument
*
@@ -997,4 +995,3 @@ class IndexDocument implements IIndexDocument, JsonSerializable {
}
}
-
diff --git a/lib/private/FullTextSearch/Model/SearchOption.php b/lib/private/FullTextSearch/Model/SearchOption.php
index 6a67c9fe7df..d0eb0eab2ed 100644
--- a/lib/private/FullTextSearch/Model/SearchOption.php
+++ b/lib/private/FullTextSearch/Model/SearchOption.php
@@ -27,14 +27,12 @@ declare(strict_types=1);
*
*/
-
namespace OC\FullTextSearch\Model;
use JsonSerializable;
use OCP\FullTextSearch\Model\ISearchOption;
-
/**
* @since 15.0.0
*
diff --git a/lib/private/FullTextSearch/Model/SearchRequestSimpleQuery.php b/lib/private/FullTextSearch/Model/SearchRequestSimpleQuery.php
index a01fb232916..8796f28a249 100644
--- a/lib/private/FullTextSearch/Model/SearchRequestSimpleQuery.php
+++ b/lib/private/FullTextSearch/Model/SearchRequestSimpleQuery.php
@@ -27,14 +27,12 @@ declare(strict_types=1);
*
*/
-
namespace OC\FullTextSearch\Model;
use JsonSerializable;
use OCP\FullTextSearch\Model\ISearchRequestSimpleQuery;
-
/**
* @since 17.0.0
*
diff --git a/lib/private/FullTextSearch/Model/SearchTemplate.php b/lib/private/FullTextSearch/Model/SearchTemplate.php
index 22333e712ce..a4c21d30bcc 100644
--- a/lib/private/FullTextSearch/Model/SearchTemplate.php
+++ b/lib/private/FullTextSearch/Model/SearchTemplate.php
@@ -27,7 +27,6 @@ declare(strict_types=1);
*
*/
-
namespace OC\FullTextSearch\Model;
@@ -36,7 +35,6 @@ use OCP\FullTextSearch\IFullTextSearchProvider;
use OCP\FullTextSearch\Model\ISearchOption;
use OCP\FullTextSearch\Model\ISearchTemplate;
-
/**
* Class ISearchTemplate
*
@@ -257,4 +255,3 @@ final class SearchTemplate implements ISearchTemplate, JsonSerializable {
];
}
}
-
diff --git a/lib/private/GlobalScale/Config.php b/lib/private/GlobalScale/Config.php
index da7a459741b..2ab862a0e4e 100644
--- a/lib/private/GlobalScale/Config.php
+++ b/lib/private/GlobalScale/Config.php
@@ -21,7 +21,6 @@
*
*/
-
namespace OC\GlobalScale;
diff --git a/lib/private/Group/Database.php b/lib/private/Group/Database.php
index 7a5728b957d..7028b1fa81b 100644
--- a/lib/private/Group/Database.php
+++ b/lib/private/Group/Database.php
@@ -49,7 +49,10 @@ use OCP\Group\Backend\ICountDisabledInGroup;
use OCP\Group\Backend\ICountUsersBackend;
use OCP\Group\Backend\ICreateGroupBackend;
use OCP\Group\Backend\IDeleteGroupBackend;
+use OCP\Group\Backend\IGetDisplayNameBackend;
+use OCP\Group\Backend\IGroupDetailsBackend;
use OCP\Group\Backend\IRemoveFromGroupBackend;
+use OCP\Group\Backend\ISetDisplayNameBackend;
use OCP\IDBConnection;
/**
@@ -61,7 +64,10 @@ class Database extends ABackend
ICountUsersBackend,
ICreateGroupBackend,
IDeleteGroupBackend,
- IRemoveFromGroupBackend {
+ IGetDisplayNameBackend,
+ IGroupDetailsBackend,
+ IRemoveFromGroupBackend,
+ ISetDisplayNameBackend {
/** @var string[] */
private $groupCache = [];
@@ -103,6 +109,7 @@ class Database extends ABackend
$builder = $this->dbConn->getQueryBuilder();
$result = $builder->insert('groups')
->setValue('gid', $builder->createNamedParameter($gid))
+ ->setValue('displayname', $builder->createNamedParameter($gid))
->execute();
} catch(UniqueConstraintViolationException $e) {
$result = 0;
@@ -322,7 +329,7 @@ class Database extends ABackend
* @param int $offset
* @return array an array of user ids
*/
- public function usersInGroup($gid, $search = '', $limit = null, $offset = null) {
+ public function usersInGroup($gid, $search = '', $limit = -1, $offset = 0) {
$this->fixDI();
$query = $this->dbConn->getQueryBuilder();
@@ -337,8 +344,13 @@ class Database extends ABackend
)));
}
- $query->setMaxResults($limit)
- ->setFirstResult($offset);
+ if ($limit !== -1) {
+ $query->setMaxResults($limit);
+ }
+ if ($offset !== 0) {
+ $query->setFirstResult($offset);
+ }
+
$result = $query->execute();
$users = [];
@@ -391,7 +403,7 @@ class Database extends ABackend
*/
public function countDisabledInGroup(string $gid): int {
$this->fixDI();
-
+
$query = $this->dbConn->getQueryBuilder();
$query->select($query->createFunction('COUNT(DISTINCT ' . $query->getColumnName('uid') . ')'))
->from('preferences', 'p')
@@ -400,11 +412,11 @@ class Database extends ABackend
->andWhere($query->expr()->eq('configkey', $query->createNamedParameter('enabled')))
->andWhere($query->expr()->eq('configvalue', $query->createNamedParameter('false'), IQueryBuilder::PARAM_STR))
->andWhere($query->expr()->eq('gid', $query->createNamedParameter($gid), IQueryBuilder::PARAM_STR));
-
+
$result = $query->execute();
$count = $result->fetchColumn();
$result->closeCursor();
-
+
if ($count !== false) {
$count = (int)$count;
} else {
@@ -414,4 +426,49 @@ class Database extends ABackend
return $count;
}
+ public function getDisplayName(string $gid): string {
+ $this->fixDI();
+
+ $query = $this->dbConn->getQueryBuilder();
+ $query->select('displayname')
+ ->from('groups')
+ ->where($query->expr()->eq('gid', $query->createNamedParameter($gid)));
+
+ $result = $query->execute();
+ $displayName = $result->fetchColumn();
+ $result->closeCursor();
+
+ return (string) $displayName;
+ }
+
+ public function getGroupDetails(string $gid): array {
+ $displayName = $this->getDisplayName($gid);
+ if ($displayName !== '') {
+ return ['displayName' => $displayName];
+ }
+
+ return [];
+ }
+
+ public function setDisplayName(string $gid, string $displayName): bool {
+ if (!$this->groupExists($gid)) {
+ return false;
+ }
+
+ $this->fixDI();
+
+ $displayName = trim($displayName);
+ if ($displayName === '') {
+ $displayName = $gid;
+ }
+
+ $query = $this->dbConn->getQueryBuilder();
+ $query->update('groups')
+ ->set('displayname', $query->createNamedParameter($displayName))
+ ->where($query->expr()->eq('gid', $query->createNamedParameter($gid)));
+ $query->execute();
+
+ return true;
+ }
+
}
diff --git a/lib/private/Group/Group.php b/lib/private/Group/Group.php
index a50a5ffde78..fa14e4e9932 100644
--- a/lib/private/Group/Group.php
+++ b/lib/private/Group/Group.php
@@ -30,13 +30,14 @@
namespace OC\Group;
+use OC\Hooks\PublicEmitter;
+use OCP\Group\Backend\ICountDisabledInGroup;
use OCP\Group\Backend\IGetDisplayNameBackend;
use OCP\Group\Backend\IHideFromCollaborationBackend;
-use OC\Hooks\PublicEmitter;
+use OCP\Group\Backend\ISetDisplayNameBackend;
use OCP\GroupInterface;
use OCP\IGroup;
use OCP\IUser;
-use OCP\Group\Backend\ICountDisabledInGroup;
use OCP\IUserManager;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\EventDispatcher\GenericEvent;
@@ -101,6 +102,20 @@ class Group implements IGroup {
return $this->displayName;
}
+ public function setDisplayName(string $displayName): bool {
+ $displayName = trim($displayName);
+ if ($displayName !== '') {
+ foreach ($this->backends as $backend) {
+ if (($backend instanceof ISetDisplayNameBackend)
+ && $backend->setDisplayName($this->gid, $displayName)) {
+ $this->displayName = $displayName;
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
/**
* get all users in the group
*
diff --git a/lib/private/Group/Manager.php b/lib/private/Group/Manager.php
index 7567f719b0a..dc4a7fbd11c 100644
--- a/lib/private/Group/Manager.php
+++ b/lib/private/Group/Manager.php
@@ -93,8 +93,8 @@ class Manager extends PublicEmitter implements IGroupManager {
$this->dispatcher = $dispatcher;
$this->logger = $logger;
- $cachedGroups = & $this->cachedGroups;
- $cachedUserGroups = & $this->cachedUserGroups;
+ $cachedGroups = &$this->cachedGroups;
+ $cachedUserGroups = &$this->cachedUserGroups;
$this->listen('\OC\Group', 'postDelete', function ($group) use (&$cachedGroups, &$cachedUserGroups) {
/**
* @var \OC\Group\Group $group
@@ -149,6 +149,7 @@ class Manager extends PublicEmitter implements IGroupManager {
/**
* Get the active backends
+ *
* @return \OCP\GroupInterface[]
*/
public function getBackends() {
@@ -163,7 +164,7 @@ class Manager extends PublicEmitter implements IGroupManager {
/**
* @param string $gid
- * @return \OC\Group\Group
+ * @return IGroup|null
*/
public function get($gid) {
if (isset($this->cachedGroups[$gid])) {
@@ -175,12 +176,12 @@ class Manager extends PublicEmitter implements IGroupManager {
/**
* @param string $gid
* @param string $displayName
- * @return \OCP\IGroup
+ * @return \OCP\IGroup|null
*/
protected function getGroupObject($gid, $displayName = null) {
$backends = [];
foreach ($this->backends as $backend) {
- if ($backend->implementsActions(\OC\Group\Backend::GROUP_DETAILS)) {
+ if ($backend->implementsActions(Backend::GROUP_DETAILS)) {
$groupData = $backend->getGroupDetails($gid);
if (is_array($groupData) && !empty($groupData)) {
// take the display name from the first backend that has a non-null one
@@ -210,21 +211,22 @@ class Manager extends PublicEmitter implements IGroupManager {
/**
* @param string $gid
- * @return \OC\Group\Group
+ * @return IGroup|null
*/
public function createGroup($gid) {
if ($gid === '' || $gid === null) {
- return false;
+ return null;
} else if ($group = $this->get($gid)) {
return $group;
} else {
- $this->emit('\OC\Group', 'preCreate', array($gid));
+ $this->emit('\OC\Group', 'preCreate', [$gid]);
foreach ($this->backends as $backend) {
- if ($backend->implementsActions(\OC\Group\Backend::CREATE_GROUP)) {
- $backend->createGroup($gid);
- $group = $this->getGroupObject($gid);
- $this->emit('\OC\Group', 'postCreate', array($group));
- return $group;
+ if ($backend->implementsActions(Backend::CREATE_GROUP)) {
+ if ($backend->createGroup($gid)) {
+ $group = $this->getGroupObject($gid);
+ $this->emit('\OC\Group', 'postCreate', [$group]);
+ return $group;
+ }
}
}
return null;
@@ -260,7 +262,7 @@ class Manager extends PublicEmitter implements IGroupManager {
* @param IUser|null $user
* @return \OC\Group\Group[]
*/
- public function getUserGroups(IUser $user= null) {
+ public function getUserGroups(IUser $user = null) {
if (!$user instanceof IUser) {
return [];
}
@@ -295,12 +297,13 @@ class Manager extends PublicEmitter implements IGroupManager {
/**
* Checks if a userId is in the admin group
+ *
* @param string $userId
* @return bool if admin
*/
public function isAdmin($userId) {
foreach ($this->backends as $backend) {
- if ($backend->implementsActions(\OC\Group\Backend::IS_ADMIN) && $backend->isAdmin($userId)) {
+ if ($backend->implementsActions(Backend::IS_ADMIN) && $backend->isAdmin($userId)) {
return true;
}
}
@@ -309,6 +312,7 @@ class Manager extends PublicEmitter implements IGroupManager {
/**
* Checks if a userId is in a group
+ *
* @param string $userId
* @param string $group
* @return bool if in group
@@ -319,28 +323,31 @@ class Manager extends PublicEmitter implements IGroupManager {
/**
* get a list of group ids for a user
+ *
* @param IUser $user
* @return array with group ids
*/
public function getUserGroupIds(IUser $user) {
- return array_map(function($value) {
- return (string) $value;
+ return array_map(function ($value) {
+ return (string)$value;
}, array_keys($this->getUserGroups($user)));
}
/**
* get an array of groupid and displayName for a user
+ *
* @param IUser $user
* @return array ['displayName' => displayname]
*/
public function getUserGroupNames(IUser $user) {
- return array_map(function($group) {
+ return array_map(function ($group) {
return array('displayName' => $group->getDisplayName());
}, $this->getUserGroups($user));
}
/**
* get a list of all display names in a group
+ *
* @param string $gid
* @param string $search
* @param int $limit
@@ -349,32 +356,32 @@ class Manager extends PublicEmitter implements IGroupManager {
*/
public function displayNamesInGroup($gid, $search = '', $limit = -1, $offset = 0) {
$group = $this->get($gid);
- if(is_null($group)) {
+ if (is_null($group)) {
return [];
}
$search = trim($search);
$groupUsers = [];
- if(!empty($search)) {
+ if (!empty($search)) {
// only user backends have the capability to do a complex search for users
$searchOffset = 0;
$searchLimit = $limit * 100;
- if($limit === -1) {
+ if ($limit === -1) {
$searchLimit = 500;
}
do {
$filteredUsers = $this->userManager->searchDisplayName($search, $searchLimit, $searchOffset);
- foreach($filteredUsers as $filteredUser) {
- if($group->inGroup($filteredUser)) {
- $groupUsers[]= $filteredUser;
+ foreach ($filteredUsers as $filteredUser) {
+ if ($group->inGroup($filteredUser)) {
+ $groupUsers[] = $filteredUser;
}
}
$searchOffset += $searchLimit;
- } while(count($groupUsers) < $searchLimit+$offset && count($filteredUsers) >= $searchLimit);
+ } while (count($groupUsers) < $searchLimit + $offset && count($filteredUsers) >= $searchLimit);
- if($limit === -1) {
+ if ($limit === -1) {
$groupUsers = array_slice($groupUsers, $offset);
} else {
$groupUsers = array_slice($groupUsers, $offset, $limit);
@@ -384,8 +391,8 @@ class Manager extends PublicEmitter implements IGroupManager {
}
$matchingUsers = [];
- foreach($groupUsers as $groupUser) {
- $matchingUsers[$groupUser->getUID()] = $groupUser->getDisplayName();
+ foreach ($groupUsers as $groupUser) {
+ $matchingUsers[(string) $groupUser->getUID()] = $groupUser->getDisplayName();
}
return $matchingUsers;
}
diff --git a/lib/private/Group/MetaData.php b/lib/private/Group/MetaData.php
index f4877237ec7..cda208f3f58 100644
--- a/lib/private/Group/MetaData.php
+++ b/lib/private/Group/MetaData.php
@@ -28,8 +28,8 @@
namespace OC\Group;
-use OCP\IUserSession;
use OCP\IGroupManager;
+use OCP\IUserSession;
class MetaData {
const SORT_NONE = 0;
diff --git a/lib/private/Http/Client/Client.php b/lib/private/Http/Client/Client.php
index 993b83917fd..28694f38585 100644
--- a/lib/private/Http/Client/Client.php
+++ b/lib/private/Http/Client/Client.php
@@ -63,6 +63,7 @@ class Client implements IClient {
$defaults = [
RequestOptions::PROXY => $this->getProxyUri(),
RequestOptions::VERIFY => $this->getCertBundle(),
+ RequestOptions::TIMEOUT => 30,
];
$options = array_merge($defaults, $options);
diff --git a/lib/private/L10N/Factory.php b/lib/private/L10N/Factory.php
index 80f12c0a832..2e1652e9a1b 100644
--- a/lib/private/L10N/Factory.php
+++ b/lib/private/L10N/Factory.php
@@ -469,7 +469,6 @@ class Factory implements IFactory {
if (($this->isSubDirectory($transFile, $this->serverRoot . '/core/l10n/')
|| $this->isSubDirectory($transFile, $this->serverRoot . '/lib/l10n/')
- || $this->isSubDirectory($transFile, $this->serverRoot . '/settings/l10n/')
|| $this->isSubDirectory($transFile, \OC_App::getAppPath($app) . '/l10n/')
)
&& file_exists($transFile)) {
@@ -496,7 +495,7 @@ class Factory implements IFactory {
* @return string directory
*/
protected function findL10nDir($app = null) {
- if (in_array($app, ['core', 'lib', 'settings'])) {
+ if (in_array($app, ['core', 'lib'])) {
if (file_exists($this->serverRoot . '/' . $app . '/l10n/')) {
return $this->serverRoot . '/' . $app . '/l10n/';
}
diff --git a/lib/private/L10N/LanguageNotFoundException.php b/lib/private/L10N/LanguageNotFoundException.php
index 317e0629b60..0f3b8140e08 100644
--- a/lib/private/L10N/LanguageNotFoundException.php
+++ b/lib/private/L10N/LanguageNotFoundException.php
@@ -20,6 +20,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
+
namespace OC\L10N;
class LanguageNotFoundException extends \Exception {
diff --git a/lib/private/Lock/MemcacheLockingProvider.php b/lib/private/Lock/MemcacheLockingProvider.php
index 4d1b3dc0bca..368c672dbb2 100644
--- a/lib/private/Lock/MemcacheLockingProvider.php
+++ b/lib/private/Lock/MemcacheLockingProvider.php
@@ -23,9 +23,9 @@ declare(strict_types=1);
namespace OC\Lock;
+use OCP\IMemcache;
use OCP\IMemcacheTTL;
use OCP\Lock\LockedException;
-use OCP\IMemcache;
class MemcacheLockingProvider extends AbstractLockingProvider {
/**
diff --git a/lib/private/Log.php b/lib/private/Log.php
index 4af833d778f..22792fe4020 100644
--- a/lib/private/Log.php
+++ b/lib/private/Log.php
@@ -39,9 +39,9 @@ use function array_merge;
use InterfaSys\LogNormalizer\Normalizer;
use OC\Log\ExceptionSerializer;
+use OCP\ILogger;
use OCP\Log\IFileBased;
use OCP\Log\IWriter;
-use OCP\ILogger;
use OCP\Support\CrashReport\IRegistry;
/**
@@ -214,24 +214,27 @@ class Log implements ILogger {
}
$message = strtr($message, $replace);
- if ($level >= $minLevel) {
- $this->writeLog($app, $message, $level);
-
- if ($this->crashReporters !== null) {
- $messageContext = array_merge(
- $context,
- [
- 'level' => $level
- ]
- );
- $this->crashReporters->delegateMessage($message, $messageContext);
- }
- } else {
- if ($this->crashReporters !== null) {
- $this->crashReporters->delegateBreadcrumb($message, 'log', $context);
+ try {
+ if ($level >= $minLevel) {
+ $this->writeLog($app, $message, $level);
+
+ if ($this->crashReporters !== null) {
+ $messageContext = array_merge(
+ $context,
+ [
+ 'level' => $level
+ ]
+ );
+ $this->crashReporters->delegateMessage($message, $messageContext);
+ }
+ } else {
+ if ($this->crashReporters !== null) {
+ $this->crashReporters->delegateBreadcrumb($message, 'log', $context);
+ }
}
+ } catch (\Throwable $e) {
+ // make sure we dont hard crash if logging fails
}
-
}
private function getLogLevel($context) {
@@ -318,16 +321,20 @@ class Log implements ILogger {
array_walk($context, [$this->normalizer, 'format']);
- if ($level >= $minLevel) {
- if (!$this->logger instanceof IFileBased) {
- $data = json_encode($data, JSON_PARTIAL_OUTPUT_ON_ERROR);
+ try {
+ if ($level >= $minLevel) {
+ if (!$this->logger instanceof IFileBased) {
+ $data = json_encode($data, JSON_PARTIAL_OUTPUT_ON_ERROR | JSON_UNESCAPED_SLASHES);
+ }
+ $this->writeLog($app, $data, $level);
}
- $this->writeLog($app, $data, $level);
- }
- $context['level'] = $level;
- if (!is_null($this->crashReporters)) {
- $this->crashReporters->delegateReport($exception, $context);
+ $context['level'] = $level;
+ if (!is_null($this->crashReporters)) {
+ $this->crashReporters->delegateReport($exception, $context);
+ }
+ } catch (\Throwable $e) {
+ // make sure we dont hard crash if logging fails
}
}
diff --git a/lib/private/Log/Errorlog.php b/lib/private/Log/Errorlog.php
index 9dc8b2cc49c..ebcb73be4ce 100644
--- a/lib/private/Log/Errorlog.php
+++ b/lib/private/Log/Errorlog.php
@@ -39,4 +39,3 @@ class Errorlog implements IWriter {
error_log('[owncloud]['.$app.']['.$level.'] '.$message);
}
}
-
diff --git a/lib/private/Log/ExceptionSerializer.php b/lib/private/Log/ExceptionSerializer.php
index 8cfdb57b225..a3b855aea26 100644
--- a/lib/private/Log/ExceptionSerializer.php
+++ b/lib/private/Log/ExceptionSerializer.php
@@ -92,7 +92,9 @@ class ExceptionSerializer {
];
private function editTrace(array &$sensitiveValues, array $traceLine): array {
- $sensitiveValues = array_merge($sensitiveValues, $traceLine['args']);
+ if (isset($traceLine['args'])) {
+ $sensitiveValues = array_merge($sensitiveValues, $traceLine['args']);
+ }
$traceLine['args'] = ['*** sensitive parameters replaced ***'];
return $traceLine;
}
diff --git a/lib/private/Log/File.php b/lib/private/Log/File.php
index fe2bbf30a26..b982836b8ef 100644
--- a/lib/private/Log/File.php
+++ b/lib/private/Log/File.php
@@ -37,9 +37,9 @@
namespace OC\Log;
use OC\SystemConfig;
+use OCP\ILogger;
use OCP\Log\IFileBased;
use OCP\Log\IWriter;
-use OCP\ILogger;
/**
* logging utilities
diff --git a/lib/private/Log/LogDetails.php b/lib/private/Log/LogDetails.php
index 712b5403ca0..e833221e222 100644
--- a/lib/private/Log/LogDetails.php
+++ b/lib/private/Log/LogDetails.php
@@ -90,12 +90,12 @@ abstract class LogDetails {
// them manually.
foreach($entry as $key => $value) {
if(is_string($value)) {
- $testEncode = json_encode($value);
+ $testEncode = json_encode($value, JSON_UNESCAPED_SLASHES);
if($testEncode === false) {
$entry[$key] = utf8_encode($value);
}
}
}
- return json_encode($entry, JSON_PARTIAL_OUTPUT_ON_ERROR);
+ return json_encode($entry, JSON_PARTIAL_OUTPUT_ON_ERROR | JSON_UNESCAPED_SLASHES);
}
}
diff --git a/lib/private/Log/Systemdlog.php b/lib/private/Log/Systemdlog.php
index c40e4860f95..1fd0a6a419b 100644
--- a/lib/private/Log/Systemdlog.php
+++ b/lib/private/Log/Systemdlog.php
@@ -24,8 +24,8 @@ namespace OC\Log;
use OC\HintException;
use OC\SystemConfig;
-use OCP\ILogger;
use OCP\IConfig;
+use OCP\ILogger;
use OCP\Log\IWriter;
// The following fields are understood by systemd/journald, see
diff --git a/lib/private/Mail/Mailer.php b/lib/private/Mail/Mailer.php
index d103e1380c5..e3547c84da3 100644
--- a/lib/private/Mail/Mailer.php
+++ b/lib/private/Mail/Mailer.php
@@ -31,11 +31,11 @@ use Egulias\EmailValidator\Validation\RFCValidation;
use OCP\Defaults;
use OCP\IConfig;
use OCP\IL10N;
+use OCP\ILogger;
use OCP\IURLGenerator;
use OCP\Mail\IAttachment;
use OCP\Mail\IEMailTemplate;
use OCP\Mail\IMailer;
-use OCP\ILogger;
use OCP\Mail\IMessage;
/**
diff --git a/lib/private/Memcache/Redis.php b/lib/private/Memcache/Redis.php
index adf3c5050bd..8d0d1679e80 100644
--- a/lib/private/Memcache/Redis.php
+++ b/lib/private/Memcache/Redis.php
@@ -178,4 +178,3 @@ class Redis extends Cache implements IMemcacheTTL {
return \OC::$server->getGetRedisFactory()->isAvailable();
}
}
-
diff --git a/lib/private/Migration/BackgroundRepair.php b/lib/private/Migration/BackgroundRepair.php
index 7ef90301cf3..7cab14f5ccc 100644
--- a/lib/private/Migration/BackgroundRepair.php
+++ b/lib/private/Migration/BackgroundRepair.php
@@ -20,6 +20,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
+
namespace OC\Migration;
use OC\BackgroundJob\JobList;
diff --git a/lib/private/Migration/ConsoleOutput.php b/lib/private/Migration/ConsoleOutput.php
index 74c8c7340cc..d3487a771cc 100644
--- a/lib/private/Migration/ConsoleOutput.php
+++ b/lib/private/Migration/ConsoleOutput.php
@@ -20,7 +20,6 @@
*
*/
-
namespace OC\Migration;
diff --git a/lib/private/Migration/SimpleOutput.php b/lib/private/Migration/SimpleOutput.php
index ea61c44fcac..c3426a426f8 100644
--- a/lib/private/Migration/SimpleOutput.php
+++ b/lib/private/Migration/SimpleOutput.php
@@ -20,7 +20,6 @@
*
*/
-
namespace OC\Migration;
diff --git a/lib/private/NavigationManager.php b/lib/private/NavigationManager.php
index 2c41fbd88c2..2f6befc632c 100644
--- a/lib/private/NavigationManager.php
+++ b/lib/private/NavigationManager.php
@@ -199,7 +199,7 @@ class NavigationManager implements INavigationManager {
'type' => 'settings',
'id' => 'help',
'order' => 5,
- 'href' => $this->urlGenerator->linkToRoute('settings_help'),
+ 'href' => $this->urlGenerator->linkToRoute('settings.Help.help'),
'name' => $l->t('Help'),
'icon' => $this->urlGenerator->imagePath('settings', 'help.svg'),
]);
diff --git a/lib/private/OCS/DiscoveryService.php b/lib/private/OCS/DiscoveryService.php
index 6662263fb76..f084dae35ed 100644
--- a/lib/private/OCS/DiscoveryService.php
+++ b/lib/private/OCS/DiscoveryService.php
@@ -22,7 +22,6 @@ declare(strict_types=1);
*
*/
-
namespace OC\OCS;
use OCP\AppFramework\Http;
diff --git a/lib/private/Preview/Bitmap.php b/lib/private/Preview/Bitmap.php
index 000b1f8277f..fe309376296 100644
--- a/lib/private/Preview/Bitmap.php
+++ b/lib/private/Preview/Bitmap.php
@@ -26,9 +26,9 @@
namespace OC\Preview;
use Imagick;
+use OCP\Files\File;
use OCP\IImage;
use OCP\ILogger;
-use OCP\Files\File;
/**
* Creates a PNG preview using ImageMagick via the PECL extension
diff --git a/lib/private/Preview/Generator.php b/lib/private/Preview/Generator.php
index 79c512c84aa..981c820ccf3 100644
--- a/lib/private/Preview/Generator.php
+++ b/lib/private/Preview/Generator.php
@@ -36,8 +36,8 @@ use OCP\IConfig;
use OCP\IImage;
use OCP\IPreview;
use OCP\Preview\IProvider;
-use OCP\Preview\IVersionedPreviewFile;
use OCP\Preview\IProviderV2;
+use OCP\Preview\IVersionedPreviewFile;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\EventDispatcher\GenericEvent;
diff --git a/lib/private/Preview/GeneratorHelper.php b/lib/private/Preview/GeneratorHelper.php
index 7e35b5360d4..4389e269c8b 100644
--- a/lib/private/Preview/GeneratorHelper.php
+++ b/lib/private/Preview/GeneratorHelper.php
@@ -20,6 +20,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
+
namespace OC\Preview;
use OC\Files\View;
diff --git a/lib/private/Preview/HEIC.php b/lib/private/Preview/HEIC.php
index d23e6c6bd1f..9f4f9be38df 100644
--- a/lib/private/Preview/HEIC.php
+++ b/lib/private/Preview/HEIC.php
@@ -23,9 +23,9 @@ declare(strict_types=1);
namespace OC\Preview;
+use OCP\Files\File;
use OCP\IImage;
use OCP\ILogger;
-use OCP\Files\File;
/**
* Creates a JPG preview using ImageMagick via the PECL extension
diff --git a/lib/private/Preview/Image.php b/lib/private/Preview/Image.php
index 6f82904a6a7..b8767d3f639 100644
--- a/lib/private/Preview/Image.php
+++ b/lib/private/Preview/Image.php
@@ -25,6 +25,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
+
namespace OC\Preview;
use OCP\Files\File;
diff --git a/lib/private/Preview/MP3.php b/lib/private/Preview/MP3.php
index f560f100109..6b19602b5c9 100644
--- a/lib/private/Preview/MP3.php
+++ b/lib/private/Preview/MP3.php
@@ -24,6 +24,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
+
namespace OC\Preview;
use ID3Parser\ID3Parser;
diff --git a/lib/private/Preview/MSOffice2003.php b/lib/private/Preview/MSOffice2003.php
index 5af66f72720..67559224528 100644
--- a/lib/private/Preview/MSOffice2003.php
+++ b/lib/private/Preview/MSOffice2003.php
@@ -19,6 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
+
namespace OC\Preview;
//.docm, .dotm, .xls(m), .xlt(m), .xla(m), .ppt(m), .pot(m), .pps(m), .ppa(m)
diff --git a/lib/private/Preview/MSOffice2007.php b/lib/private/Preview/MSOffice2007.php
index 0d1177d9de9..125e0ecfcad 100644
--- a/lib/private/Preview/MSOffice2007.php
+++ b/lib/private/Preview/MSOffice2007.php
@@ -19,6 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
+
namespace OC\Preview;
//.docx, .dotx, .xlsx, .xltx, .pptx, .potx, .ppsx
diff --git a/lib/private/Preview/MSOfficeDoc.php b/lib/private/Preview/MSOfficeDoc.php
index 24d1a9d5b6a..e1359c6b903 100644
--- a/lib/private/Preview/MSOfficeDoc.php
+++ b/lib/private/Preview/MSOfficeDoc.php
@@ -19,6 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
+
namespace OC\Preview;
//.doc, .dot
diff --git a/lib/private/Preview/MarkDown.php b/lib/private/Preview/MarkDown.php
index ae24c4f4419..bdf16ae2bc5 100644
--- a/lib/private/Preview/MarkDown.php
+++ b/lib/private/Preview/MarkDown.php
@@ -19,6 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
+
namespace OC\Preview;
class MarkDown extends TXT {
diff --git a/lib/private/Preview/Movie.php b/lib/private/Preview/Movie.php
index 2f64811b45e..17916896f97 100644
--- a/lib/private/Preview/Movie.php
+++ b/lib/private/Preview/Movie.php
@@ -23,6 +23,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
+
namespace OC\Preview;
use OCP\Files\File;
@@ -88,8 +89,8 @@ class Movie extends ProviderV2 {
if ($returnCode === 0) {
$image = new \OC_Image();
$image->loadFromFile($tmpPath);
- unlink($tmpPath);
if ($image->valid()) {
+ unlink($tmpPath);
$image->scaleDownToFit($maxX, $maxY);
return $image;
diff --git a/lib/private/Preview/Office.php b/lib/private/Preview/Office.php
index f51023c5a83..49437aec186 100644
--- a/lib/private/Preview/Office.php
+++ b/lib/private/Preview/Office.php
@@ -23,11 +23,12 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
+
namespace OC\Preview;
+use OCP\Files\File;
use OCP\IImage;
use OCP\ILogger;
-use OCP\Files\File;
abstract class Office extends ProviderV2 {
private $cmd;
diff --git a/lib/private/Preview/OpenDocument.php b/lib/private/Preview/OpenDocument.php
index 929fecffb21..ab3394ffea0 100644
--- a/lib/private/Preview/OpenDocument.php
+++ b/lib/private/Preview/OpenDocument.php
@@ -19,6 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
+
namespace OC\Preview;
//.odt, .ott, .oth, .odm, .odg, .otg, .odp, .otp, .ods, .ots, .odc, .odf, .odb, .odi, .oxt
diff --git a/lib/private/Preview/Provider.php b/lib/private/Preview/Provider.php
index d0dd259891f..ed128638e4b 100644
--- a/lib/private/Preview/Provider.php
+++ b/lib/private/Preview/Provider.php
@@ -23,6 +23,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
+
namespace OC\Preview;
use OCP\Preview\IProvider;
diff --git a/lib/private/Preview/ProviderV1Adapter.php b/lib/private/Preview/ProviderV1Adapter.php
index 903a7904bf8..0685193eb5b 100644
--- a/lib/private/Preview/ProviderV1Adapter.php
+++ b/lib/private/Preview/ProviderV1Adapter.php
@@ -36,11 +36,11 @@ class ProviderV1Adapter implements IProviderV2 {
}
public function getMimeType(): string {
- return $this->providerV1->getMimeType();
+ return (string)$this->providerV1->getMimeType();
}
public function isAvailable(FileInfo $file): bool {
- return $this->providerV1->isAvailable($file);
+ return (bool)$this->providerV1->isAvailable($file);
}
public function getThumbnail(File $file, int $maxX, int $maxY): ?IImage {
diff --git a/lib/private/Preview/SVG.php b/lib/private/Preview/SVG.php
index 3f313f4bb9b..2fe4c464575 100644
--- a/lib/private/Preview/SVG.php
+++ b/lib/private/Preview/SVG.php
@@ -22,11 +22,12 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
+
namespace OC\Preview;
+use OCP\Files\File;
use OCP\IImage;
use OCP\ILogger;
-use OCP\Files\File;
class SVG extends ProviderV2 {
/**
diff --git a/lib/private/Preview/StarOffice.php b/lib/private/Preview/StarOffice.php
index 2c9542b22e6..1300bdc7b41 100644
--- a/lib/private/Preview/StarOffice.php
+++ b/lib/private/Preview/StarOffice.php
@@ -19,6 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
+
namespace OC\Preview;
//.sxw, .stw, .sxc, .stc, .sxd, .std, .sxi, .sti, .sxg, .sxm
diff --git a/lib/private/Preview/TXT.php b/lib/private/Preview/TXT.php
index 3e2032df2de..d1ee1c025ea 100644
--- a/lib/private/Preview/TXT.php
+++ b/lib/private/Preview/TXT.php
@@ -24,6 +24,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
+
namespace OC\Preview;
use OCP\Files\File;
diff --git a/lib/private/Preview/Watcher.php b/lib/private/Preview/Watcher.php
index 0c0531dff94..30708445c76 100644
--- a/lib/private/Preview/Watcher.php
+++ b/lib/private/Preview/Watcher.php
@@ -21,11 +21,12 @@ declare(strict_types=1);
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
+
namespace OC\Preview;
-use OCP\Files\Node;
use OCP\Files\Folder;
use OCP\Files\IAppData;
+use OCP\Files\Node;
use OCP\Files\NotFoundException;
/**
diff --git a/lib/private/Preview/WatcherConnector.php b/lib/private/Preview/WatcherConnector.php
index f374b909d8f..346634ccf3a 100644
--- a/lib/private/Preview/WatcherConnector.php
+++ b/lib/private/Preview/WatcherConnector.php
@@ -21,11 +21,12 @@ declare(strict_types=1);
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
+
namespace OC\Preview;
use OC\SystemConfig;
-use OCP\Files\Node;
use OCP\Files\IRootFolder;
+use OCP\Files\Node;
class WatcherConnector {
diff --git a/lib/private/PreviewManager.php b/lib/private/PreviewManager.php
index 621c45f28c5..45b1529648b 100644
--- a/lib/private/PreviewManager.php
+++ b/lib/private/PreviewManager.php
@@ -24,6 +24,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
+
namespace OC;
use OC\Preview\Generator;
@@ -149,34 +150,6 @@ class PreviewManager implements IPreview {
}
/**
- * return a preview of a file
- *
- * @param string $file The path to the file where you want a thumbnail from
- * @param int $maxX The maximum X size of the thumbnail. It can be smaller depending on the shape of the image
- * @param int $maxY The maximum Y size of the thumbnail. It can be smaller depending on the shape of the image
- * @param boolean $scaleUp Scale smaller images up to the thumbnail size or not. Might look ugly
- * @return \OCP\IImage
- * @deprecated 11 Use getPreview
- */
- public function createPreview($file, $maxX = 100, $maxY = 75, $scaleUp = false) {
- try {
- $userRoot = $this->rootFolder->getUserFolder($this->userId)->getParent();
- $node = $userRoot->get($file);
- if (!($file instanceof File)) {
- throw new NotFoundException();
- }
-
- $preview = $this->getPreview($node, $maxX, $maxY);
- } catch (\Exception $e) {
- return new \OC_Image();
- }
-
- $previewImage = new \OC_Image();
- $previewImage->loadFromData($preview->getContent());
- return $previewImage;
- }
-
- /**
* Returns a preview of a file
*
* The cache is searched first and if nothing usable was found then a preview is
diff --git a/lib/private/Repair.php b/lib/private/Repair.php
index 35e6856e429..2b6080ca985 100644
--- a/lib/private/Repair.php
+++ b/lib/private/Repair.php
@@ -42,7 +42,7 @@ use OC\Repair\NC13\AddLogRotateJob;
use OC\Repair\NC14\AddPreviewBackgroundCleanupJob;
use OC\Repair\NC16\AddClenupLoginFlowV2BackgroundJob;
use OC\Repair\NC16\CleanupCardDAVPhotoCache;
-use OC\Repair\NC16\RemoveCypressFiles;
+use OC\Repair\NC16\ClearCollectionsAccessCache;
use OC\Repair\NC17\SetEnterpriseLogo;
use OC\Repair\NC17\SwitchUpdateChannel;
use OC\Repair\OldGroupMembershipShares;
@@ -56,6 +56,7 @@ use OC\Template\JSCombiner;
use OC\Template\SCSSCacher;
use OCP\AppFramework\QueryException;
use OCP\AppFramework\Utility\ITimeFactory;
+use OCP\Collaboration\Resources\IManager;
use OCP\Migration\IOutput;
use OCP\Migration\IRepairStep;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
@@ -150,7 +151,7 @@ class Repair implements IOutput {
new CleanupCardDAVPhotoCache(\OC::$server->getConfig(), \OC::$server->getAppDataDir('dav-photocache'), \OC::$server->getLogger()),
new AddClenupLoginFlowV2BackgroundJob(\OC::$server->getJobList()),
new RemoveLinkShares(\OC::$server->getDatabaseConnection(), \OC::$server->getConfig(), \OC::$server->getGroupManager(), \OC::$server->getNotificationManager(), \OC::$server->query(ITimeFactory::class)),
- \OC::$server->query(RemoveCypressFiles::class),
+ new ClearCollectionsAccessCache(\OC::$server->getConfig(), \OC::$server->query(IManager::class)),
\OC::$server->query(SwitchUpdateChannel::class),
\OC::$server->query(SetEnterpriseLogo::class),
];
diff --git a/lib/private/Repair/AddCleanupUpdaterBackupsJob.php b/lib/private/Repair/AddCleanupUpdaterBackupsJob.php
index 1574e665fb6..cf35bc1fda5 100644
--- a/lib/private/Repair/AddCleanupUpdaterBackupsJob.php
+++ b/lib/private/Repair/AddCleanupUpdaterBackupsJob.php
@@ -45,4 +45,3 @@ class AddCleanupUpdaterBackupsJob implements IRepairStep {
$this->jobList->add(BackgroundCleanupUpdaterBackupsJob::class);
}
}
-
diff --git a/lib/private/Repair/ClearFrontendCaches.php b/lib/private/Repair/ClearFrontendCaches.php
index 22add525adb..90fdaf6b70f 100644
--- a/lib/private/Repair/ClearFrontendCaches.php
+++ b/lib/private/Repair/ClearFrontendCaches.php
@@ -23,11 +23,11 @@
namespace OC\Repair;
+use OC\Template\JSCombiner;
+use OC\Template\SCSSCacher;
use OCP\ICacheFactory;
use OCP\Migration\IOutput;
use OCP\Migration\IRepairStep;
-use OC\Template\JSCombiner;
-use OC\Template\SCSSCacher;
class ClearFrontendCaches implements IRepairStep {
diff --git a/lib/private/Repair/Collation.php b/lib/private/Repair/Collation.php
index f2cc9373176..a7a53720db5 100644
--- a/lib/private/Repair/Collation.php
+++ b/lib/private/Repair/Collation.php
@@ -151,4 +151,3 @@ class Collation implements IRepairStep {
return array_keys($result);
}
}
-
diff --git a/lib/private/Repair/MoveUpdaterStepFile.php b/lib/private/Repair/MoveUpdaterStepFile.php
index feb8a291282..adeabea9672 100644
--- a/lib/private/Repair/MoveUpdaterStepFile.php
+++ b/lib/private/Repair/MoveUpdaterStepFile.php
@@ -77,4 +77,3 @@ class MoveUpdaterStepFile implements IRepairStep {
}
}
}
-
diff --git a/lib/private/Repair/NC11/FixMountStorages.php b/lib/private/Repair/NC11/FixMountStorages.php
index d57a356dff9..c3c239d11ba 100644
--- a/lib/private/Repair/NC11/FixMountStorages.php
+++ b/lib/private/Repair/NC11/FixMountStorages.php
@@ -20,6 +20,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
+
namespace OC\Repair\NC11;
use OCP\DB\QueryBuilder\IQueryBuilder;
diff --git a/lib/private/Repair/NC13/AddLogRotateJob.php b/lib/private/Repair/NC13/AddLogRotateJob.php
index c65ea47f02b..0d258aa3779 100644
--- a/lib/private/Repair/NC13/AddLogRotateJob.php
+++ b/lib/private/Repair/NC13/AddLogRotateJob.php
@@ -20,6 +20,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
+
namespace OC\Repair\NC13;
use OC\Log\Rotate;
diff --git a/lib/private/Repair/NC14/AddPreviewBackgroundCleanupJob.php b/lib/private/Repair/NC14/AddPreviewBackgroundCleanupJob.php
index b58fabcba50..7bef59a9d37 100644
--- a/lib/private/Repair/NC14/AddPreviewBackgroundCleanupJob.php
+++ b/lib/private/Repair/NC14/AddPreviewBackgroundCleanupJob.php
@@ -21,6 +21,7 @@ declare(strict_types=1);
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
+
namespace OC\Repair\NC14;
use OC\Preview\BackgroundCleanupJob;
diff --git a/lib/private/Repair/NC16/ClearCollectionsAccessCache.php b/lib/private/Repair/NC16/ClearCollectionsAccessCache.php
new file mode 100644
index 00000000000..7945fffb822
--- /dev/null
+++ b/lib/private/Repair/NC16/ClearCollectionsAccessCache.php
@@ -0,0 +1,58 @@
+<?php
+declare(strict_types=1);
+/**
+ * @copyright Copyright (c) 2019 Joas Schilling <coding@schilljs.com>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OC\Repair\NC16;
+
+use OC\Collaboration\Resources\Manager;
+use OCP\Collaboration\Resources\IManager;
+use OCP\IConfig;
+use OCP\Migration\IOutput;
+use OCP\Migration\IRepairStep;
+
+class ClearCollectionsAccessCache implements IRepairStep {
+
+ /** @var IConfig */
+ private $config;
+
+ /** @var IManager|Manager */
+ private $manager;
+
+ public function __construct(IConfig $config, IManager $manager) {
+ $this->config = $config;
+ $this->manager = $manager;
+ }
+
+ public function getName(): string {
+ return 'Clear access cache of projects';
+ }
+
+ private function shouldRun(): bool {
+ $versionFromBeforeUpdate = $this->config->getSystemValue('version', '0.0.0.0');
+ return version_compare($versionFromBeforeUpdate, '17.0.0.3', '<=');
+ }
+
+ public function run(IOutput $output): void {
+ if ($this->shouldRun()) {
+ $this->manager->invalidateAccessCacheForAllCollections();
+ }
+ }
+}
diff --git a/lib/private/Repair/NC16/RemoveCypressFiles.php b/lib/private/Repair/NC16/RemoveCypressFiles.php
deleted file mode 100644
index 4b6108d0232..00000000000
--- a/lib/private/Repair/NC16/RemoveCypressFiles.php
+++ /dev/null
@@ -1,82 +0,0 @@
-<?php
-declare(strict_types=1);
-/**
- * @copyright Copyright (c) 2019, Morris Jobke <hey@morrisjobke.de>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-namespace OC\Repair\NC16;
-
-use OC\IntegrityCheck\Checker;
-use OCP\Migration\IOutput;
-use OCP\Migration\IRepairStep;
-
-/**
- * Class CleanupCypressFiles
- *
- * This repair step removes "cypress" files and folder created by viewer app in 16.0.1
- *
- * See https://github.com/nextcloud/server/issues/16229 for more details.
- *
- * @deprecated - can be removed in 18 because this is the first version where no migration from 16 can happen
- */
-class RemoveCypressFiles implements IRepairStep {
-
- /** @var Checker $checker */
- private $checker;
-
- private $pathToViewerApp = __DIR__ . '/../../../../apps/viewer';
-
- public function getName(): string {
- return 'Cleanup cypress files from viewer app';
- }
-
- public function __construct(Checker $checker) {
- $this->checker = $checker;
- }
-
- public function run(IOutput $output): void {
- $file = $this->pathToViewerApp . '/cypress.json';
- if (file_exists($file)) {
- unlink($file);
- }
-
- $dir = $this->pathToViewerApp . '/cypress';
- if (is_dir($dir)) {
- $files = new \RecursiveIteratorIterator(
- new \RecursiveDirectoryIterator($dir, \RecursiveDirectoryIterator::SKIP_DOTS),
- \RecursiveIteratorIterator::CHILD_FIRST
- );
-
- foreach ($files as $fileInfo) {
- /** @var \SplFileInfo $fileInfo */
- if ($fileInfo->isLink()) {
- unlink($fileInfo->getPathname());
- } else if ($fileInfo->isDir()) {
- rmdir($fileInfo->getRealPath());
- } else {
- unlink($fileInfo->getRealPath());
- }
- }
- rmdir($dir);
- }
-
- // re-run the instance verification
- $this->checker->runInstanceVerification();
- }
-}
diff --git a/lib/private/Repair/NC17/SwitchUpdateChannel.php b/lib/private/Repair/NC17/SwitchUpdateChannel.php
index cfa72d86b1e..8a2850080a6 100644
--- a/lib/private/Repair/NC17/SwitchUpdateChannel.php
+++ b/lib/private/Repair/NC17/SwitchUpdateChannel.php
@@ -26,6 +26,7 @@ use OCP\IConfig;
use OCP\Migration\IOutput;
use OCP\Migration\IRepairStep;
use OCP\Support\Subscription\IRegistry;
+
/**
* @deprecated - can be removed in 18
*/
diff --git a/lib/private/Repair/Owncloud/DropAccountTermsTable.php b/lib/private/Repair/Owncloud/DropAccountTermsTable.php
index 0b1b64c3a3a..9c18ff809ae 100644
--- a/lib/private/Repair/Owncloud/DropAccountTermsTable.php
+++ b/lib/private/Repair/Owncloud/DropAccountTermsTable.php
@@ -57,4 +57,3 @@ class DropAccountTermsTable implements IRepairStep {
$this->db->dropTable('account_terms');
}
}
-
diff --git a/lib/private/Repair/Owncloud/SaveAccountsTableData.php b/lib/private/Repair/Owncloud/SaveAccountsTableData.php
index f62f8b56b26..13f618b6747 100644
--- a/lib/private/Repair/Owncloud/SaveAccountsTableData.php
+++ b/lib/private/Repair/Owncloud/SaveAccountsTableData.php
@@ -189,4 +189,3 @@ class SaveAccountsTableData implements IRepairStep {
}
}
-
diff --git a/lib/private/Repair/SqliteAutoincrement.php b/lib/private/Repair/SqliteAutoincrement.php
index 814f955dc70..93f9961d565 100644
--- a/lib/private/Repair/SqliteAutoincrement.php
+++ b/lib/private/Repair/SqliteAutoincrement.php
@@ -24,10 +24,10 @@
namespace OC\Repair;
use Doctrine\DBAL\Platforms\SqlitePlatform;
-use Doctrine\DBAL\Schema\SchemaException;
+use Doctrine\DBAL\Schema\ColumnDiff;
use Doctrine\DBAL\Schema\SchemaDiff;
+use Doctrine\DBAL\Schema\SchemaException;
use Doctrine\DBAL\Schema\TableDiff;
-use Doctrine\DBAL\Schema\ColumnDiff;
use OCP\Migration\IOutput;
use OCP\Migration\IRepairStep;
@@ -98,4 +98,3 @@ class SqliteAutoincrement implements IRepairStep {
$this->connection->commit();
}
}
-
diff --git a/lib/private/Route/CachingRouter.php b/lib/private/Route/CachingRouter.php
index cb1b98d77e6..a37bbf5b701 100644
--- a/lib/private/Route/CachingRouter.php
+++ b/lib/private/Route/CachingRouter.php
@@ -58,7 +58,9 @@ class CachingRouter extends Router {
return $cachedKey;
} else {
$url = parent::generate($name, $parameters, $absolute);
- $this->cache->set($key, $url, 3600);
+ if ($url) {
+ $this->cache->set($key, $url, 3600);
+ }
return $url;
}
}
diff --git a/lib/private/Route/Router.php b/lib/private/Route/Router.php
index 1839b356424..125c5ff2742 100644
--- a/lib/private/Route/Router.php
+++ b/lib/private/Route/Router.php
@@ -33,16 +33,16 @@
namespace OC\Route;
+use OCP\AppFramework\App;
use OCP\ILogger;
use OCP\Route\IRouter;
-use OCP\AppFramework\App;
use OCP\Util;
+use Symfony\Component\Routing\Exception\ResourceNotFoundException;
use Symfony\Component\Routing\Exception\RouteNotFoundException;
-use Symfony\Component\Routing\Matcher\UrlMatcher;
use Symfony\Component\Routing\Generator\UrlGenerator;
+use Symfony\Component\Routing\Matcher\UrlMatcher;
use Symfony\Component\Routing\RequestContext;
use Symfony\Component\Routing\RouteCollection;
-use Symfony\Component\Routing\Exception\ResourceNotFoundException;
class Router implements IRouter {
/** @var RouteCollection[] */
@@ -162,7 +162,6 @@ class Router implements IRouter {
if (!isset($this->loadedApps['core'])) {
$this->loadedApps['core'] = true;
$this->useCollection('root');
- require_once __DIR__ . '/../../../settings/routes.php';
require_once __DIR__ . '/../../../core/routes.php';
// Also add the OCS collection
@@ -258,7 +257,9 @@ class Router implements IRouter {
$app = \OC_App::cleanAppId($app);
\OC::$REQUESTEDAPP = $app;
$this->loadRoutes($app);
- } else if (substr($url, 0, 6) === '/core/' or substr($url, 0, 10) === '/settings/') {
+ } else if (substr($url, 0, 10) === '/settings/') {
+ $this->loadRoutes('settings');
+ } else if (substr($url, 0, 6) === '/core/') {
\OC::$REQUESTEDAPP = $url;
if (!\OC::$server->getConfig()->getSystemValueBool('maintenance') && !Util::needUpgrade()) {
\OC_App::loadApps();
@@ -370,7 +371,7 @@ class Router implements IRouter {
$applicationClassName = $appNameSpace . '\\AppInfo\\Application';
if (class_exists($applicationClassName)) {
- $application = new $applicationClassName();
+ $application = \OC::$server->query($applicationClassName);
} else {
$application = new App($appName);
}
diff --git a/lib/private/Search.php b/lib/private/Search.php
index 0cfdf24ac97..2ef7eeda4ad 100644
--- a/lib/private/Search.php
+++ b/lib/private/Search.php
@@ -25,9 +25,9 @@
*/
namespace OC;
+use OCP\ISearch;
use OCP\Search\PagedProvider;
use OCP\Search\Provider;
-use OCP\ISearch;
/**
* Provide an interface to all search providers
diff --git a/lib/private/Security/Bruteforce/Capabilities.php b/lib/private/Security/Bruteforce/Capabilities.php
index 3df0458c694..d6e08c399ed 100644
--- a/lib/private/Security/Bruteforce/Capabilities.php
+++ b/lib/private/Security/Bruteforce/Capabilities.php
@@ -20,6 +20,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
+
namespace OC\Security\Bruteforce;
use OCP\Capabilities\IPublicCapability;
diff --git a/lib/private/Security/CSP/ContentSecurityPolicy.php b/lib/private/Security/CSP/ContentSecurityPolicy.php
index 9d1d043a165..c912b820eba 100644
--- a/lib/private/Security/CSP/ContentSecurityPolicy.php
+++ b/lib/private/Security/CSP/ContentSecurityPolicy.php
@@ -21,6 +21,7 @@ declare(strict_types=1);
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
+
namespace OC\Security\CSP;
/**
diff --git a/lib/private/Security/CredentialsManager.php b/lib/private/Security/CredentialsManager.php
index 0ac9b30c6ce..7c58cb3b1c9 100644
--- a/lib/private/Security/CredentialsManager.php
+++ b/lib/private/Security/CredentialsManager.php
@@ -22,9 +22,9 @@
namespace OC\Security;
-use OCP\Security\ICrypto;
use OCP\IDBConnection;
use OCP\Security\ICredentialsManager;
+use OCP\Security\ICrypto;
/**
* Store and retrieve credentials for external services
diff --git a/lib/private/Security/Crypto.php b/lib/private/Security/Crypto.php
index 876f159950c..2eb20d41456 100644
--- a/lib/private/Security/Crypto.php
+++ b/lib/private/Security/Crypto.php
@@ -24,14 +24,13 @@ declare(strict_types=1);
*
*/
-
namespace OC\Security;
-use phpseclib\Crypt\AES;
-use phpseclib\Crypt\Hash;
+use OCP\IConfig;
use OCP\Security\ICrypto;
use OCP\Security\ISecureRandom;
-use OCP\IConfig;
+use phpseclib\Crypt\AES;
+use phpseclib\Crypt\Hash;
/**
* Class Crypto provides a high-level encryption layer using AES-CBC. If no key has been provided
diff --git a/lib/private/Security/IdentityProof/Manager.php b/lib/private/Security/IdentityProof/Manager.php
index fb27f04d873..6db5d4ab2eb 100644
--- a/lib/private/Security/IdentityProof/Manager.php
+++ b/lib/private/Security/IdentityProof/Manager.php
@@ -29,6 +29,7 @@ namespace OC\Security\IdentityProof;
use OC\Files\AppData\Factory;
use OCP\Files\IAppData;
use OCP\IConfig;
+use OCP\ILogger;
use OCP\IUser;
use OCP\Security\ICrypto;
@@ -39,19 +40,18 @@ class Manager {
private $crypto;
/** @var IConfig */
private $config;
+ /** @var ILogger */
+ private $logger;
- /**
- * @param Factory $appDataFactory
- * @param ICrypto $crypto
- * @param IConfig $config
- */
public function __construct(Factory $appDataFactory,
ICrypto $crypto,
- IConfig $config
+ IConfig $config,
+ ILogger $logger
) {
$this->appData = $appDataFactory->get('identityproof');
$this->crypto = $crypto;
$this->config = $config;
+ $this->logger = $logger;
}
/**
@@ -59,6 +59,7 @@ class Manager {
* In a separate function for unit testing purposes.
*
* @return array [$publicKey, $privateKey]
+ * @throws \RuntimeException
*/
protected function generateKeyPair(): array {
$config = [
@@ -68,7 +69,16 @@ class Manager {
// Generate new key
$res = openssl_pkey_new($config);
- openssl_pkey_export($res, $privateKey);
+
+ if ($res === false) {
+ $this->logOpensslError();
+ throw new \RuntimeException('OpenSSL reported a problem');
+ }
+
+ if (openssl_pkey_export($res, $privateKey, null, $config) === false) {
+ $this->logOpensslError();
+ throw new \RuntimeException('OpenSSL reported a problem');
+ }
// Extract the public key from $res to $pubKey
$publicKey = openssl_pkey_get_details($res);
@@ -83,6 +93,7 @@ class Manager {
*
* @param string $id key id
* @return Key
+ * @throws \RuntimeException
*/
protected function generateKey(string $id): Key {
list($publicKey, $privateKey) = $this->generateKeyPair();
@@ -105,6 +116,7 @@ class Manager {
*
* @param string $id
* @return Key
+ * @throws \RuntimeException
*/
protected function retrieveKey(string $id): Key {
try {
@@ -124,6 +136,7 @@ class Manager {
*
* @param IUser $user
* @return Key
+ * @throws \RuntimeException
*/
public function getKey(IUser $user): Key {
$uid = $user->getUID();
@@ -144,5 +157,13 @@ class Manager {
return $this->retrieveKey('system-' . $instanceId);
}
+ private function logOpensslError(): void {
+ $errors = [];
+ while ($error = openssl_error_string()) {
+ $errors[] = $error;
+ }
+ $this->logger->critical('Something is wrong with your openssl setup: ' . implode(', ', $errors));
+ }
+
}
diff --git a/lib/private/Security/RateLimiting/Limiter.php b/lib/private/Security/RateLimiting/Limiter.php
index 5267497f86f..c272120a898 100644
--- a/lib/private/Security/RateLimiting/Limiter.php
+++ b/lib/private/Security/RateLimiting/Limiter.php
@@ -28,9 +28,7 @@ use OC\Security\Normalizer\IpAddress;
use OC\Security\RateLimiting\Backend\IBackend;
use OC\Security\RateLimiting\Exception\RateLimitExceededException;
use OCP\AppFramework\Utility\ITimeFactory;
-use OCP\IRequest;
use OCP\IUser;
-use OCP\IUserSession;
class Limiter {
/** @var IBackend */
@@ -39,14 +37,10 @@ class Limiter {
private $timeFactory;
/**
- * @param IUserSession $userSession
- * @param IRequest $request
* @param ITimeFactory $timeFactory
* @param IBackend $backend
*/
- public function __construct(IUserSession $userSession,
- IRequest $request,
- ITimeFactory $timeFactory,
+ public function __construct(ITimeFactory $timeFactory,
IBackend $backend) {
$this->backend = $backend;
$this->timeFactory = $timeFactory;
@@ -62,7 +56,7 @@ class Limiter {
private function register(string $methodIdentifier,
string $userIdentifier,
int $period,
- int $limit) {
+ int $limit): void {
$existingAttempts = $this->backend->getAttempts($methodIdentifier, $userIdentifier, $period);
if ($existingAttempts >= $limit) {
throw new RateLimitExceededException();
@@ -83,7 +77,7 @@ class Limiter {
public function registerAnonRequest(string $identifier,
int $anonLimit,
int $anonPeriod,
- string $ip) {
+ string $ip): void {
$ipSubnet = (new IpAddress($ip))->getSubnet();
$anonHashIdentifier = hash('sha512', 'anon::' . $identifier . $ipSubnet);
@@ -102,7 +96,7 @@ class Limiter {
public function registerUserRequest(string $identifier,
int $userLimit,
int $userPeriod,
- IUser $user) {
+ IUser $user): void {
$userHashIdentifier = hash('sha512', 'user::' . $identifier . $user->getUID());
$this->register($identifier, $userHashIdentifier, $userPeriod, $userLimit);
}
diff --git a/lib/private/Security/TrustedDomainHelper.php b/lib/private/Security/TrustedDomainHelper.php
index 5237767d8ea..22a75158294 100644
--- a/lib/private/Security/TrustedDomainHelper.php
+++ b/lib/private/Security/TrustedDomainHelper.php
@@ -90,7 +90,7 @@ class TrustedDomainHelper {
if (gettype($trusted) !== 'string') {
break;
}
- $regex = '/^' . implode('[-\.a-zA-Z0-9]*', array_map(function($v) { return preg_quote($v, '/'); }, explode('*', $trusted))) . '$/';
+ $regex = '/^' . implode('[-\.a-zA-Z0-9]*', array_map(function($v) { return preg_quote($v, '/'); }, explode('*', $trusted))) . '$/i';
if (preg_match($regex, $domain) || preg_match($regex, $domainWithPort)) {
return true;
}
diff --git a/lib/private/Server.php b/lib/private/Server.php
index f919e0b4efb..fa2a521b6b1 100644
--- a/lib/private/Server.php
+++ b/lib/private/Server.php
@@ -199,6 +199,8 @@ class Server extends ServerContainer implements IServerContainer {
$this->registerAlias(\OCP\Contacts\IManager::class, \OC\ContactsManager::class);
$this->registerAlias('ContactsManager', \OCP\Contacts\IManager::class);
+ $this->registerAlias(\OCP\DirectEditing\IManager::class, \OC\DirectEditing\Manager::class);
+
$this->registerAlias(IActionFactory::class, ActionFactory::class);
@@ -298,7 +300,7 @@ class Server extends ServerContainer implements IServerContainer {
$this->getLogger(),
$this->getUserManager()
);
- $connector = new HookConnector($root, $view);
+ $connector = new HookConnector($root, $view, $c->getEventDispatcher());
$connector->viewToNode();
$previewConnector = new \OC\Preview\WatcherConnector($root, $c->getSystemConfig());
@@ -315,9 +317,6 @@ class Server extends ServerContainer implements IServerContainer {
});
$this->registerAlias('LazyRootFolder', \OCP\Files\IRootFolder::class);
- $this->registerService(\OC\User\Manager::class, function (Server $c) {
- return new \OC\User\Manager($c->getConfig(), $c->getEventDispatcher());
- });
$this->registerAlias('UserManager', \OC\User\Manager::class);
$this->registerAlias(\OCP\IUserManager::class, \OC\User\Manager::class);
@@ -597,14 +596,6 @@ class Server extends ServerContainer implements IServerContainer {
});
$this->registerAlias('Search', \OCP\ISearch::class);
- $this->registerService(\OC\Security\RateLimiting\Limiter::class, function (Server $c) {
- return new \OC\Security\RateLimiting\Limiter(
- $this->getUserSession(),
- $this->getRequest(),
- new \OC\AppFramework\Utility\TimeFactory(),
- $c->query(\OC\Security\RateLimiting\Backend\IBackend::class)
- );
- });
$this->registerService(\OC\Security\RateLimiting\Backend\IBackend::class, function ($c) {
return new \OC\Security\RateLimiting\Backend\MemoryCache(
$this->getMemCacheFactory(),
@@ -1194,14 +1185,6 @@ class Server extends ServerContainer implements IServerContainer {
$this->registerAlias(IDashboardManager::class, DashboardManager::class);
$this->registerAlias(IFullTextSearchManager::class, FullTextSearchManager::class);
- $this->registerService(\OC\Security\IdentityProof\Manager::class, function (Server $c) {
- return new \OC\Security\IdentityProof\Manager(
- $c->query(\OC\Files\AppData\Factory::class),
- $c->getCrypto(),
- $c->getConfig()
- );
- });
-
$this->registerAlias(ISubAdmin::class, SubAdmin::class);
$this->registerAlias(IInitialStateService::class, InitialStateService::class);
diff --git a/lib/private/ServerContainer.php b/lib/private/ServerContainer.php
index b67b4d1e701..704d207223b 100644
--- a/lib/private/ServerContainer.php
+++ b/lib/private/ServerContainer.php
@@ -100,8 +100,9 @@ class ServerContainer extends SimpleContainer {
if (!isset($this->hasNoAppContainer[$namespace])) {
$applicationClassName = 'OCA\\' . $sensitiveNamespace . '\\AppInfo\\Application';
if (class_exists($applicationClassName)) {
- new $applicationClassName();
+ $app = new $applicationClassName();
if (isset($this->appContainers[$namespace])) {
+ $this->appContainers[$namespace]->offsetSet($applicationClassName, $app);
return $this->appContainers[$namespace];
}
}
diff --git a/lib/private/Settings/Manager.php b/lib/private/Settings/Manager.php
index 7e3edfa9df0..1205cb81525 100644
--- a/lib/private/Settings/Manager.php
+++ b/lib/private/Settings/Manager.php
@@ -30,15 +30,16 @@
namespace OC\Settings;
use Closure;
+use OC\Settings\Personal\PersonalInfo;
use OCP\AppFramework\QueryException;
use OCP\IL10N;
use OCP\ILogger;
use OCP\IServerContainer;
use OCP\IURLGenerator;
use OCP\L10N\IFactory;
-use OCP\Settings\ISettings;
use OCP\Settings\IManager;
use OCP\Settings\ISection;
+use OCP\Settings\ISettings;
use OCP\Settings\ISubAdminSettings;
class Manager implements IManager {
@@ -245,32 +246,32 @@ class Manager implements IManager {
if ($section === 'overview') {
/** @var ISettings $form */
- $form = $this->container->query(Admin\Overview::class);
+ $form = $this->container->query(\OCA\Settings\Admin\Overview::class);
if ($filter === null || $filter($form)) {
$forms[$form->getPriority()] = [$form];
}
}
if ($section === 'server') {
/** @var ISettings $form */
- $form = $this->container->query(Admin\Server::class);
+ $form = $this->container->query(\OCA\Settings\Admin\Server::class);
if ($filter === null || $filter($form)) {
$forms[$form->getPriority()] = [$form];
}
- $form = $this->container->query(Admin\Mail::class);
+ $form = $this->container->query(\OCA\Settings\Admin\Mail::class);
if ($filter === null || $filter($form)) {
$forms[$form->getPriority()] = [$form];
}
}
if ($section === 'security') {
/** @var ISettings $form */
- $form = $this->container->query(Admin\Security::class);
+ $form = $this->container->query(\OCA\Settings\Admin\Security::class);
if ($filter === null || $filter($form)) {
$forms[$form->getPriority()] = [$form];
}
}
if ($section === 'sharing') {
/** @var ISettings $form */
- $form = $this->container->query(Admin\Sharing::class);
+ $form = $this->container->query(\OCA\Settings\Admin\Sharing::class);
if ($filter === null || $filter($form)) {
$forms[$form->getPriority()] = [$form];
}
@@ -289,19 +290,23 @@ class Manager implements IManager {
if ($section === 'personal-info') {
/** @var ISettings $form */
- $form = $this->container->query(Personal\PersonalInfo::class);
+ $form = $this->container->query(\OCA\Settings\Personal\PersonalInfo::class);
$forms[$form->getPriority()] = [$form];
- $form = new Personal\ServerDevNotice();
+ $form = new \OCA\Settings\Personal\ServerDevNotice();
$forms[$form->getPriority()] = [$form];
}
if ($section === 'security') {
/** @var ISettings $form */
- $form = $this->container->query(Personal\Security::class);
+ $form = $this->container->query(\OCA\Settings\Personal\Security::class);
+ $forms[$form->getPriority()] = [$form];
+
+ /** @var ISettings $form */
+ $form = $this->container->query(\OCA\Settings\Personal\Security\Authtokens::class);
$forms[$form->getPriority()] = [$form];
}
if ($section === 'additional') {
/** @var ISettings $form */
- $form = $this->container->query(Personal\Additional::class);
+ $form = $this->container->query(\OCA\Settings\Personal\Additional::class);
$forms[$form->getPriority()] = [$form];
}
@@ -343,7 +348,7 @@ class Manager implements IManager {
}
$sections = [
- 0 => [new Section('personal-info', $this->l->t('Personal info'), 0, $this->url->imagePath('core', 'actions/info.svg'))],
+ 0 => [new Section('personal-info', $this->l->t('Personal info'), 0, $this->url->imagePath('core', 'actions/user.svg'))],
5 => [new Section('security', $this->l->t('Security'), 0, $this->url->imagePath('settings', 'password.svg'))],
15 => [new Section('sync-clients', $this->l->t('Mobile & desktop'), 0, $this->url->imagePath('core', 'clients/phone.svg'))],
];
diff --git a/lib/private/Setup.php b/lib/private/Setup.php
index e360319c5b6..32a85264f57 100644
--- a/lib/private/Setup.php
+++ b/lib/private/Setup.php
@@ -49,7 +49,9 @@ use OC\Authentication\Token\DefaultTokenCleanupJob;
use OC\Authentication\Token\DefaultTokenProvider;
use OC\Log\Rotate;
use OC\Preview\BackgroundCleanupJob;
+use OCP\AppFramework\Utility\ITimeFactory;
use OCP\Defaults;
+use OCP\IGroup;
use OCP\IL10N;
use OCP\ILogger;
use OCP\IUser;
@@ -80,14 +82,15 @@ class Setup {
* @param ISecureRandom $random
* @param Installer $installer
*/
- public function __construct(SystemConfig $config,
- IniGetWrapper $iniWrapper,
- IL10N $l10n,
- Defaults $defaults,
- ILogger $logger,
- ISecureRandom $random,
- Installer $installer
- ) {
+ public function __construct(
+ SystemConfig $config,
+ IniGetWrapper $iniWrapper,
+ IL10N $l10n,
+ Defaults $defaults,
+ ILogger $logger,
+ ISecureRandom $random,
+ Installer $installer
+ ) {
$this->config = $config;
$this->iniWrapper = $iniWrapper;
$this->l10n = $l10n;
@@ -100,13 +103,14 @@ class Setup {
static protected $dbSetupClasses = [
'mysql' => \OC\Setup\MySQL::class,
'pgsql' => \OC\Setup\PostgreSQL::class,
- 'oci' => \OC\Setup\OCI::class,
+ 'oci' => \OC\Setup\OCI::class,
'sqlite' => \OC\Setup\Sqlite::class,
'sqlite3' => \OC\Setup\Sqlite::class,
];
/**
* Wrapper around the "class_exists" PHP function to be able to mock it
+ *
* @param string $name
* @return bool
*/
@@ -116,6 +120,7 @@ class Setup {
/**
* Wrapper around the "is_callable" PHP function to be able to mock it
+ *
* @param string $name
* @return bool
*/
@@ -141,7 +146,7 @@ class Setup {
*/
public function getSupportedDatabases($allowAllDatabases = false) {
$availableDatabases = [
- 'sqlite' => [
+ 'sqlite' => [
'type' => 'pdo',
'call' => 'sqlite',
'name' => 'SQLite',
@@ -168,24 +173,24 @@ class Setup {
$configuredDatabases = $this->config->getValue('supportedDatabases',
['sqlite', 'mysql', 'pgsql']);
}
- if(!is_array($configuredDatabases)) {
+ if (!is_array($configuredDatabases)) {
throw new Exception('Supported databases are not properly configured.');
}
$supportedDatabases = array();
- foreach($configuredDatabases as $database) {
- if(array_key_exists($database, $availableDatabases)) {
+ foreach ($configuredDatabases as $database) {
+ if (array_key_exists($database, $availableDatabases)) {
$working = false;
$type = $availableDatabases[$database]['type'];
$call = $availableDatabases[$database]['call'];
if ($type === 'function') {
$working = $this->is_callable($call);
- } elseif($type === 'pdo') {
+ } elseif ($type === 'pdo') {
$working = in_array($call, $this->getAvailableDbDriversForPdo(), true);
}
- if($working) {
+ if ($working) {
$supportedDatabases[$database] = $availableDatabases[$database]['name'];
}
}
@@ -204,14 +209,14 @@ class Setup {
public function getSystemInfo($allowAllDatabases = false) {
$databases = $this->getSupportedDatabases($allowAllDatabases);
- $dataDir = $this->config->getValue('datadirectory', \OC::$SERVERROOT.'/data');
+ $dataDir = $this->config->getValue('datadirectory', \OC::$SERVERROOT . '/data');
$errors = [];
// Create data directory to test whether the .htaccess works
// Notice that this is not necessarily the same data directory as the one
// that will effectively be used.
- if(!file_exists($dataDir)) {
+ if (!file_exists($dataDir)) {
@mkdir($dataDir);
}
$htAccessWorking = true;
@@ -242,7 +247,7 @@ class Setup {
];
}
- if($this->iniWrapper->getString('open_basedir') !== '' && PHP_INT_SIZE === 4) {
+ if ($this->iniWrapper->getString('open_basedir') !== '' && PHP_INT_SIZE === 4) {
$errors[] = [
'error' => $this->l10n->t(
'It seems that this %s instance is running on a 32-bit PHP environment and the open_basedir has been configured in php.ini. ' .
@@ -275,14 +280,14 @@ class Setup {
$error = array();
$dbType = $options['dbtype'];
- if(empty($options['adminlogin'])) {
+ if (empty($options['adminlogin'])) {
$error[] = $l->t('Set an admin username.');
}
- if(empty($options['adminpass'])) {
+ if (empty($options['adminpass'])) {
$error[] = $l->t('Set an admin password.');
}
- if(empty($options['directory'])) {
- $options['directory'] = \OC::$SERVERROOT."/data";
+ if (empty($options['directory'])) {
+ $options['directory'] = \OC::$SERVERROOT . "/data";
}
if (!isset(self::$dbSetupClasses[$dbType])) {
@@ -310,8 +315,8 @@ class Setup {
$request = \OC::$server->getRequest();
//no errors, good
- if(isset($options['trusted_domains'])
- && is_array($options['trusted_domains'])) {
+ if (isset($options['trusted_domains'])
+ && is_array($options['trusted_domains'])) {
$trustedDomains = $options['trusted_domains'];
} else {
$trustedDomains = [$request->getInsecureServerHost()];
@@ -329,12 +334,12 @@ class Setup {
//write the config file
$newConfigValues = [
- 'passwordsalt' => $salt,
- 'secret' => $secret,
- 'trusted_domains' => $trustedDomains,
- 'datadirectory' => $dataDir,
- 'dbtype' => $dbType,
- 'version' => implode('.', \OCP\Util::getVersion()),
+ 'passwordsalt' => $salt,
+ 'secret' => $secret,
+ 'trusted_domains' => $trustedDomains,
+ 'datadirectory' => $dataDir,
+ 'dbtype' => $dbType,
+ 'version' => implode('.', \OCP\Util::getVersion()),
];
if ($this->config->getValue('overwrite.cli.url', null) === null) {
@@ -363,13 +368,13 @@ class Setup {
}
//create the user and group
- $user = null;
+ $user = null;
try {
$user = \OC::$server->getUserManager()->createUser($username, $password);
if (!$user) {
$error[] = "User <$username> could not be created.";
}
- } catch(Exception $exception) {
+ } catch (Exception $exception) {
$error[] = $exception->getMessage();
}
@@ -379,22 +384,25 @@ class Setup {
$config->setAppValue('core', 'lastupdatedat', microtime(true));
$config->setAppValue('core', 'vendor', $this->getVendor());
- $group =\OC::$server->getGroupManager()->createGroup('admin');
- $group->addUser($user);
+ $group = \OC::$server->getGroupManager()->createGroup('admin');
+ if ($group instanceof IGroup) {
+ $group->addUser($user);
+ }
// Install shipped apps and specified app bundles
Installer::installShippedApps();
$bundleFetcher = new BundleFetcher(\OC::$server->getL10N('lib'));
$defaultInstallationBundles = $bundleFetcher->getDefaultInstallationBundle();
- foreach($defaultInstallationBundles as $bundle) {
+ foreach ($defaultInstallationBundles as $bundle) {
try {
$this->installer->installAppBundle($bundle);
- } catch (Exception $e) {}
+ } catch (Exception $e) {
+ }
}
// create empty file in data dir, so we can later find
// out that this is indeed an ownCloud data directory
- file_put_contents($config->getSystemValue('datadirectory', \OC::$SERVERROOT.'/data').'/.ocdata', '');
+ file_put_contents($config->getSystemValue('datadirectory', \OC::$SERVERROOT . '/data') . '/.ocdata', '');
// Update .htaccess files
self::updateHtaccess();
@@ -414,6 +422,9 @@ class Setup {
$userSession->login($username, $password);
$userSession->createSessionToken($request, $userSession->getUser()->getUID(), $username, $password);
+ $session = $userSession->getSession();
+ $session->set('last-password-confirm', \OC::$server->query(ITimeFactory::class)->getTime());
+
// Set email for admin
if (!empty($options['adminemail'])) {
$config->setUserValue($user->getUID(), 'settings', 'email', $options['adminemail']);
@@ -434,7 +445,7 @@ class Setup {
* @return string Absolute path to htaccess
*/
private function pathToHtaccess() {
- return \OC::$SERVERROOT.'/.htaccess';
+ return \OC::$SERVERROOT . '/.htaccess';
}
/**
@@ -499,7 +510,7 @@ class Setup {
// Add rewrite rules if the RewriteBase is configured
$rewriteBase = $config->getValue('htaccess.RewriteBase', '');
- if($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]";
@@ -532,7 +543,7 @@ class Setup {
if ($content !== '') {
//suppress errors in case we don't have permissions for it
- return (bool) @file_put_contents($setupHelper->pathToHtaccess(), $htaccessContent.$content . "\n");
+ return (bool)@file_put_contents($setupHelper->pathToHtaccess(), $htaccessContent . $content . "\n");
}
return false;
@@ -582,6 +593,6 @@ class Setup {
// this should really be a JSON file
require \OC::$SERVERROOT . '/version.php';
/** @var string $vendor */
- return (string) $vendor;
+ return (string)$vendor;
}
}
diff --git a/lib/private/Setup/AbstractDatabase.php b/lib/private/Setup/AbstractDatabase.php
index 903f8b6e386..459848d1c79 100644
--- a/lib/private/Setup/AbstractDatabase.php
+++ b/lib/private/Setup/AbstractDatabase.php
@@ -26,6 +26,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
+
namespace OC\Setup;
use OC\DB\ConnectionFactory;
diff --git a/lib/private/Setup/MySQL.php b/lib/private/Setup/MySQL.php
index eb4fedefd4b..8a38f889c74 100644
--- a/lib/private/Setup/MySQL.php
+++ b/lib/private/Setup/MySQL.php
@@ -27,6 +27,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
+
namespace OC\Setup;
use OC\DB\MySqlTools;
@@ -100,9 +101,9 @@ class MySQL extends AbstractDatabase {
$password = $this->dbPassword;
// we need to create 2 accounts, one for global use and one for local user. if we don't specify the local one,
// the anonymous user would take precedence when there is one.
- $query = "CREATE USER '$name'@'localhost' IDENTIFIED BY '$password'";
+ $query = "CREATE USER '$name'@'localhost' IDENTIFIED WITH mysql_native_password BY '$password'";
$connection->executeUpdate($query);
- $query = "CREATE USER '$name'@'%' IDENTIFIED BY '$password'";
+ $query = "CREATE USER '$name'@'%' IDENTIFIED WITH mysql_native_password BY '$password'";
$connection->executeUpdate($query);
}
catch (\Exception $ex){
diff --git a/lib/private/Setup/PostgreSQL.php b/lib/private/Setup/PostgreSQL.php
index 6d1b5ca2927..020c2e555d9 100644
--- a/lib/private/Setup/PostgreSQL.php
+++ b/lib/private/Setup/PostgreSQL.php
@@ -24,6 +24,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
+
namespace OC\Setup;
use OC\DatabaseException;
diff --git a/lib/private/Share/Constants.php b/lib/private/Share/Constants.php
index 72dc5cd43be..a76208655a3 100644
--- a/lib/private/Share/Constants.php
+++ b/lib/private/Share/Constants.php
@@ -27,18 +27,47 @@
namespace OC\Share;
+use OCP\Share\IShare;
+
class Constants {
+ /**
+ * @deprecated 17.0.0 - use IShare::TYPE_USER instead
+ */
const SHARE_TYPE_USER = 0;
+ /**
+ * @deprecated 17.0.0 - use IShare::TYPE_GROUP instead
+ */
const SHARE_TYPE_GROUP = 1;
// const SHARE_TYPE_USERGROUP = 2; // Internal type used by DefaultShareProvider
+ /**
+ * @deprecated 17.0.0 - use IShare::TYPE_LINK instead
+ */
const SHARE_TYPE_LINK = 3;
+ /**
+ * @deprecated 17.0.0 - use IShare::TYPE_EMAIL instead
+ */
const SHARE_TYPE_EMAIL = 4;
const SHARE_TYPE_CONTACT = 5; // ToDo Check if it is still in use otherwise remove it
+ /**
+ * @deprecated 17.0.0 - use IShare::TYPE_REMOTE instead
+ */
const SHARE_TYPE_REMOTE = 6;
+ /**
+ * @deprecated 17.0.0 - use IShare::TYPE_CIRCLE instead
+ */
const SHARE_TYPE_CIRCLE = 7;
+ /**
+ * @deprecated 17.0.0 - use IShare::TYPE_GUEST instead
+ */
const SHARE_TYPE_GUEST = 8;
+ /**
+ * @deprecated 17.0.0 - use IShare::REMOTE_GROUP instead
+ */
const SHARE_TYPE_REMOTE_GROUP = 9;
+ /**
+ * @deprecated 17.0.0 - use IShare::TYPE_ROOM instead
+ */
const SHARE_TYPE_ROOM = 10;
// const SHARE_TYPE_USERROOM = 11; // Internal type used by RoomShareProvider
diff --git a/lib/private/Share/SearchResultSorter.php b/lib/private/Share/SearchResultSorter.php
index da63dd33b8e..8418a1e4119 100644
--- a/lib/private/Share/SearchResultSorter.php
+++ b/lib/private/Share/SearchResultSorter.php
@@ -21,6 +21,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
+
namespace OC\Share;
use OCP\ILogger;
@@ -73,4 +74,3 @@ class SearchResultSorter {
}
}
}
-
diff --git a/lib/private/Share/Share.php b/lib/private/Share/Share.php
index 86101707dbf..64d59334aad 100644
--- a/lib/private/Share/Share.php
+++ b/lib/private/Share/Share.php
@@ -84,9 +84,6 @@ class Share extends Constants {
'collectionOf' => $collectionOf,
'supportedFileExtensions' => $supportedFileExtensions
);
- if(count(self::$backendTypes) === 1) {
- Util::addScript('core', 'dist/share_backend');
- }
return true;
}
\OCP\Util::writeLog('OCP\Share',
diff --git a/lib/private/Share20/DefaultShareProvider.php b/lib/private/Share20/DefaultShareProvider.php
index aea50dfcdb6..152e5d55394 100644
--- a/lib/private/Share20/DefaultShareProvider.php
+++ b/lib/private/Share20/DefaultShareProvider.php
@@ -27,29 +27,30 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
+
namespace OC\Share20;
use OC\Files\Cache\Cache;
+use OC\Share20\Exception\BackendError;
+use OC\Share20\Exception\InvalidShare;
+use OC\Share20\Exception\ProviderException;
+use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\Defaults;
use OCP\Files\Folder;
+use OCP\Files\IRootFolder;
+use OCP\Files\Node;
+use OCP\IDBConnection;
+use OCP\IGroup;
+use OCP\IGroupManager;
use OCP\IL10N;
use OCP\IURLGenerator;
use OCP\IUser;
+use OCP\IUserManager;
use OCP\Mail\IMailer;
+use OCP\Share\Exceptions\ShareNotFound;
use OCP\Share\IShare;
use OCP\Share\IShareHelper;
use OCP\Share\IShareProvider;
-use OC\Share20\Exception\InvalidShare;
-use OC\Share20\Exception\ProviderException;
-use OCP\Share\Exceptions\ShareNotFound;
-use OC\Share20\Exception\BackendError;
-use OCP\DB\QueryBuilder\IQueryBuilder;
-use OCP\IGroup;
-use OCP\IGroupManager;
-use OCP\IUserManager;
-use OCP\Files\IRootFolder;
-use OCP\IDBConnection;
-use OCP\Files\Node;
/**
* Class DefaultShareProvider
@@ -142,9 +143,20 @@ class DefaultShareProvider implements IShareProvider {
if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
//Set the UID of the user we share with
$qb->setValue('share_with', $qb->createNamedParameter($share->getSharedWith()));
+ $qb->setValue('accepted', $qb->createNamedParameter(IShare::STATUS_PENDING));
+
+ //If an expiration date is set store it
+ if ($share->getExpirationDate() !== null) {
+ $qb->setValue('expiration', $qb->createNamedParameter($share->getExpirationDate(), 'datetime'));
+ }
} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
//Set the GID of the group we share with
$qb->setValue('share_with', $qb->createNamedParameter($share->getSharedWith()));
+
+ //If an expiration date is set store it
+ if ($share->getExpirationDate() !== null) {
+ $qb->setValue('expiration', $qb->createNamedParameter($share->getExpirationDate(), 'datetime'));
+ }
} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) {
//set label for public link
$qb->setValue('label', $qb->createNamedParameter($share->getLabel()));
@@ -252,6 +264,7 @@ class DefaultShareProvider implements IShareProvider {
->set('file_source', $qb->createNamedParameter($share->getNode()->getId()))
->set('expiration', $qb->createNamedParameter($share->getExpirationDate(), IQueryBuilder::PARAM_DATE))
->set('note', $qb->createNamedParameter($share->getNote()))
+ ->set('accepted', $qb->createNamedParameter($share->getStatus()))
->execute();
} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
$qb = $this->dbConn->getQueryBuilder();
@@ -319,6 +332,72 @@ class DefaultShareProvider implements IShareProvider {
}
/**
+ * Accept a share.
+ *
+ * @param IShare $share
+ * @param string $recipient
+ * @return IShare The share object
+ * @since 9.0.0
+ */
+ public function acceptShare(IShare $share, string $recipient): IShare {
+ if ($share->getShareType() === IShare::TYPE_GROUP) {
+ $group = $this->groupManager->get($share->getSharedWith());
+ $user = $this->userManager->get($recipient);
+
+ if (is_null($group)) {
+ throw new ProviderException('Group "' . $share->getSharedWith() . '" does not exist');
+ }
+
+ if (!$group->inGroup($user)) {
+ throw new ProviderException('Recipient not in receiving group');
+ }
+
+ // Try to fetch user specific share
+ $qb = $this->dbConn->getQueryBuilder();
+ $stmt = $qb->select('*')
+ ->from('share')
+ ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_USERGROUP)))
+ ->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($recipient)))
+ ->andWhere($qb->expr()->eq('parent', $qb->createNamedParameter($share->getId())))
+ ->andWhere($qb->expr()->orX(
+ $qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
+ $qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
+ ))
+ ->execute();
+
+ $data = $stmt->fetch();
+ $stmt->closeCursor();
+
+ /*
+ * Check if there already is a user specific group share.
+ * If there is update it (if required).
+ */
+ if ($data === false) {
+ $id = $this->createUserSpecificGroupShare($share, $recipient);
+ } else {
+ $id = $data['id'];
+ }
+
+ } else if ($share->getShareType() === IShare::TYPE_USER) {
+ if ($share->getSharedWith() !== $recipient) {
+ throw new ProviderException('Recipient does not match');
+ }
+
+ $id = $share->getId();
+ } else {
+ throw new ProviderException('Invalid shareType');
+ }
+
+ $qb = $this->dbConn->getQueryBuilder();
+ $qb->update('share')
+ ->set('accepted', $qb->createNamedParameter(IShare::STATUS_ACCEPTED))
+ ->where($qb->expr()->eq('id', $qb->createNamedParameter($id)))
+ ->execute();
+
+ return $share;
+ }
+
+ /**
* Get all children of this share
* FIXME: remove once https://github.com/owncloud/core/pull/21660 is in
*
@@ -382,13 +461,13 @@ class DefaultShareProvider implements IShareProvider {
* Unshare a share from the recipient. If this is a group share
* this means we need a special entry in the share db.
*
- * @param \OCP\Share\IShare $share
+ * @param IShare $share
* @param string $recipient UserId of recipient
* @throws BackendError
* @throws ProviderException
*/
- public function deleteFromSelf(\OCP\Share\IShare $share, $recipient) {
- if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
+ public function deleteFromSelf(IShare $share, $recipient) {
+ if ($share->getShareType() === IShare::TYPE_GROUP) {
$group = $this->groupManager->get($share->getSharedWith());
$user = $this->userManager->get($recipient);
@@ -421,37 +500,23 @@ class DefaultShareProvider implements IShareProvider {
* If there is update it (if required).
*/
if ($data === false) {
- $qb = $this->dbConn->getQueryBuilder();
-
- $type = $share->getNodeType();
-
- //Insert new share
- $qb->insert('share')
- ->values([
- 'share_type' => $qb->createNamedParameter(self::SHARE_TYPE_USERGROUP),
- 'share_with' => $qb->createNamedParameter($recipient),
- 'uid_owner' => $qb->createNamedParameter($share->getShareOwner()),
- 'uid_initiator' => $qb->createNamedParameter($share->getSharedBy()),
- 'parent' => $qb->createNamedParameter($share->getId()),
- 'item_type' => $qb->createNamedParameter($type),
- 'item_source' => $qb->createNamedParameter($share->getNodeId()),
- 'file_source' => $qb->createNamedParameter($share->getNodeId()),
- 'file_target' => $qb->createNamedParameter($share->getTarget()),
- 'permissions' => $qb->createNamedParameter(0),
- 'stime' => $qb->createNamedParameter($share->getShareTime()->getTimestamp()),
- ])->execute();
-
- } else if ($data['permissions'] !== 0) {
+ $id = $this->createUserSpecificGroupShare($share, $recipient);
+ $permissions = $share->getPermissions();
+ } else {
+ $permissions = $data['permissions'];
+ $id = $data['id'];
+ }
+ if ($permissions !== 0) {
// Update existing usergroup share
$qb = $this->dbConn->getQueryBuilder();
$qb->update('share')
->set('permissions', $qb->createNamedParameter(0))
- ->where($qb->expr()->eq('id', $qb->createNamedParameter($data['id'])))
+ ->where($qb->expr()->eq('id', $qb->createNamedParameter($id)))
->execute();
}
- } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
+ } else if ($share->getShareType() === IShare::TYPE_USER) {
if ($share->getSharedWith() !== $recipient) {
throw new ProviderException('Recipient does not match');
@@ -464,6 +529,28 @@ class DefaultShareProvider implements IShareProvider {
}
}
+ protected function createUserSpecificGroupShare(IShare $share, string $recipient): int {
+ $type = $share->getNodeType();
+
+ $qb = $this->dbConn->getQueryBuilder();
+ $qb->insert('share')
+ ->values([
+ 'share_type' => $qb->createNamedParameter(self::SHARE_TYPE_USERGROUP),
+ 'share_with' => $qb->createNamedParameter($recipient),
+ 'uid_owner' => $qb->createNamedParameter($share->getShareOwner()),
+ 'uid_initiator' => $qb->createNamedParameter($share->getSharedBy()),
+ 'parent' => $qb->createNamedParameter($share->getId()),
+ 'item_type' => $qb->createNamedParameter($type),
+ 'item_source' => $qb->createNamedParameter($share->getNodeId()),
+ 'file_source' => $qb->createNamedParameter($share->getNodeId()),
+ 'file_target' => $qb->createNamedParameter($share->getTarget()),
+ 'permissions' => $qb->createNamedParameter($share->getPermissions()),
+ 'stime' => $qb->createNamedParameter($share->getShareTime()->getTimestamp()),
+ ])->execute();
+
+ return $qb->getLastInsertId();
+ }
+
/**
* @inheritdoc
*
@@ -932,6 +1019,7 @@ class DefaultShareProvider implements IShareProvider {
->setTarget($data['file_target'])
->setNote($data['note'])
->setMailSend((bool)$data['mail_send'])
+ ->setStatus((int)$data['accepted'])
->setLabel($data['label']);
$shareTime = new \DateTime();
@@ -1020,6 +1108,7 @@ class DefaultShareProvider implements IShareProvider {
while($data = $stmt->fetch()) {
$shareMap[$data['parent']]->setPermissions((int)$data['permissions']);
+ $shareMap[$data['parent']]->setStatus((int)$data['accepted']);
$shareMap[$data['parent']]->setTarget($data['file_target']);
$shareMap[$data['parent']]->setParent($data['parent']);
}
@@ -1382,4 +1471,30 @@ class DefaultShareProvider implements IShareProvider {
}
}
+
+ public function getAllShares(): iterable {
+ $qb = $this->dbConn->getQueryBuilder();
+
+ $qb->select('*')
+ ->from('share')
+ ->where(
+ $qb->expr()->orX(
+ $qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share\IShare::TYPE_USER)),
+ $qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share\IShare::TYPE_GROUP)),
+ $qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share\IShare::TYPE_LINK))
+ )
+ );
+
+ $cursor = $qb->execute();
+ while($data = $cursor->fetch()) {
+ try {
+ $share = $this->createShare($data);
+ } catch (InvalidShare $e) {
+ continue;
+ }
+
+ yield $share;
+ }
+ $cursor->closeCursor();
+ }
}
diff --git a/lib/private/Share20/Exception/BackendError.php b/lib/private/Share20/Exception/BackendError.php
index 10dae34cc34..f270dd53147 100644
--- a/lib/private/Share20/Exception/BackendError.php
+++ b/lib/private/Share20/Exception/BackendError.php
@@ -19,6 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
+
namespace OC\Share20\Exception;
class BackendError extends \Exception {
diff --git a/lib/private/Share20/Exception/InvalidShare.php b/lib/private/Share20/Exception/InvalidShare.php
index 1e7337b0418..f4a88ebc188 100644
--- a/lib/private/Share20/Exception/InvalidShare.php
+++ b/lib/private/Share20/Exception/InvalidShare.php
@@ -19,6 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
+
namespace OC\Share20\Exception;
class InvalidShare extends \Exception {
diff --git a/lib/private/Share20/Exception/ProviderException.php b/lib/private/Share20/Exception/ProviderException.php
index f7ada6d48fd..89bd28a60eb 100644
--- a/lib/private/Share20/Exception/ProviderException.php
+++ b/lib/private/Share20/Exception/ProviderException.php
@@ -19,10 +19,10 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
+
namespace OC\Share20\Exception;
class ProviderException extends \Exception {
}
-
diff --git a/lib/private/Share20/Hooks.php b/lib/private/Share20/Hooks.php
index 4519b709a8c..4318fd57cf1 100644
--- a/lib/private/Share20/Hooks.php
+++ b/lib/private/Share20/Hooks.php
@@ -19,6 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
+
namespace OC\Share20;
class Hooks {
diff --git a/lib/private/Share20/LegacyHooks.php b/lib/private/Share20/LegacyHooks.php
index 4cc748aa418..4554ab64a14 100644
--- a/lib/private/Share20/LegacyHooks.php
+++ b/lib/private/Share20/LegacyHooks.php
@@ -26,10 +26,10 @@
namespace OC\Share20;
use OCP\Files\File;
+use OCP\Share;
use OCP\Share\IShare;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\EventDispatcher\GenericEvent;
-use OCP\Share;
class LegacyHooks {
diff --git a/lib/private/Share20/Manager.php b/lib/private/Share20/Manager.php
index 2a2c64cf383..db9c704871d 100644
--- a/lib/private/Share20/Manager.php
+++ b/lib/private/Share20/Manager.php
@@ -55,17 +55,18 @@ use OCP\IUser;
use OCP\IUserManager;
use OCP\L10N\IFactory;
use OCP\Mail\IMailer;
+use OCP\Security\Events\ValidatePasswordPolicyEvent;
use OCP\Security\IHasher;
use OCP\Security\ISecureRandom;
+use OCP\Share;
use OCP\Share\Exceptions\GenericShareException;
use OCP\Share\Exceptions\ShareNotFound;
use OCP\Share\IManager;
use OCP\Share\IProviderFactory;
use OCP\Share\IShare;
+use OCP\Share\IShareProvider;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\EventDispatcher\GenericEvent;
-use OCP\Share\IShareProvider;
-use OCP\Share;
/**
* This class is the communication hub for all sharing related operations.
@@ -191,8 +192,7 @@ class Manager implements IManager {
// Let others verify the password
try {
- $event = new GenericEvent($password);
- $this->eventDispatcher->dispatch('OCP\PasswordPolicy::validate', $event);
+ $this->eventDispatcher->dispatch(new ValidatePasswordPolicyEvent($password));
} catch (HintException $e) {
throw new \Exception($e->getHint());
}
@@ -302,6 +302,7 @@ class Manager implements IManager {
/* Check if this is an incoming share */
$incomingShares = $this->getSharedWith($share->getSharedBy(), Share::SHARE_TYPE_USER, $userMountPoint, -1, 0);
$incomingShares = array_merge($incomingShares, $this->getSharedWith($share->getSharedBy(), Share::SHARE_TYPE_GROUP, $userMountPoint, -1, 0));
+ $incomingShares = array_merge($incomingShares, $this->getSharedWith($share->getSharedBy(), Share::SHARE_TYPE_CIRCLE, $userMountPoint, -1, 0));
$incomingShares = array_merge($incomingShares, $this->getSharedWith($share->getSharedBy(), Share::SHARE_TYPE_ROOM, $userMountPoint, -1, 0));
/** @var \OCP\Share\IShare[] $incomingShares */
@@ -359,6 +360,77 @@ class Manager implements IManager {
* @throws \InvalidArgumentException
* @throws \Exception
*/
+ protected function validateExpirationDateInternal(\OCP\Share\IShare $share) {
+ $expirationDate = $share->getExpirationDate();
+
+ if ($expirationDate !== null) {
+ //Make sure the expiration date is a date
+ $expirationDate->setTime(0, 0, 0);
+
+ $date = new \DateTime();
+ $date->setTime(0, 0, 0);
+ if ($date >= $expirationDate) {
+ $message = $this->l->t('Expiration date is in the past');
+ throw new GenericShareException($message, $message, 404);
+ }
+ }
+
+ // If expiredate is empty set a default one if there is a default
+ $fullId = null;
+ try {
+ $fullId = $share->getFullId();
+ } catch (\UnexpectedValueException $e) {
+ // This is a new share
+ }
+
+ if ($fullId === null && $expirationDate === null && $this->shareApiInternalDefaultExpireDate()) {
+ $expirationDate = new \DateTime();
+ $expirationDate->setTime(0,0,0);
+ $expirationDate->add(new \DateInterval('P'.$this->shareApiInternalDefaultExpireDays().'D'));
+ }
+
+ // If we enforce the expiration date check that is does not exceed
+ if ($this->shareApiInternalDefaultExpireDateEnforced()) {
+ if ($expirationDate === null) {
+ throw new \InvalidArgumentException('Expiration date is enforced');
+ }
+
+ $date = new \DateTime();
+ $date->setTime(0, 0, 0);
+ $date->add(new \DateInterval('P' . $this->shareApiInternalDefaultExpireDays() . 'D'));
+ if ($date < $expirationDate) {
+ $message = $this->l->t('Can’t set expiration date more than %s days in the future', [$this->shareApiInternalDefaultExpireDays()]);
+ throw new GenericShareException($message, $message, 404);
+ }
+ }
+
+ $accepted = true;
+ $message = '';
+ \OCP\Util::emitHook('\OC\Share', 'verifyExpirationDate', [
+ 'expirationDate' => &$expirationDate,
+ 'accepted' => &$accepted,
+ 'message' => &$message,
+ 'passwordSet' => $share->getPassword() !== null,
+ ]);
+
+ if (!$accepted) {
+ throw new \Exception($message);
+ }
+
+ $share->setExpirationDate($expirationDate);
+
+ return $share;
+ }
+
+ /**
+ * Validate if the expiration date fits the system settings
+ *
+ * @param \OCP\Share\IShare $share The share to validate the expiration date of
+ * @return \OCP\Share\IShare The modified share object
+ * @throws GenericShareException
+ * @throws \InvalidArgumentException
+ * @throws \Exception
+ */
protected function validateExpirationDate(\OCP\Share\IShare $share) {
$expirationDate = $share->getExpirationDate();
@@ -635,8 +707,16 @@ class Manager implements IManager {
//Verify share type
if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
$this->userCreateChecks($share);
+
+ //Verify the expiration date
+ $share = $this->validateExpirationDateInternal($share);
+
} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
$this->groupCreateChecks($share);
+
+ //Verify the expiration date
+ $share = $this->validateExpirationDateInternal($share);
+
} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) {
$this->linkCreateChecks($share);
$this->setLinkParent($share);
@@ -652,7 +732,7 @@ class Manager implements IManager {
);
//Verify the expiration date
- $this->validateExpirationDate($share);
+ $share = $this->validateExpirationDate($share);
//Verify the password
$this->verifyPassword($share->getPassword());
@@ -849,8 +929,20 @@ class Manager implements IManager {
if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
$this->userCreateChecks($share);
+
+ if ($share->getExpirationDate() != $originalShare->getExpirationDate()) {
+ //Verify the expiration date
+ $this->validateExpirationDate($share);
+ $expirationDateUpdated = true;
+ }
} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
$this->groupCreateChecks($share);
+
+ if ($share->getExpirationDate() != $originalShare->getExpirationDate()) {
+ //Verify the expiration date
+ $this->validateExpirationDate($share);
+ $expirationDateUpdated = true;
+ }
} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) {
$this->linkCreateChecks($share);
@@ -928,6 +1020,30 @@ class Manager implements IManager {
}
/**
+ * Accept a share.
+ *
+ * @param IShare $share
+ * @param string $recipientId
+ * @return IShare The share object
+ * @throws \InvalidArgumentException
+ * @since 9.0.0
+ */
+ public function acceptShare(IShare $share, string $recipientId): IShare {
+ [$providerId, ] = $this->splitFullId($share->getFullId());
+ $provider = $this->factory->getProvider($providerId);
+
+ if (!method_exists($provider, 'acceptShare')) {
+ // TODO FIX ME
+ throw new \InvalidArgumentException('Share provider does not support accepting');
+ }
+ $provider->acceptShare($share, $recipientId);
+ $event = new GenericEvent($share);
+ $this->eventDispatcher->dispatch('OCP\Share::postAcceptShare', $event);
+
+ return $share;
+ }
+
+ /**
* Updates the password of the given share if it is not the same as the
* password of the original share.
*
@@ -1313,8 +1429,7 @@ class Manager implements IManager {
}
protected function checkExpireDate($share) {
- if ($share->getExpirationDate() !== null &&
- $share->getExpirationDate() <= new \DateTime()) {
+ if ($share->isExpired()) {
$this->deleteShare($share);
throw new ShareNotFound($this->l->t('The requested share does not exist anymore'));
}
@@ -1551,7 +1666,7 @@ class Manager implements IManager {
}
/**
- * Is default expire date enabled
+ * Is default link expire date enabled
*
* @return bool
*/
@@ -1560,7 +1675,7 @@ class Manager implements IManager {
}
/**
- * Is default expire date enforced
+ * Is default link expire date enforced
*`
* @return bool
*/
@@ -1569,9 +1684,9 @@ class Manager implements IManager {
$this->config->getAppValue('core', 'shareapi_enforce_expire_date', 'no') === 'yes';
}
+
/**
- * Number of default expire days
- *shareApiLinkAllowPublicUpload
+ * Number of default link expire days
* @return int
*/
public function shareApiLinkDefaultExpireDays() {
@@ -1579,6 +1694,34 @@ class Manager implements IManager {
}
/**
+ * Is default internal expire date enabled
+ *
+ * @return bool
+ */
+ public function shareApiInternalDefaultExpireDate(): bool {
+ return $this->config->getAppValue('core', 'shareapi_default_internal_expire_date', 'no') === 'yes';
+ }
+
+ /**
+ * Is default expire date enforced
+ *`
+ * @return bool
+ */
+ public function shareApiInternalDefaultExpireDateEnforced(): bool {
+ return $this->shareApiInternalDefaultExpireDate() &&
+ $this->config->getAppValue('core', 'shareapi_enforce_internal_expire_date', 'no') === 'yes';
+ }
+
+
+ /**
+ * Number of default expire days
+ * @return int
+ */
+ public function shareApiInternalDefaultExpireDays(): int {
+ return (int)$this->config->getAppValue('core', 'shareapi_internal_expire_after_n_days', '7');
+ }
+
+ /**
* Allow public upload on link shares
*
* @return bool
@@ -1672,4 +1815,11 @@ class Manager implements IManager {
return true;
}
+ public function getAllShares(): iterable {
+ $providers = $this->factory->getAllProviders();
+
+ foreach ($providers as $provider) {
+ yield from $provider->getAllShares();
+ }
+ }
}
diff --git a/lib/private/Share20/ProviderFactory.php b/lib/private/Share20/ProviderFactory.php
index 6cb6c082df5..dc77a9fbcbb 100644
--- a/lib/private/Share20/ProviderFactory.php
+++ b/lib/private/Share20/ProviderFactory.php
@@ -26,9 +26,11 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
+
namespace OC\Share20;
use OC\CapabilitiesManager;
+use OC\Share20\Exception\ProviderException;
use OCA\FederatedFileSharing\AddressHandler;
use OCA\FederatedFileSharing\FederatedShareProvider;
use OCA\FederatedFileSharing\Notifications;
@@ -37,9 +39,8 @@ use OCA\FederatedFileSharing\TokenHandler;
use OCA\ShareByMail\Settings\SettingsManager;
use OCA\ShareByMail\ShareByMailProvider;
use OCP\Defaults;
-use OCP\Share\IProviderFactory;
-use OC\Share20\Exception\ProviderException;
use OCP\IServerContainer;
+use OCP\Share\IProviderFactory;
/**
* Class ProviderFactory
@@ -60,7 +61,7 @@ class ProviderFactory implements IProviderFactory {
private $shareByCircleProvider = null;
/** @var bool */
private $circlesAreNotAvailable = false;
- /** @var \OCA\Spreed\Share\RoomShareProvider */
+ /** @var \OCA\Talk\Share\RoomShareProvider */
private $roomShareProvider = null;
/**
@@ -112,7 +113,7 @@ class ProviderFactory implements IProviderFactory {
/*
* TODO: add factory to federated sharing app
*/
- $l = $this->serverContainer->getL10N('federatedfilessharing');
+ $l = $this->serverContainer->getL10N('federatedfilesharing');
$addressHandler = new AddressHandler(
$this->serverContainer->getURLGenerator(),
$l,
@@ -239,7 +240,7 @@ class ProviderFactory implements IProviderFactory {
}
try {
- $this->roomShareProvider = $this->serverContainer->query('\OCA\Spreed\Share\RoomShareProvider');
+ $this->roomShareProvider = $this->serverContainer->query('\OCA\Talk\Share\RoomShareProvider');
} catch (\OCP\AppFramework\QueryException $e) {
return null;
}
diff --git a/lib/private/Share20/Share.php b/lib/private/Share20/Share.php
index f9b548c1adf..3ac324b40ce 100644
--- a/lib/private/Share20/Share.php
+++ b/lib/private/Share20/Share.php
@@ -21,6 +21,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
+
namespace OC\Share20;
use OCP\Files\Cache\ICacheEntry;
@@ -58,6 +59,8 @@ class Share implements \OCP\Share\IShare {
private $shareOwner;
/** @var int */
private $permissions;
+ /** @var int */
+ private $status;
/** @var string */
private $note = '';
/** @var \DateTime */
@@ -321,6 +324,21 @@ class Share implements \OCP\Share\IShare {
/**
* @inheritdoc
*/
+ public function setStatus(int $status): IShare {
+ $this->status = $status;
+ return $this;
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function getStatus(): int {
+ return $this->status;
+ }
+
+ /**
+ * @inheritdoc
+ */
public function setNote($note) {
$this->note = $note;
return $this;
@@ -371,6 +389,14 @@ class Share implements \OCP\Share\IShare {
/**
* @inheritdoc
*/
+ public function isExpired() {
+ return $this->getExpirationDate() !== null &&
+ $this->getExpirationDate() <= new \DateTime();
+ }
+
+ /**
+ * @inheritdoc
+ */
public function setSharedBy($sharedBy) {
if (!is_string($sharedBy)) {
throw new \InvalidArgumentException();
diff --git a/lib/private/Share20/ShareHelper.php b/lib/private/Share20/ShareHelper.php
index 5f692c6a62b..f94546d19ed 100644
--- a/lib/private/Share20/ShareHelper.php
+++ b/lib/private/Share20/ShareHelper.php
@@ -21,6 +21,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
+
namespace OC\Share20;
use OCP\Files\InvalidPathException;
diff --git a/lib/private/SubAdmin.php b/lib/private/SubAdmin.php
index f79a0b1ae5a..ec959e0e4ea 100644
--- a/lib/private/SubAdmin.php
+++ b/lib/private/SubAdmin.php
@@ -30,11 +30,11 @@ namespace OC;
use OC\Hooks\PublicEmitter;
use OCP\Group\ISubAdmin;
-use OCP\IUser;
-use OCP\IUserManager;
+use OCP\IDBConnection;
use OCP\IGroup;
use OCP\IGroupManager;
-use OCP\IDBConnection;
+use OCP\IUser;
+use OCP\IUserManager;
class SubAdmin extends PublicEmitter implements ISubAdmin {
diff --git a/lib/private/SystemConfig.php b/lib/private/SystemConfig.php
index 444e5842437..64cc805f9f3 100644
--- a/lib/private/SystemConfig.php
+++ b/lib/private/SystemConfig.php
@@ -64,13 +64,24 @@ class SystemConfig {
],
'objectstore' => [
'arguments' => [
- 'password' => true,
+ // Legacy Swift (https://github.com/nextcloud/server/pull/17696#discussion_r341302207)
'options' => [
'credentials' => [
'key' => true,
'secret' => true,
]
- ]
+ ],
+ // S3
+ 'key' => true,
+ 'secret' => true,
+ // Swift v2
+ 'username' => true,
+ 'password' => true,
+ // Swift v3
+ 'user' => [
+ 'name' => true,
+ 'password' => true,
+ ],
],
],
];
diff --git a/lib/private/SystemTag/ManagerFactory.php b/lib/private/SystemTag/ManagerFactory.php
index 839a819a04a..ab17ae69ac8 100644
--- a/lib/private/SystemTag/ManagerFactory.php
+++ b/lib/private/SystemTag/ManagerFactory.php
@@ -21,6 +21,7 @@ declare(strict_types=1);
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
+
namespace OC\SystemTag;
use OCP\IServerContainer;
diff --git a/lib/private/SystemTag/SystemTagManager.php b/lib/private/SystemTag/SystemTagManager.php
index 055b744e5c3..85a12da67f2 100644
--- a/lib/private/SystemTag/SystemTagManager.php
+++ b/lib/private/SystemTag/SystemTagManager.php
@@ -29,14 +29,14 @@ namespace OC\SystemTag;
use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\IDBConnection;
+use OCP\IGroupManager;
+use OCP\IUser;
+use OCP\SystemTag\ISystemTag;
use OCP\SystemTag\ISystemTagManager;
use OCP\SystemTag\ManagerEvent;
use OCP\SystemTag\TagAlreadyExistsException;
use OCP\SystemTag\TagNotFoundException;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
-use OCP\IGroupManager;
-use OCP\SystemTag\ISystemTag;
-use OCP\IUser;
/**
* Manager class for system tags
diff --git a/lib/private/SystemTag/SystemTagObjectMapper.php b/lib/private/SystemTag/SystemTagObjectMapper.php
index f8a1b03cd01..f1f39fd7d0a 100644
--- a/lib/private/SystemTag/SystemTagObjectMapper.php
+++ b/lib/private/SystemTag/SystemTagObjectMapper.php
@@ -154,20 +154,26 @@ class SystemTagObjectMapper implements ISystemTagObjectMapper {
'systemtagid' => $query->createParameter('tagid'),
]);
+ $tagsAssigned = [];
foreach ($tagIds as $tagId) {
try {
$query->setParameter('tagid', $tagId);
$query->execute();
+ $tagsAssigned[] = $tagId;
} catch (UniqueConstraintViolationException $e) {
// ignore existing relations
}
}
+ if (empty($tagsAssigned)) {
+ return;
+ }
+
$this->dispatcher->dispatch(MapperEvent::EVENT_ASSIGN, new MapperEvent(
MapperEvent::EVENT_ASSIGN,
$objectType,
$objId,
- $tagIds
+ $tagsAssigned
));
}
diff --git a/lib/private/Tagging/Tag.php b/lib/private/Tagging/Tag.php
index de5ab0a485c..f20f22955a3 100644
--- a/lib/private/Tagging/Tag.php
+++ b/lib/private/Tagging/Tag.php
@@ -23,7 +23,7 @@
namespace OC\Tagging;
-use \OCP\AppFramework\Db\Entity;
+use OCP\AppFramework\Db\Entity;
/**
* Class to represent a tag.
diff --git a/lib/private/Tagging/TagMapper.php b/lib/private/Tagging/TagMapper.php
index e5ca41f69e3..49361ff181a 100644
--- a/lib/private/Tagging/TagMapper.php
+++ b/lib/private/Tagging/TagMapper.php
@@ -24,9 +24,9 @@
namespace OC\Tagging;
-use \OCP\AppFramework\Db\Mapper,
- \OCP\AppFramework\Db\DoesNotExistException,
- \OCP\IDBConnection;
+use OCP\AppFramework\Db\DoesNotExistException;
+use OCP\AppFramework\Db\Mapper;
+use OCP\IDBConnection;
/**
* Mapper for Tag entity
@@ -76,4 +76,3 @@ class TagMapper extends Mapper {
return true;
}
}
-
diff --git a/lib/private/TempManager.php b/lib/private/TempManager.php
index 6e8683d2f7c..479c41ff7fd 100644
--- a/lib/private/TempManager.php
+++ b/lib/private/TempManager.php
@@ -30,8 +30,8 @@
namespace OC;
-use OCP\ILogger;
use OCP\IConfig;
+use OCP\ILogger;
use OCP\ITempManager;
class TempManager implements ITempManager {
diff --git a/lib/private/Template/IconsCacher.php b/lib/private/Template/IconsCacher.php
index 3c0a270d3f2..75175ad6373 100644
--- a/lib/private/Template/IconsCacher.php
+++ b/lib/private/Template/IconsCacher.php
@@ -24,14 +24,14 @@ declare (strict_types = 1);
namespace OC\Template;
+use OC\Files\AppData\Factory;
use OCP\AppFramework\Utility\ITimeFactory;
use OCP\Files\IAppData;
use OCP\Files\NotFoundException;
-use OCP\Files\SimpleFS\ISimpleFolder;
use OCP\Files\SimpleFS\ISimpleFile;
+use OCP\Files\SimpleFS\ISimpleFolder;
use OCP\ILogger;
use OCP\IURLGenerator;
-use OC\Files\AppData\Factory;
class IconsCacher {
diff --git a/lib/private/Template/JSCombiner.php b/lib/private/Template/JSCombiner.php
index 93683753899..224a7a9b213 100644
--- a/lib/private/Template/JSCombiner.php
+++ b/lib/private/Template/JSCombiner.php
@@ -22,14 +22,15 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
+
namespace OC\Template;
use OC\SystemConfig;
-use OCP\ICache;
use OCP\Files\IAppData;
use OCP\Files\NotFoundException;
use OCP\Files\NotPermittedException;
use OCP\Files\SimpleFS\ISimpleFolder;
+use OCP\ICache;
use OCP\ICacheFactory;
use OCP\ILogger;
use OCP\IURLGenerator;
diff --git a/lib/private/Template/JSConfigHelper.php b/lib/private/Template/JSConfigHelper.php
index 15e2fd76c48..065bf2545e0 100644
--- a/lib/private/Template/JSConfigHelper.php
+++ b/lib/private/Template/JSConfigHelper.php
@@ -25,6 +25,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
+
namespace OC\Template;
use bantu\IniGetWrapper\IniGetWrapper;
@@ -148,6 +149,13 @@ class JSConfigHelper {
}
$outgoingServer2serverShareEnabled = $this->config->getAppValue('files_sharing', 'outgoing_server2server_share_enabled', 'yes') === 'yes';
+ $defaultInternalExpireDateEnabled = $this->config->getAppValue('core', 'shareapi_default_internal_expire_date', 'no') === 'yes';
+ $defaultInternalExpireDate = $defaultInternalExpireDateEnforced = null;
+ if ($defaultInternalExpireDateEnabled) {
+ $defaultInternalExpireDate = (int) $this->config->getAppValue('core', 'shareapi_internal_expire_after_n_days', '7');
+ $defaultInternalExpireDateEnforced = $this->config->getAppValue('core', 'shareapi_internal_enforce_expire_date', 'no') === 'yes';
+ }
+
$countOfDataLocation = 0;
$dataLocation = str_replace(\OC::$SERVERROOT .'/', '', $this->config->getSystemValue('datadirectory', ''), $countOfDataLocation);
if($countOfDataLocation !== 1 || !$this->groupManager->isAdmin($uid)) {
@@ -254,7 +262,10 @@ class JSConfigHelper {
'resharingAllowed' => \OC\Share\Share::isResharingAllowed(),
'remoteShareAllowed' => $outgoingServer2serverShareEnabled,
'federatedCloudShareDoc' => $this->urlGenerator->linkToDocs('user-sharing-federated'),
- 'allowGroupSharing' => \OC::$server->getShareManager()->allowGroupSharing()
+ 'allowGroupSharing' => \OC::$server->getShareManager()->allowGroupSharing(),
+ 'defaultInternalExpireDateEnabled' => $defaultInternalExpireDateEnabled,
+ 'defaultInternalExpireDate' => $defaultInternalExpireDate,
+ 'defaultInternalExpireDateEnforced' => $defaultInternalExpireDateEnforced,
]
]),
"_theme" => json_encode([
diff --git a/lib/private/Template/SCSSCacher.php b/lib/private/Template/SCSSCacher.php
index 9bdaca3a674..df90fca9817 100644
--- a/lib/private/Template/SCSSCacher.php
+++ b/lib/private/Template/SCSSCacher.php
@@ -32,7 +32,9 @@ use Leafo\ScssPhp\Compiler;
use Leafo\ScssPhp\Exception\ParserException;
use Leafo\ScssPhp\Formatter\Crunched;
use Leafo\ScssPhp\Formatter\Expanded;
+use OC\Files\AppData\Factory;
use OC\Memcache\NullCache;
+use OC\Template\IconsCacher;
use OCP\AppFramework\Utility\ITimeFactory;
use OCP\Files\IAppData;
use OCP\Files\NotFoundException;
@@ -45,8 +47,6 @@ use OCP\IConfig;
use OCP\ILogger;
use OCP\IMemcache;
use OCP\IURLGenerator;
-use OC\Files\AppData\Factory;
-use OC\Template\IconsCacher;
class SCSSCacher {
@@ -117,7 +117,7 @@ class SCSSCacher {
$this->serverRoot = $serverRoot;
$this->cacheFactory = $cacheFactory;
$this->depsCache = $cacheFactory->createDistributed('SCSS-deps-' . md5($this->urlGenerator->getBaseUrl()));
- $this->isCachedCache = $cacheFactory->createLocal('SCSS-cached-' . md5($this->urlGenerator->getBaseUrl()));
+ $this->isCachedCache = $cacheFactory->createDistributed('SCSS-cached-' . md5($this->urlGenerator->getBaseUrl()));
$lockingCache = $cacheFactory->createDistributed('SCSS-locks-' . md5($this->urlGenerator->getBaseUrl()));
if (!($lockingCache instanceof IMemcache)) {
$lockingCache = new NullCache();
@@ -269,8 +269,8 @@ class SCSSCacher {
private function variablesChanged(): bool {
$injectedVariables = $this->getInjectedVariables();
if ($this->config->getAppValue('core', 'theming.variables') !== md5($injectedVariables)) {
- $this->resetCache();
$this->config->setAppValue('core', 'theming.variables', md5($injectedVariables));
+ $this->resetCache();
return true;
}
return false;
@@ -364,6 +364,9 @@ class SCSSCacher {
* We need to regenerate all files when variables change
*/
public function resetCache() {
+ if (!$this->lockingCache->add('resetCache', 'locked!', 120)) {
+ return;
+ }
$this->injectedVariables = null;
// do not clear locks
@@ -381,6 +384,7 @@ class SCSSCacher {
}
}
$this->logger->debug('SCSSCacher: css cache cleared!');
+ $this->lockingCache->remove('resetCache');
}
/**
diff --git a/lib/private/TemplateLayout.php b/lib/private/TemplateLayout.php
index f23ec97119f..e476ddd275d 100644
--- a/lib/private/TemplateLayout.php
+++ b/lib/private/TemplateLayout.php
@@ -36,13 +36,15 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
+
namespace OC;
+use OC\AppFramework\Http\Request;
use OC\Template\JSCombiner;
use OC\Template\JSConfigHelper;
use OC\Template\SCSSCacher;
use OCP\Defaults;
-use OC\AppFramework\Http\Request;
+use OCP\Support\Subscription\IRegistry;
class TemplateLayout extends \OC_Template {
@@ -113,6 +115,8 @@ class TemplateLayout extends \OC_Template {
$this->assign('themingInvertMenu', $util->invertTextColor(\OC::$server->getThemingDefaults()->getColorPrimary()));
} catch (\OCP\AppFramework\QueryException $e) {
$this->assign('themingInvertMenu', false);
+ } catch (\OCP\AutoloadNotAllowedException $e) {
+ $this->assign('themingInvertMenu', false);
}
} else if ($renderAs === 'error') {
@@ -132,7 +136,14 @@ class TemplateLayout extends \OC_Template {
parent::__construct('core', 'layout.public');
$this->assign( 'appid', $appId );
$this->assign('bodyid', 'body-public');
- $this->assign('showSimpleSignUpLink', $this->config->getSystemValue('simpleSignUpLink.shown', true) !== false);
+
+ /** @var IRegistry $subscription */
+ $subscription = \OC::$server->query(IRegistry::class);
+ $showSimpleSignup = $this->config->getSystemValueBool('simpleSignUpLink.shown', true);
+ if ($showSimpleSignup && $subscription->delegateHasValidSubscription()) {
+ $showSimpleSignup = false;
+ }
+ $this->assign('showSimpleSignUpLink', $showSimpleSignup);
} else {
parent::__construct('core', 'layout.base');
@@ -140,7 +151,6 @@ class TemplateLayout extends \OC_Template {
// Send the language and the locale to our layouts
$lang = \OC::$server->getL10NFactory()->findLanguage();
$locale = \OC::$server->getL10NFactory()->findLocale($lang);
- $localeLang = \OC::$server->getL10NFactory()->findLanguageFromLocale('lib', $locale);
$lang = str_replace('_', '-', $lang);
$this->assign('language', $lang);
@@ -162,7 +172,7 @@ class TemplateLayout extends \OC_Template {
if ($this->config->getSystemValue('installed', false) && $renderAs != 'error') {
if (\OC::$server->getContentSecurityPolicyNonceManager()->browserSupportsCspV3()) {
$jsConfigHelper = new JSConfigHelper(
- \OC::$server->getL10N('lib', $localeLang ?: $lang),
+ \OC::$server->getL10N('lib'),
\OC::$server->query(Defaults::class),
\OC::$server->getAppManager(),
\OC::$server->getSession(),
diff --git a/lib/private/URLGenerator.php b/lib/private/URLGenerator.php
index 167690f3a6e..1fb69031f03 100644
--- a/lib/private/URLGenerator.php
+++ b/lib/private/URLGenerator.php
@@ -94,8 +94,9 @@ class URLGenerator implements IURLGenerator {
public function linkToOCSRouteAbsolute(string $routeName, array $arguments = []): string {
$route = \OC::$server->getRouter()->generate('ocs.'.$routeName, $arguments, false);
- if (strpos($route, '/index.php') === 0) {
- $route = substr($route, 10);
+ $indexPhpPos = strpos($route, '/index.php/');
+ if ($indexPhpPos !== false) {
+ $route = substr($route, $indexPhpPos + 10);
}
$route = substr($route, 7);
diff --git a/lib/private/Updater/VersionCheck.php b/lib/private/Updater/VersionCheck.php
index 3cbd7061fe0..079ffe7ff44 100644
--- a/lib/private/Updater/VersionCheck.php
+++ b/lib/private/Updater/VersionCheck.php
@@ -33,7 +33,7 @@ class VersionCheck {
/** @var IClientService */
private $clientService;
-
+
/** @var IConfig */
private $config;
@@ -54,6 +54,11 @@ class VersionCheck {
* @return array|bool
*/
public function check() {
+ // If this server is set to have no internet connection this is all not needed
+ if (!$this->config->getSystemValueBool('has_internet_connection', true)) {
+ return false;
+ }
+
// 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);
@@ -122,4 +127,3 @@ class VersionCheck {
return $response->getBody();
}
}
-
diff --git a/lib/private/User/Backend.php b/lib/private/User/Backend.php
index 30ed962555d..2b9b4d27ea3 100644
--- a/lib/private/User/Backend.php
+++ b/lib/private/User/Backend.php
@@ -23,7 +23,7 @@
namespace OC\User;
-use \OCP\UserInterface;
+use OCP\UserInterface;
/**
* Abstract base class for user management. Provides methods for querying backend
diff --git a/lib/private/User/Database.php b/lib/private/User/Database.php
index 3db96fa02e2..a4c35deb2b8 100644
--- a/lib/private/User/Database.php
+++ b/lib/private/User/Database.php
@@ -58,7 +58,9 @@ declare(strict_types=1);
namespace OC\User;
use OC\Cache\CappedMemoryCache;
+use OCP\EventDispatcher\IEventDispatcher;
use OCP\IDBConnection;
+use OCP\Security\Events\ValidatePasswordPolicyEvent;
use OCP\User\Backend\ABackend;
use OCP\User\Backend\ICheckPasswordBackend;
use OCP\User\Backend\ICountUsersBackend;
@@ -68,7 +70,6 @@ use OCP\User\Backend\IGetHomeBackend;
use OCP\User\Backend\IGetRealUIDBackend;
use OCP\User\Backend\ISetDisplayNameBackend;
use OCP\User\Backend\ISetPasswordBackend;
-use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\EventDispatcher\GenericEvent;
/**
@@ -86,7 +87,7 @@ class Database extends ABackend
/** @var CappedMemoryCache */
private $cache;
- /** @var EventDispatcherInterface */
+ /** @var IEventDispatcher */
private $eventDispatcher;
/** @var IDBConnection */
@@ -98,13 +99,13 @@ class Database extends ABackend
/**
* \OC\User\Database constructor.
*
- * @param EventDispatcherInterface $eventDispatcher
+ * @param IEventDispatcher $eventDispatcher
* @param string $table
*/
public function __construct($eventDispatcher = null, $table = 'users') {
$this->cache = new CappedMemoryCache();
$this->table = $table;
- $this->eventDispatcher = $eventDispatcher ? $eventDispatcher : \OC::$server->getEventDispatcher();
+ $this->eventDispatcher = $eventDispatcher ? $eventDispatcher : \OC::$server->query(IEventDispatcher::class);
}
/**
@@ -130,8 +131,7 @@ class Database extends ABackend
$this->fixDI();
if (!$this->userExists($uid)) {
- $event = new GenericEvent($password);
- $this->eventDispatcher->dispatch('OCP\PasswordPolicy::validate', $event);
+ $this->eventDispatcher->dispatchTyped(new ValidatePasswordPolicyEvent($password));
$qb = $this->dbConn->getQueryBuilder();
$qb->insert($this->table)
@@ -199,8 +199,7 @@ class Database extends ABackend
$this->fixDI();
if ($this->userExists($uid)) {
- $event = new GenericEvent($password);
- $this->eventDispatcher->dispatch('OCP\PasswordPolicy::validate', $event);
+ $this->eventDispatcher->dispatchTyped(new ValidatePasswordPolicyEvent($password));
$hasher = \OC::$server->getHasher();
$hashedPassword = $hasher->hash($password);
@@ -259,6 +258,8 @@ class Database extends ABackend
* @return array an array of all displayNames (value) and the corresponding uids (key)
*/
public function getDisplayNames($search = '', $limit = null, $offset = null) {
+ $limit = $this->fixLimit($limit);
+
$this->fixDI();
$query = $this->dbConn->getQueryBuilder();
@@ -380,6 +381,8 @@ class Database extends ABackend
* @return string[] an array of all uids
*/
public function getUsers($search = '', $limit = null, $offset = null) {
+ $limit = $this->fixLimit($limit);
+
$users = $this->getDisplayNames($search, $limit, $offset);
$userIds = array_map(function ($uid) {
return (string)$uid;
@@ -485,5 +488,11 @@ class Database extends ABackend
return $this->cache[$uid]['uid'];
}
+ private function fixLimit($limit) {
+ if (is_int($limit) && $limit >= 0) {
+ return $limit;
+ }
+ return null;
+ }
}
diff --git a/lib/private/User/Manager.php b/lib/private/User/Manager.php
index 7f9691073c9..29cae3da79b 100644
--- a/lib/private/User/Manager.php
+++ b/lib/private/User/Manager.php
@@ -33,12 +33,15 @@ namespace OC\User;
use OC\Hooks\PublicEmitter;
use OCP\DB\QueryBuilder\IQueryBuilder;
-use OCP\IUser;
+use OCP\EventDispatcher\IEventDispatcher;
+use OCP\IConfig;
use OCP\IGroup;
+use OCP\IUser;
use OCP\IUserBackend;
use OCP\IUserManager;
-use OCP\IConfig;
use OCP\User\Backend\IGetRealUIDBackend;
+use OCP\User\Events\CreateUserEvent;
+use OCP\User\Events\UserCreatedEvent;
use OCP\UserInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
@@ -72,17 +75,24 @@ class Manager extends PublicEmitter implements IUserManager {
/** @var IConfig */
private $config;
+
/** @var EventDispatcherInterface */
private $dispatcher;
- public function __construct(IConfig $config, EventDispatcherInterface $dispatcher) {
+ /** @var IEventDispatcher */
+ private $eventDispatcher;
+
+ public function __construct(IConfig $config,
+ EventDispatcherInterface $oldDispatcher,
+ IEventDispatcher $eventDispatcher) {
$this->config = $config;
- $this->dispatcher = $dispatcher;
+ $this->dispatcher = $oldDispatcher;
$cachedUsers = &$this->cachedUsers;
$this->listen('\OC\User', 'postDelete', function ($user) use (&$cachedUsers) {
/** @var \OC\User\User $user */
unset($cachedUsers[$user->getUID()]);
});
+ $this->eventDispatcher = $eventDispatcher;
}
/**
@@ -349,6 +359,7 @@ class Manager extends PublicEmitter implements IUserManager {
}
$this->emit('\OC\User', 'preCreateUser', [$uid, $password]);
+ $this->eventDispatcher->dispatchTyped(new CreateUserEvent($uid, $password));
$state = $backend->createUser($uid, $password);
if($state === false) {
throw new \InvalidArgumentException($l->t('Could not create user'));
@@ -356,6 +367,7 @@ class Manager extends PublicEmitter implements IUserManager {
$user = $this->getUserObject($uid, $backend);
if ($user instanceof IUser) {
$this->emit('\OC\User', 'postCreateUser', [$user, $password]);
+ $this->eventDispatcher->dispatchTyped(new UserCreatedEvent($user, $password));
}
return $user;
}
@@ -460,11 +472,11 @@ class Manager extends PublicEmitter implements IUserManager {
->andWhere($queryBuilder->expr()->eq('configkey', $queryBuilder->createNamedParameter('enabled')))
->andWhere($queryBuilder->expr()->eq('configvalue', $queryBuilder->createNamedParameter('false'), IQueryBuilder::PARAM_STR));
-
+
$result = $queryBuilder->execute();
$count = $result->fetchColumn();
$result->closeCursor();
-
+
if ($count !== false) {
$count = (int)$count;
} else {
@@ -494,7 +506,7 @@ class Manager extends PublicEmitter implements IUserManager {
$result = $queryBuilder->execute();
$count = $result->fetchColumn();
$result->closeCursor();
-
+
if ($count !== false) {
$count = (int)$count;
} else {
diff --git a/lib/private/User/NoUserException.php b/lib/private/User/NoUserException.php
index a80bf7dc54b..b72fb6a9e25 100644
--- a/lib/private/User/NoUserException.php
+++ b/lib/private/User/NoUserException.php
@@ -22,4 +22,4 @@
namespace OC\User;
-class NoUserException extends \Exception {} \ No newline at end of file
+class NoUserException extends \Exception {}
diff --git a/lib/private/User/Session.php b/lib/private/User/Session.php
index 13519d97ef4..3b0231aea03 100644
--- a/lib/private/User/Session.php
+++ b/lib/private/User/Session.php
@@ -61,6 +61,7 @@ use OCP\IUserSession;
use OCP\Lockdown\ILockdownManager;
use OCP\Security\ISecureRandom;
use OCP\Session\Exceptions\SessionNotAvailableException;
+use OCP\User\Events\PostLoginEvent;
use OCP\Util;
use Symfony\Component\EventDispatcher\GenericEvent;
@@ -315,6 +316,29 @@ class Session implements IUserSession, Emitter {
}
/**
+ * @return mixed
+ */
+ public function getImpersonatingUserID(): ?string {
+
+ return $this->session->get('oldUserId');
+
+ }
+
+ public function setImpersonatingUserID(bool $useCurrentUser = true): void {
+ if ($useCurrentUser === false) {
+ $this->session->remove('oldUserId');
+ return;
+ }
+
+ $currentUser = $this->getUser();
+
+ if ($currentUser === null) {
+ throw new \OC\User\NoUserException();
+ }
+ $this->session->set('oldUserId', $currentUser->getUID());
+
+ }
+ /**
* set the token id
*
* @param int|null $token that was used to log in
@@ -375,13 +399,11 @@ class Session implements IUserSession, Emitter {
$firstTimeLogin = $user->updateLastLoginTimestamp();
}
- $postLoginEvent = new OC\User\Events\PostLoginEvent(
+ $this->dispatcher->dispatchTyped(new PostLoginEvent(
$user,
$loginDetails['password'],
$isToken
- );
- $this->dispatcher->dispatch(OC\User\Events\PostLoginEvent::class, $postLoginEvent);
-
+ ));
$this->manager->emit('\OC\User', 'postLogin', [
$user,
$loginDetails['password'],
@@ -838,7 +860,7 @@ class Session implements IUserSession, Emitter {
try {
$sessionId = $this->session->getId();
- $this->tokenProvider->renewSessionToken($oldSessionId, $sessionId);
+ $token = $this->tokenProvider->renewSessionToken($oldSessionId, $sessionId);
} catch (SessionNotAvailableException $ex) {
return false;
} catch (InvalidTokenException $ex) {
@@ -847,7 +869,6 @@ class Session implements IUserSession, Emitter {
}
$this->setMagicInCookie($user->getUID(), $newToken);
- $token = $this->tokenProvider->getToken($sessionId);
//login
$this->setUser($user);
diff --git a/lib/private/User/User.php b/lib/private/User/User.php
index 12af787a5a6..96f0f38b82a 100644
--- a/lib/private/User/User.php
+++ b/lib/private/User/User.php
@@ -36,12 +36,12 @@ use OC\Files\Cache\Storage;
use OC\Hooks\Emitter;
use OC_Helper;
use OCP\IAvatarManager;
+use OCP\IConfig;
use OCP\IImage;
use OCP\IURLGenerator;
use OCP\IUser;
-use OCP\IConfig;
+use OCP\IUserBackend;
use OCP\UserInterface;
-use \OCP\IUserBackend;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\EventDispatcher\GenericEvent;
diff --git a/lib/private/legacy/app.php b/lib/private/legacy/app.php
index 58b617aae45..146262c3f95 100644
--- a/lib/private/legacy/app.php
+++ b/lib/private/legacy/app.php
@@ -55,6 +55,7 @@ use OC\App\Platform;
use OC\DB\MigrationService;
use OC\Installer;
use OC\Repair;
+use OC\ServerNotAvailableException;
use OCP\App\ManagerEvent;
use OCP\ILogger;
@@ -153,6 +154,9 @@ class OC_App {
try {
self::requireAppFile($app);
} catch (Throwable $ex) {
+ if($ex instanceof ServerNotAvailableException) {
+ throw $ex;
+ }
\OC::$server->getLogger()->logException($ex);
if (!\OC::$server->getAppManager()->isShipped($app)) {
// Only disable apps which are not shipped
@@ -485,6 +489,7 @@ class OC_App {
*
* @param string $appId
* @return string|false
+ * @deprecated 11.0.0 use \OC::$server->getAppManager()->getAppPath()
*/
public static function getAppPath(string $appId) {
if ($appId === null || trim($appId) === '') {
@@ -503,6 +508,7 @@ class OC_App {
*
* @param string $appId
* @return string|false
+ * @deprecated 18.0.0 use \OC::$server->getAppManager()->getAppWebPath()
*/
public static function getAppWebPath(string $appId) {
if (($dir = self::findAppInDirectories($appId)) != false) {
diff --git a/lib/private/legacy/defaults.php b/lib/private/legacy/defaults.php
index d313366abe7..8633113ba5a 100644
--- a/lib/private/legacy/defaults.php
+++ b/lib/private/legacy/defaults.php
@@ -52,7 +52,6 @@ class OC_Defaults {
private $defaultTextColorPrimary;
public function __construct() {
- $l10n = \OC::$server->getL10N('lib');
$config = \OC::$server->getConfig();
$this->defaultEntity = 'Nextcloud'; /* e.g. company name, used for footers and copyright notices */
@@ -65,7 +64,6 @@ class OC_Defaults {
$this->defaultAndroidClientUrl = $config->getSystemValue('customclient_android', 'https://play.google.com/store/apps/details?id=com.nextcloud.client');
$this->defaultDocBaseUrl = 'https://docs.nextcloud.com';
$this->defaultDocVersion = \OC_Util::getVersion()[0]; // used to generate doc links
- $this->defaultSlogan = $l10n->t('a safe home for all your data');
$this->defaultColorPrimary = '#0082c9';
$this->defaultTextColorPrimary = '#ffffff';
@@ -219,6 +217,10 @@ class OC_Defaults {
if ($this->themeExist('getSlogan')) {
return $this->theme->getSlogan();
} else {
+ if ($this->defaultSlogan === null) {
+ $l10n = \OC::$server->getL10N('lib');
+ $this->defaultSlogan = $l10n->t('a safe home for all your data');
+ }
return $this->defaultSlogan;
}
}
diff --git a/lib/private/legacy/eventsource.php b/lib/private/legacy/eventsource.php
index 1e68dd24af0..aa3d3395443 100644
--- a/lib/private/legacy/eventsource.php
+++ b/lib/private/legacy/eventsource.php
@@ -27,7 +27,7 @@
*/
/**
- * wrapper for server side events (http://en.wikipedia.org/wiki/Server-sent_events)
+ * wrapper for server side events (https://en.wikipedia.org/wiki/Server-sent_events)
* includes a fallback for older browsers and IE
*
* use server side events with caution, to many open requests can hang the server
diff --git a/lib/private/legacy/files.php b/lib/private/legacy/files.php
index 577392f1edc..140c02e77b6 100644
--- a/lib/private/legacy/files.php
+++ b/lib/private/legacy/files.php
@@ -177,10 +177,21 @@ class OC_Files {
foreach ($files as $file) {
$file = $dir . '/' . $file;
if (\OC\Files\Filesystem::is_file($file)) {
- $fileSize = \OC\Files\Filesystem::filesize($file);
- $fileTime = \OC\Files\Filesystem::filemtime($file);
- $fh = \OC\Files\Filesystem::fopen($file, 'r');
- $streamer->addFileFromStream($fh, basename($file), $fileSize, $fileTime);
+ $userFolder = \OC::$server->getRootFolder()->get(\OC\Files\Filesystem::getRoot());
+ $file = $userFolder->get($file);
+ if($file instanceof \OC\Files\Node\File) {
+ $fh = $file->fopen('r');
+ $fileSize = $file->getSize();
+ $fileTime = $file->getMTime();
+ } else {
+ // File is not a file? …
+ \OC::$server->getLogger()->debug(
+ 'File given, but no Node available. Name {file}',
+ [ 'app' => 'files', 'file' => $file ]
+ );
+ continue;
+ }
+ $streamer->addFileFromStream($fh, $file->getName(), $fileSize, $fileTime);
fclose($fh);
} elseif (\OC\Files\Filesystem::is_dir($file)) {
$streamer->addDirRecursive($file);
diff --git a/lib/private/legacy/helper.php b/lib/private/legacy/helper.php
index a5ed3a3e24b..3c4915ae748 100644
--- a/lib/private/legacy/helper.php
+++ b/lib/private/legacy/helper.php
@@ -189,6 +189,7 @@ class OC_Helper {
}
/**
+ * @deprecated 18.0.0
* @return \OC\Files\Type\TemplateManager
*/
static public function getFileTemplateManager() {
@@ -585,8 +586,13 @@ class OC_Helper {
$relative = 0;
}
- return array('free' => $free, 'used' => $used, 'total' => $total, 'relative' => $relative);
-
+ return [
+ 'free' => $free,
+ 'used' => $used,
+ 'total' => $total,
+ 'relative' => $relative,
+ 'quota' => $quota
+ ];
}
/**
diff --git a/lib/private/legacy/image.php b/lib/private/legacy/image.php
index d9af45f2226..2efde2ee688 100644
--- a/lib/private/legacy/image.php
+++ b/lib/private/legacy/image.php
@@ -878,10 +878,8 @@ class OC_Image implements \OCP\IImage {
$widthOrig = imagesx($this->resource);
$heightOrig = imagesy($this->resource);
$process = imagecreatetruecolor($width, $height);
-
- if ($process == false) {
+ if ($process === false) {
$this->logger->error(__METHOD__ . '(): Error creating true color image', array('app' => 'core'));
- imagedestroy($process);
return false;
}
@@ -892,8 +890,8 @@ class OC_Image implements \OCP\IImage {
imagesavealpha($process, true);
}
- imagecopyresampled($process, $this->resource, 0, 0, 0, 0, $width, $height, $widthOrig, $heightOrig);
- if ($process == false) {
+ $res = imagecopyresampled($process, $this->resource, 0, 0, 0, 0, $width, $height, $widthOrig, $heightOrig);
+ if ($res === false) {
$this->logger->error(__METHOD__ . '(): Error re-sampling process image', array('app' => 'core'));
imagedestroy($process);
return false;
diff --git a/lib/private/legacy/template.php b/lib/private/legacy/template.php
index 6d9bf7c99f4..26b1b360adc 100644
--- a/lib/private/legacy/template.php
+++ b/lib/private/legacy/template.php
@@ -266,7 +266,7 @@ class OC_Template extends \OC\Template\Base {
* @return bool
*/
public static function printGuestPage( $application, $name, $parameters = array() ) {
- $content = new OC_Template( $application, $name, "guest" );
+ $content = new OC_Template($application, $name, $name === 'error' ? $name : 'guest');
foreach( $parameters as $key => $value ) {
$content->assign( $key, $value );
}
diff --git a/lib/private/legacy/util.php b/lib/private/legacy/util.php
index 810f22fb9e5..f73756dd240 100644
--- a/lib/private/legacy/util.php
+++ b/lib/private/legacy/util.php
@@ -61,11 +61,11 @@
*
*/
+use OC\AppFramework\Http\Request;
use OCP\IConfig;
use OCP\IGroupManager;
use OCP\ILogger;
use OCP\IUser;
-use OC\AppFramework\Http\Request;
class OC_Util {
public static $scripts = array();
@@ -1249,6 +1249,18 @@ class OC_Util {
$content = false;
}
+ if (strpos($url, 'https:') === 0) {
+ $url = 'http:' . substr($url, 6);
+ } else {
+ $url = 'https:' . substr($url, 5);
+ }
+
+ try {
+ $fallbackContent = \OC::$server->getHTTPClientService()->newClient()->get($url)->getBody();
+ } catch (\Exception $e) {
+ $fallbackContent = false;
+ }
+
// cleanup
@unlink($testFile);
@@ -1256,7 +1268,7 @@ class OC_Util {
* If the content is not equal to test content our .htaccess
* is working as required
*/
- return $content !== $testContent;
+ return $content !== $testContent && $fallbackContent !== $testContent;
}
/**