diff options
Diffstat (limited to 'lib/private')
-rw-r--r-- | lib/private/DB/Adapter.php | 20 | ||||
-rw-r--r-- | lib/private/DB/AdapterOCI8.php | 2 | ||||
-rw-r--r-- | lib/private/DB/AdapterPgSql.php | 2 | ||||
-rw-r--r-- | lib/private/DB/Connection.php | 29 | ||||
-rw-r--r-- | lib/private/Files/Config/MountProviderCollection.php | 116 | ||||
-rw-r--r-- | lib/private/Files/Config/UserMountCache.php | 31 | ||||
-rw-r--r-- | lib/private/Files/SetupManager.php | 9 | ||||
-rw-r--r-- | lib/private/Files/Template/TemplateManager.php | 65 | ||||
-rw-r--r-- | lib/private/PreviewManager.php | 8 | ||||
-rw-r--r-- | lib/private/Repair.php | 3 | ||||
-rw-r--r-- | lib/private/Repair/NC16/CleanupCardDAVPhotoCache.php | 24 | ||||
-rw-r--r-- | lib/private/Security/Bruteforce/Throttler.php | 26 | ||||
-rw-r--r-- | lib/private/legacy/OC_Helper.php | 3 | ||||
-rw-r--r-- | lib/private/legacy/OC_Util.php | 3 |
14 files changed, 199 insertions, 142 deletions
diff --git a/lib/private/DB/Adapter.php b/lib/private/DB/Adapter.php index edd8c1bf023..8f1b8e6d75f 100644 --- a/lib/private/DB/Adapter.php +++ b/lib/private/DB/Adapter.php @@ -28,25 +28,11 @@ class Adapter { /** * @param string $table name * - * @return int id of last insert statement, 0 in case there was no INSERT before or it failed to get the ID + * @return int id of last insert statement * @throws Exception */ - public function lastInsertId($table, bool $allowRetry = true): int { - $return = $this->conn->realLastInsertId($table); - if ($return === 0 && $allowRetry) { - /** - * During a reconnect we are losing the connection and when the - * realLastInsertId call is the one triggering the reconnect, it - * does not return the ID. But inside the reconnect, we were able - * to save the last insert id, so calling it a second time is going - * to be successful. - * We can not return the result on the initial call, as we are already - * way deeper in the stack performing the actual database query on - * the doctrine driver. - */ - return $this->lastInsertId($table, false); - } - return $return; + public function lastInsertId($table) { + return (int)$this->conn->realLastInsertId($table); } /** diff --git a/lib/private/DB/AdapterOCI8.php b/lib/private/DB/AdapterOCI8.php index f5ad9f7c934..0a509090bca 100644 --- a/lib/private/DB/AdapterOCI8.php +++ b/lib/private/DB/AdapterOCI8.php @@ -8,7 +8,7 @@ namespace OC\DB; class AdapterOCI8 extends Adapter { - public function lastInsertId($table, bool $allowRetry = true): int { + public function lastInsertId($table) { if (is_null($table)) { throw new \InvalidArgumentException('Oracle requires a table name to be passed into lastInsertId()'); } diff --git a/lib/private/DB/AdapterPgSql.php b/lib/private/DB/AdapterPgSql.php index b321fcf4715..db48c81c2c5 100644 --- a/lib/private/DB/AdapterPgSql.php +++ b/lib/private/DB/AdapterPgSql.php @@ -9,7 +9,7 @@ namespace OC\DB; class AdapterPgSql extends Adapter { - public function lastInsertId($table, bool $allowRetry = true): int { + public function lastInsertId($table) { $result = $this->conn->executeQuery('SELECT lastval()'); $val = $result->fetchOne(); $result->free(); diff --git a/lib/private/DB/Connection.php b/lib/private/DB/Connection.php index 4ba2d2a341d..96dd578b2ef 100644 --- a/lib/private/DB/Connection.php +++ b/lib/private/DB/Connection.php @@ -92,8 +92,6 @@ class Connection extends PrimaryReadReplicaConnection { protected ShardConnectionManager $shardConnectionManager; protected AutoIncrementHandler $autoIncrementHandler; protected bool $isShardingEnabled; - protected bool $disableReconnect = false; - protected int $lastInsertId = 0; public const SHARD_PRESETS = [ 'filecache' => [ @@ -512,9 +510,9 @@ class Connection extends PrimaryReadReplicaConnection { * because the underlying database may not even support the notion of AUTO_INCREMENT/IDENTITY * columns or sequences. * - * @param ?string $name Name of the sequence object from which the ID should be returned. + * @param string $seqName Name of the sequence object from which the ID should be returned. * - * @return int the last inserted ID, 0 in case there was no INSERT before or it failed to get the ID + * @return int the last inserted ID. * @throws Exception */ public function lastInsertId($name = null): int { @@ -528,13 +526,8 @@ class Connection extends PrimaryReadReplicaConnection { * @internal * @throws Exception */ - public function realLastInsertId($seqName = null): int { - if ($this->lastInsertId !== 0) { - $lastInsertId = $this->lastInsertId; - $this->lastInsertId = 0; - return $lastInsertId; - } - return (int)parent::lastInsertId($seqName); + public function realLastInsertId($seqName = null) { + return parent::lastInsertId($seqName); } /** @@ -903,23 +896,11 @@ class Connection extends PrimaryReadReplicaConnection { if ( !isset($this->lastConnectionCheck[$this->getConnectionName()]) || time() <= $this->lastConnectionCheck[$this->getConnectionName()] + 30 || - $this->isTransactionActive() || - $this->disableReconnect + $this->isTransactionActive() ) { return; } - if ($this->getDatabaseProvider() === IDBConnection::PLATFORM_MYSQL) { - /** - * Before reconnecting we save the lastInsertId, so that if the reconnect - * happens between the INSERT executeStatement() and the getLastInsertId call - * we are able to return the correct result after all. - */ - $this->disableReconnect = true; - $this->lastInsertId = (int)parent::lastInsertId(); - $this->disableReconnect = false; - } - try { $this->_conn->query($this->getDriver()->getDatabasePlatform()->getDummySelectSQL()); $this->lastConnectionCheck[$this->getConnectionName()] = time(); diff --git a/lib/private/Files/Config/MountProviderCollection.php b/lib/private/Files/Config/MountProviderCollection.php index 6a5407934c8..9d63184e05f 100644 --- a/lib/private/Files/Config/MountProviderCollection.php +++ b/lib/private/Files/Config/MountProviderCollection.php @@ -24,60 +24,43 @@ class MountProviderCollection implements IMountProviderCollection, Emitter { use EmitterTrait; /** - * @var \OCP\Files\Config\IHomeMountProvider[] + * @var list<IHomeMountProvider> */ - private $homeProviders = []; + private array $homeProviders = []; /** - * @var \OCP\Files\Config\IMountProvider[] + * @var list<IMountProvider> */ - private $providers = []; + private array $providers = []; - /** @var \OCP\Files\Config\IRootMountProvider[] */ - private $rootProviders = []; + /** @var list<IRootMountProvider> */ + private array $rootProviders = []; - /** - * @var \OCP\Files\Storage\IStorageFactory - */ - private $loader; - - /** - * @var \OCP\Files\Config\IUserMountCache - */ - private $mountCache; - - /** @var callable[] */ - private $mountFilters = []; + /** @var list<callable> */ + private array $mountFilters = []; - private IEventLogger $eventLogger; - - /** - * @param \OCP\Files\Storage\IStorageFactory $loader - * @param IUserMountCache $mountCache - */ public function __construct( - IStorageFactory $loader, - IUserMountCache $mountCache, - IEventLogger $eventLogger, + private IStorageFactory $loader, + private IUserMountCache $mountCache, + private IEventLogger $eventLogger, ) { - $this->loader = $loader; - $this->mountCache = $mountCache; - $this->eventLogger = $eventLogger; } + /** + * @return list<IMountPoint> + */ private function getMountsFromProvider(IMountProvider $provider, IUser $user, IStorageFactory $loader): array { $class = str_replace('\\', '_', get_class($provider)); $uid = $user->getUID(); $this->eventLogger->start('fs:setup:provider:' . $class, "Getting mounts from $class for $uid"); $mounts = $provider->getMountsForUser($user, $loader) ?? []; $this->eventLogger->end('fs:setup:provider:' . $class); - return $mounts; + return array_values($mounts); } /** - * @param IUser $user - * @param IMountProvider[] $providers - * @return IMountPoint[] + * @param list<IMountProvider> $providers + * @return list<IMountPoint> */ private function getUserMountsForProviders(IUser $user, array $providers): array { $loader = $this->loader; @@ -90,10 +73,16 @@ class MountProviderCollection implements IMountProviderCollection, Emitter { return $this->filterMounts($user, $mounts); } + /** + * @return list<IMountPoint> + */ public function getMountsForUser(IUser $user): array { return $this->getUserMountsForProviders($user, $this->providers); } + /** + * @return list<IMountPoint> + */ public function getUserMountsForProviderClasses(IUser $user, array $mountProviderClasses): array { $providers = array_filter( $this->providers, @@ -102,7 +91,10 @@ class MountProviderCollection implements IMountProviderCollection, Emitter { return $this->getUserMountsForProviders($user, $providers); } - public function addMountForUser(IUser $user, IMountManager $mountManager, ?callable $providerFilter = null) { + /** + * @return list<IMountPoint> + */ + public function addMountForUser(IUser $user, IMountManager $mountManager, ?callable $providerFilter = null): array { // shared mount provider gets to go last since it needs to know existing files // to check for name collisions $firstMounts = []; @@ -135,18 +127,15 @@ class MountProviderCollection implements IMountProviderCollection, Emitter { array_walk($lateMounts, [$mountManager, 'addMount']); $this->eventLogger->end('fs:setup:add-mounts'); - return array_merge($lateMounts, $firstMounts); + return array_values(array_merge($lateMounts, $firstMounts)); } /** * Get the configured home mount for this user * - * @param \OCP\IUser $user - * @return \OCP\Files\Mount\IMountPoint * @since 9.1.0 */ - public function getHomeMountForUser(IUser $user) { - /** @var \OCP\Files\Config\IHomeMountProvider[] $providers */ + public function getHomeMountForUser(IUser $user): IMountPoint { $providers = array_reverse($this->homeProviders); // call the latest registered provider first to give apps an opportunity to overwrite builtin foreach ($providers as $homeProvider) { if ($mount = $homeProvider->getHomeMountForUser($user, $this->loader)) { @@ -159,34 +148,36 @@ class MountProviderCollection implements IMountProviderCollection, Emitter { /** * Add a provider for mount points - * - * @param \OCP\Files\Config\IMountProvider $provider */ - public function registerProvider(IMountProvider $provider) { + public function registerProvider(IMountProvider $provider): void { $this->providers[] = $provider; $this->emit('\OC\Files\Config', 'registerMountProvider', [$provider]); } - public function registerMountFilter(callable $filter) { + public function registerMountFilter(callable $filter): void { $this->mountFilters[] = $filter; } - private function filterMounts(IUser $user, array $mountPoints) { - return array_filter($mountPoints, function (IMountPoint $mountPoint) use ($user) { + /** + * @param list<IMountPoint> $mountPoints + * @return list<IMountPoint> + */ + private function filterMounts(IUser $user, array $mountPoints): array { + return array_values(array_filter($mountPoints, function (IMountPoint $mountPoint) use ($user) { foreach ($this->mountFilters as $filter) { if ($filter($mountPoint, $user) === false) { return false; } } return true; - }); + })); } /** * Add a provider for home mount points * - * @param \OCP\Files\Config\IHomeMountProvider $provider + * @param IHomeMountProvider $provider * @since 9.1.0 */ public function registerHomeProvider(IHomeMountProvider $provider) { @@ -196,21 +187,19 @@ class MountProviderCollection implements IMountProviderCollection, Emitter { /** * Get the mount cache which can be used to search for mounts without setting up the filesystem - * - * @return IUserMountCache */ - public function getMountCache() { + public function getMountCache(): IUserMountCache { return $this->mountCache; } - public function registerRootProvider(IRootMountProvider $provider) { + public function registerRootProvider(IRootMountProvider $provider): void { $this->rootProviders[] = $provider; } /** * Get all root mountpoints * - * @return \OCP\Files\Mount\IMountPoint[] + * @return list<IMountPoint> * @since 20.0.0 */ public function getRootMounts(): array { @@ -226,16 +215,33 @@ class MountProviderCollection implements IMountProviderCollection, Emitter { throw new \Exception('No root mounts provided by any provider'); } - return $mounts; + return array_values($mounts); } - public function clearProviders() { + public function clearProviders(): void { $this->providers = []; $this->homeProviders = []; $this->rootProviders = []; } + /** + * @return list<IMountProvider> + */ public function getProviders(): array { return $this->providers; } + + /** + * @return list<IHomeMountProvider> + */ + public function getHomeProviders(): array { + return $this->homeProviders; + } + + /** + * @return list<IRootMountProvider> + */ + public function getRootProviders(): array { + return $this->rootProviders; + } } diff --git a/lib/private/Files/Config/UserMountCache.php b/lib/private/Files/Config/UserMountCache.php index 9c1e2314262..09ac6d1416a 100644 --- a/lib/private/Files/Config/UserMountCache.php +++ b/lib/private/Files/Config/UserMountCache.php @@ -11,6 +11,10 @@ use OC\User\LazyUser; use OCP\Cache\CappedMemoryCache; use OCP\DB\QueryBuilder\IQueryBuilder; use OCP\Diagnostics\IEventLogger; +use OCP\EventDispatcher\IEventDispatcher; +use OCP\Files\Config\Event\UserMountAddedEvent; +use OCP\Files\Config\Event\UserMountRemovedEvent; +use OCP\Files\Config\Event\UserMountUpdatedEvent; use OCP\Files\Config\ICachedMountFileInfo; use OCP\Files\Config\ICachedMountInfo; use OCP\Files\Config\IUserMountCache; @@ -46,6 +50,7 @@ class UserMountCache implements IUserMountCache { private IUserManager $userManager, private LoggerInterface $logger, private IEventLogger $eventLogger, + private IEventDispatcher $eventDispatcher, ) { $this->cacheInfoCache = new CappedMemoryCache(); $this->internalPathCache = new CappedMemoryCache(); @@ -108,17 +113,29 @@ class UserMountCache implements IUserMountCache { $this->removeFromCache($mount); unset($this->mountsForUsers[$userUID][$mount->getKey()]); } - foreach ($changedMounts as $mount) { - $this->logger->debug("Updating mount '{$mount->getKey()}' for user '$userUID'", ['app' => 'files', 'mount_provider' => $mount->getMountProvider()]); - $this->updateCachedMount($mount); + foreach ($changedMounts as $mountPair) { + $newMount = $mountPair[1]; + $this->logger->debug("Updating mount '{$newMount->getKey()}' for user '$userUID'", ['app' => 'files', 'mount_provider' => $newMount->getMountProvider()]); + $this->updateCachedMount($newMount); /** @psalm-suppress InvalidArgument */ - $this->mountsForUsers[$userUID][$mount->getKey()] = $mount; + $this->mountsForUsers[$userUID][$newMount->getKey()] = $newMount; } $this->connection->commit(); } catch (\Throwable $e) { $this->connection->rollBack(); throw $e; } + + // Only fire events after all mounts have already been adjusted in the database. + foreach ($addedMounts as $mount) { + $this->eventDispatcher->dispatchTyped(new UserMountAddedEvent($mount)); + } + foreach ($removedMounts as $mount) { + $this->eventDispatcher->dispatchTyped(new UserMountRemovedEvent($mount)); + } + foreach ($changedMounts as $mountPair) { + $this->eventDispatcher->dispatchTyped(new UserMountUpdatedEvent($mountPair[0], $mountPair[1])); + } } $this->eventLogger->end('fs:setup:user:register'); } @@ -126,9 +143,9 @@ class UserMountCache implements IUserMountCache { /** * @param array<string, ICachedMountInfo> $newMounts * @param array<string, ICachedMountInfo> $cachedMounts - * @return ICachedMountInfo[] + * @return list<list{0: ICachedMountInfo, 1: ICachedMountInfo}> Pairs of old and new mounts */ - private function findChangedMounts(array $newMounts, array $cachedMounts) { + private function findChangedMounts(array $newMounts, array $cachedMounts): array { $changed = []; foreach ($cachedMounts as $key => $cachedMount) { if (isset($newMounts[$key])) { @@ -138,7 +155,7 @@ class UserMountCache implements IUserMountCache { $newMount->getMountId() !== $cachedMount->getMountId() || $newMount->getMountProvider() !== $cachedMount->getMountProvider() ) { - $changed[] = $newMount; + $changed[] = [$cachedMount, $newMount]; } } } diff --git a/lib/private/Files/SetupManager.php b/lib/private/Files/SetupManager.php index 2b8121a529d..7f97187179e 100644 --- a/lib/private/Files/SetupManager.php +++ b/lib/private/Files/SetupManager.php @@ -34,6 +34,7 @@ use OCP\EventDispatcher\IEventDispatcher; use OCP\Files\Config\ICachedMountInfo; use OCP\Files\Config\IHomeMountProvider; use OCP\Files\Config\IMountProvider; +use OCP\Files\Config\IRootMountProvider; use OCP\Files\Config\IUserMountCache; use OCP\Files\Events\BeforeFileSystemSetupEvent; use OCP\Files\Events\InvalidateMountCacheEvent; @@ -280,9 +281,13 @@ class SetupManager { $mounts = array_filter($mounts, function (IMountPoint $mount) use ($userRoot) { return str_starts_with($mount->getMountPoint(), $userRoot); }); - $allProviders = array_map(function (IMountProvider $provider) { + $allProviders = array_map(function (IMountProvider|IHomeMountProvider|IRootMountProvider $provider) { return get_class($provider); - }, $this->mountProviderCollection->getProviders()); + }, array_merge( + $this->mountProviderCollection->getProviders(), + $this->mountProviderCollection->getHomeProviders(), + $this->mountProviderCollection->getRootProviders(), + )); $newProviders = array_diff($allProviders, $previouslySetupProviders); $mounts = array_filter($mounts, function (IMountPoint $mount) use ($previouslySetupProviders) { return !in_array($mount->getMountProvider(), $previouslySetupProviders); diff --git a/lib/private/Files/Template/TemplateManager.php b/lib/private/Files/Template/TemplateManager.php index 8032cdf941f..80ef5a14786 100644 --- a/lib/private/Files/Template/TemplateManager.php +++ b/lib/private/Files/Template/TemplateManager.php @@ -19,6 +19,7 @@ use OCP\Files\IRootFolder; use OCP\Files\Node; use OCP\Files\NotFoundException; use OCP\Files\Template\BeforeGetTemplatesEvent; +use OCP\Files\Template\Field; use OCP\Files\Template\FileCreatedFromTemplateEvent; use OCP\Files\Template\ICustomTemplateProvider; use OCP\Files\Template\ITemplateManager; @@ -125,6 +126,19 @@ class TemplateManager implements ITemplateManager { }, $this->listCreators())); } + public function listTemplateFields(int $fileId): array { + foreach ($this->listCreators() as $creator) { + $fields = $this->getTemplateFields($creator, $fileId); + if (empty($fields)) { + continue; + } + + return $fields; + } + + return []; + } + /** * @param string $filePath * @param string $templateId @@ -187,6 +201,20 @@ class TemplateManager implements ITemplateManager { * @return list<Template> */ private function getTemplateFiles(TemplateFileCreator $type): array { + $templates = array_merge( + $this->getProviderTemplates($type), + $this->getUserTemplates($type) + ); + + $this->eventDispatcher->dispatchTyped(new BeforeGetTemplatesEvent($templates, false)); + + return $templates; + } + + /** + * @return list<Template> + */ + private function getProviderTemplates(TemplateFileCreator $type): array { $templates = []; foreach ($this->getRegisteredProviders() as $provider) { foreach ($type->getMimetypes() as $mimetype) { @@ -195,11 +223,22 @@ class TemplateManager implements ITemplateManager { } } } + + return $templates; + } + + /** + * @return list<Template> + */ + private function getUserTemplates(TemplateFileCreator $type): array { + $templates = []; + try { $userTemplateFolder = $this->getTemplateFolder(); } catch (\Exception $e) { return $templates; } + foreach ($type->getMimetypes() as $mimetype) { foreach ($userTemplateFolder->searchByMime($mimetype) as $templateFile) { $template = new Template( @@ -212,11 +251,33 @@ class TemplateManager implements ITemplateManager { } } - $this->eventDispatcher->dispatchTyped(new BeforeGetTemplatesEvent($templates)); - return $templates; } + /* + * @return list<Field> + */ + private function getTemplateFields(TemplateFileCreator $type, int $fileId): array { + $providerTemplates = $this->getProviderTemplates($type); + $userTemplates = $this->getUserTemplates($type); + + $matchedTemplates = array_filter( + array_merge($providerTemplates, $userTemplates), + function (Template $template) use ($fileId) { + return $template->jsonSerialize()['fileid'] === $fileId; + }); + + if (empty($matchedTemplates)) { + return []; + } + + $this->eventDispatcher->dispatchTyped(new BeforeGetTemplatesEvent($matchedTemplates, true)); + + return array_values(array_map(function (Template $template) { + return $template->jsonSerialize()['fields'] ?? []; + }, $matchedTemplates)); + } + /** * @param Node|File $file * @return array diff --git a/lib/private/PreviewManager.php b/lib/private/PreviewManager.php index 1f618dab22d..fa62a7b0257 100644 --- a/lib/private/PreviewManager.php +++ b/lib/private/PreviewManager.php @@ -154,7 +154,7 @@ class PreviewManager implements IPreview { $mimeType = null, bool $cacheResult = true, ): ISimpleFile { - $this->throwIfPreviewsDisabled(); + $this->throwIfPreviewsDisabled($file); $previewConcurrency = $this->getGenerator()->getNumConcurrentPreviews('preview_concurrency_all'); $sem = Generator::guardWithSemaphore(Generator::SEMAPHORE_ID_ALL, $previewConcurrency); try { @@ -178,7 +178,7 @@ class PreviewManager implements IPreview { * @since 19.0.0 */ public function generatePreviews(File $file, array $specifications, $mimeType = null) { - $this->throwIfPreviewsDisabled(); + $this->throwIfPreviewsDisabled($file); return $this->getGenerator()->generatePreviews($file, $specifications, $mimeType); } @@ -455,8 +455,8 @@ class PreviewManager implements IPreview { /** * @throws NotFoundException if preview generation is disabled */ - private function throwIfPreviewsDisabled(): void { - if (!$this->enablePreviews) { + private function throwIfPreviewsDisabled(File $file): void { + if (!$this->isAvailable($file)) { throw new NotFoundException('Previews disabled'); } } diff --git a/lib/private/Repair.php b/lib/private/Repair.php index c5069bff48e..7fbf776d9a1 100644 --- a/lib/private/Repair.php +++ b/lib/private/Repair.php @@ -61,6 +61,7 @@ use OCP\AppFramework\QueryException; use OCP\AppFramework\Utility\ITimeFactory; use OCP\Collaboration\Resources\IManager; use OCP\EventDispatcher\IEventDispatcher; +use OCP\Files\AppData\IAppDataFactory; use OCP\IAppConfig; use OCP\IConfig; use OCP\IDBConnection; @@ -173,7 +174,7 @@ class Repair implements IOutput { \OCP\Server::get(ClearGeneratedAvatarCache::class), new AddPreviewBackgroundCleanupJob(\OC::$server->getJobList()), new AddCleanupUpdaterBackupsJob(\OC::$server->getJobList()), - new CleanupCardDAVPhotoCache(\OC::$server->getConfig(), \OC::$server->getAppDataDir('dav-photocache'), \OC::$server->get(LoggerInterface::class)), + new CleanupCardDAVPhotoCache(\OC::$server->getConfig(), \OCP\Server::get(IAppDataFactory::class), \OC::$server->get(LoggerInterface::class)), new AddClenupLoginFlowV2BackgroundJob(\OC::$server->getJobList()), new RemoveLinkShares(\OC::$server->getDatabaseConnection(), \OC::$server->getConfig(), \OC::$server->getGroupManager(), \OC::$server->get(INotificationManager::class), \OCP\Server::get(ITimeFactory::class)), new ClearCollectionsAccessCache(\OC::$server->getConfig(), \OCP\Server::get(IManager::class)), diff --git a/lib/private/Repair/NC16/CleanupCardDAVPhotoCache.php b/lib/private/Repair/NC16/CleanupCardDAVPhotoCache.php index a9cbbb4cbbf..646dd2c5e83 100644 --- a/lib/private/Repair/NC16/CleanupCardDAVPhotoCache.php +++ b/lib/private/Repair/NC16/CleanupCardDAVPhotoCache.php @@ -6,9 +6,10 @@ declare(strict_types=1); * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later */ + namespace OC\Repair\NC16; -use OCP\Files\IAppData; +use OCP\Files\AppData\IAppDataFactory; use OCP\Files\NotFoundException; use OCP\Files\SimpleFS\ISimpleFolder; use OCP\IConfig; @@ -27,18 +28,11 @@ use RuntimeException; * photo could be returned for this vcard. These invalid files are removed by this migration step. */ class CleanupCardDAVPhotoCache implements IRepairStep { - /** @var IConfig */ - private $config; - - /** @var IAppData */ - private $appData; - - private LoggerInterface $logger; - - public function __construct(IConfig $config, IAppData $appData, LoggerInterface $logger) { - $this->config = $config; - $this->appData = $appData; - $this->logger = $logger; + public function __construct( + private IConfig $config, + private IAppDataFactory $appDataFactory, + private LoggerInterface $logger, + ) { } public function getName(): string { @@ -46,8 +40,10 @@ class CleanupCardDAVPhotoCache implements IRepairStep { } private function repair(IOutput $output): void { + $photoCacheAppData = $this->appDataFactory->get('dav-photocache'); + try { - $folders = $this->appData->getDirectoryListing(); + $folders = $photoCacheAppData->getDirectoryListing(); } catch (NotFoundException $e) { return; } catch (RuntimeException $e) { diff --git a/lib/private/Security/Bruteforce/Throttler.php b/lib/private/Security/Bruteforce/Throttler.php index 065f720ba72..574f6c80c3f 100644 --- a/lib/private/Security/Bruteforce/Throttler.php +++ b/lib/private/Security/Bruteforce/Throttler.php @@ -206,25 +206,27 @@ class Throttler implements IThrottler { * {@inheritDoc} */ public function sleepDelayOrThrowOnMax(string $ip, string $action = ''): int { - $attempts = $this->getAttempts($ip, $action, 0.5); - if ($attempts > $this->config->getSystemValueInt('auth.bruteforce.max-attempts', self::MAX_ATTEMPTS)) { - $this->logger->info('IP address blocked because it reached the maximum failed attempts in the last 30 minutes [action: {action}, attempts: {attempts}, ip: {ip}]', [ - 'action' => $action, - 'ip' => $ip, - 'attempts' => $attempts, - ]); - // If the ip made too many attempts within the last 30 mins we don't execute anymore - throw new MaxDelayReached('Reached maximum delay'); - } - + $maxAttempts = $this->config->getSystemValueInt('auth.bruteforce.max-attempts', self::MAX_ATTEMPTS); $attempts = $this->getAttempts($ip, $action); - if ($attempts > 10) { + if ($attempts > $maxAttempts) { + $attempts30mins = $this->getAttempts($ip, $action, 0.5); + if ($attempts30mins > $maxAttempts) { + $this->logger->info('IP address blocked because it reached the maximum failed attempts in the last 30 minutes [action: {action}, attempts: {attempts}, ip: {ip}]', [ + 'action' => $action, + 'ip' => $ip, + 'attempts' => $attempts30mins, + ]); + // If the ip made too many attempts within the last 30 mins we don't execute anymore + throw new MaxDelayReached('Reached maximum delay'); + } + $this->logger->info('IP address throttled because it reached the attempts limit in the last 12 hours [action: {action}, attempts: {attempts}, ip: {ip}]', [ 'action' => $action, 'ip' => $ip, 'attempts' => $attempts, ]); } + if ($attempts > 0) { return $this->calculateDelay($attempts); } diff --git a/lib/private/legacy/OC_Helper.php b/lib/private/legacy/OC_Helper.php index a06b15573cb..87c820dcd53 100644 --- a/lib/private/legacy/OC_Helper.php +++ b/lib/private/legacy/OC_Helper.php @@ -199,7 +199,7 @@ class OC_Helper { /** * Try to find a program - * @deprecated 25.0.0 Use \OC\BinaryFinder directly + * @deprecated 25.0.0 Use \OCP\IBinaryFinder directly */ public static function findBinaryPath(string $program): ?string { $result = Server::get(IBinaryFinder::class)->findBinaryPath($program); @@ -415,6 +415,7 @@ class OC_Helper { /** * Returns whether the config file is set manually to read-only * @return bool + * @deprecated 32.0.0 use the `config_is_read_only` system config directly */ public static function isReadOnlyConfigEnabled() { return \OC::$server->getConfig()->getSystemValueBool('config_is_read_only', false); diff --git a/lib/private/legacy/OC_Util.php b/lib/private/legacy/OC_Util.php index 895cfba35c5..9444da4f36d 100644 --- a/lib/private/legacy/OC_Util.php +++ b/lib/private/legacy/OC_Util.php @@ -98,6 +98,7 @@ class OC_Util { * * @param IUser|null $user * @return int|\OCP\Files\FileInfo::SPACE_UNLIMITED|false|float Quota bytes + * @deprecated 9.0.0 - Use \OCP\IUser::getQuota */ public static function getUserQuota(?IUser $user) { if (is_null($user)) { @@ -331,7 +332,7 @@ class OC_Util { } // Check if config folder is writable. - if (!OC_Helper::isReadOnlyConfigEnabled()) { + if (!(bool)$config->getValue('config_is_read_only', false)) { if (!is_writable(OC::$configDir) or !is_readable(OC::$configDir)) { $errors[] = [ 'error' => $l->t('Cannot write into "config" directory.'), |