diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/private/DB/Connection.php | 18 | ||||
-rw-r--r-- | lib/private/Security/RateLimiting/Backend/DatabaseBackend.php | 20 | ||||
-rw-r--r-- | lib/private/Security/RateLimiting/Backend/MemoryCacheBackend.php | 21 | ||||
-rw-r--r-- | lib/private/Server.php | 16 |
4 files changed, 46 insertions, 29 deletions
diff --git a/lib/private/DB/Connection.php b/lib/private/DB/Connection.php index ceaffbcfa9a..85c6a72dfdb 100644 --- a/lib/private/DB/Connection.php +++ b/lib/private/DB/Connection.php @@ -40,8 +40,6 @@ use Doctrine\DBAL\Cache\QueryCacheProfile; use Doctrine\DBAL\Configuration; use Doctrine\DBAL\Driver; use Doctrine\DBAL\Exception; -use Doctrine\DBAL\Exception\ConstraintViolationException; -use Doctrine\DBAL\Exception\NotNullConstraintViolationException; use Doctrine\DBAL\Platforms\MySQLPlatform; use Doctrine\DBAL\Platforms\OraclePlatform; use Doctrine\DBAL\Platforms\PostgreSQL94Platform; @@ -381,10 +379,10 @@ class Connection extends \Doctrine\DBAL\Connection { * @param array $values (column name => value) * @param array $updatePreconditionValues ensure values match preconditions (column name => value) * @return int number of new rows - * @throws \Doctrine\DBAL\Exception + * @throws \OCP\DB\Exception * @throws PreConditionNotMetException */ - public function setValues($table, array $keys, array $values, array $updatePreconditionValues = []) { + public function setValues(string $table, array $keys, array $values, array $updatePreconditionValues = []): int { try { $insertQb = $this->getQueryBuilder(); $insertQb->insert($table) @@ -394,9 +392,15 @@ class Connection extends \Doctrine\DBAL\Connection { }, array_merge($keys, $values)) ); return $insertQb->executeStatement(); - } catch (NotNullConstraintViolationException $e) { - throw $e; - } catch (ConstraintViolationException $e) { + } catch (\OCP\DB\Exception $e) { + if (!in_array($e->getReason(), [ + \OCP\DB\Exception::REASON_CONSTRAINT_VIOLATION, + \OCP\DB\Exception::REASON_UNIQUE_CONSTRAINT_VIOLATION, + ]) + ) { + throw $e; + } + // value already exists, try update $updateQb = $this->getQueryBuilder(); $updateQb->update($table); diff --git a/lib/private/Security/RateLimiting/Backend/DatabaseBackend.php b/lib/private/Security/RateLimiting/Backend/DatabaseBackend.php index ea4bd87d6cd..d1631a8d0ae 100644 --- a/lib/private/Security/RateLimiting/Backend/DatabaseBackend.php +++ b/lib/private/Security/RateLimiting/Backend/DatabaseBackend.php @@ -3,8 +3,10 @@ declare(strict_types=1); /** + * @copyright Copyright (c) 2023 Joas Schilling <coding@schilljs.com> * @copyright Copyright (c) 2021 Lukas Reschke <lukas@statuscode.ch> * + * @author Joas Schilling <coding@schilljs.com> * @author Lukas Reschke <lukas@statuscode.ch> * * @license GNU AGPL version 3 or any later version @@ -27,24 +29,25 @@ namespace OC\Security\RateLimiting\Backend; use OCP\AppFramework\Utility\ITimeFactory; use OCP\DB\QueryBuilder\IQueryBuilder; +use OCP\IConfig; use OCP\IDBConnection; class DatabaseBackend implements IBackend { private const TABLE_NAME = 'ratelimit_entries'; + /** @var IConfig */ + private $config; /** @var IDBConnection */ private $dbConnection; /** @var ITimeFactory */ private $timeFactory; - /** - * @param IDBConnection $dbConnection - * @param ITimeFactory $timeFactory - */ public function __construct( + IConfig $config, IDBConnection $dbConnection, ITimeFactory $timeFactory ) { + $this->config = $config; $this->dbConnection = $dbConnection; $this->timeFactory = $timeFactory; } @@ -115,7 +118,12 @@ class DatabaseBackend implements IBackend { ->values([ 'hash' => $qb->createNamedParameter($identifier, IQueryBuilder::PARAM_STR), 'delete_after' => $qb->createNamedParameter($deleteAfter, IQueryBuilder::PARAM_DATE), - ]) - ->executeStatement(); + ]); + + if (!$this->config->getSystemValueBool('ratelimit.protection.enabled', true)) { + return; + } + + $qb->executeStatement(); } } diff --git a/lib/private/Security/RateLimiting/Backend/MemoryCacheBackend.php b/lib/private/Security/RateLimiting/Backend/MemoryCacheBackend.php index f4880fb239c..4bcb459c64e 100644 --- a/lib/private/Security/RateLimiting/Backend/MemoryCacheBackend.php +++ b/lib/private/Security/RateLimiting/Backend/MemoryCacheBackend.php @@ -3,9 +3,11 @@ declare(strict_types=1); /** + * @copyright Copyright (c) 2023 Joas Schilling <coding@schilljs.com> * @copyright Copyright (c) 2017 Lukas Reschke <lukas@statuscode.ch> * * @author Christoph Wurst <christoph@winzerhof-wurst.at> + * @author Joas Schilling <coding@schilljs.com> * @author Lukas Reschke <lukas@statuscode.ch> * @author Morris Jobke <hey@morrisjobke.de> * @author Roeland Jago Douma <roeland@famdouma.nl> @@ -31,6 +33,7 @@ namespace OC\Security\RateLimiting\Backend; use OCP\AppFramework\Utility\ITimeFactory; use OCP\ICache; use OCP\ICacheFactory; +use OCP\IConfig; /** * Class MemoryCacheBackend uses the configured distributed memory cache for storing @@ -39,17 +42,18 @@ use OCP\ICacheFactory; * @package OC\Security\RateLimiting\Backend */ class MemoryCacheBackend implements IBackend { + /** @var IConfig */ + private $config; /** @var ICache */ private $cache; /** @var ITimeFactory */ private $timeFactory; - /** - * @param ICacheFactory $cacheFactory - * @param ITimeFactory $timeFactory - */ - public function __construct(ICacheFactory $cacheFactory, - ITimeFactory $timeFactory) { + public function __construct( + IConfig $config, + ICacheFactory $cacheFactory, + ITimeFactory $timeFactory) { + $this->config = $config; $this->cache = $cacheFactory->createDistributed(__CLASS__); $this->timeFactory = $timeFactory; } @@ -121,6 +125,11 @@ class MemoryCacheBackend implements IBackend { // Store the new attempt $existingAttempts[] = (string)($currentTime + $period); + + if (!$this->config->getSystemValueBool('ratelimit.protection.enabled', true)) { + return; + } + $this->cache->set($identifier, json_encode($existingAttempts)); } } diff --git a/lib/private/Server.php b/lib/private/Server.php index f1e96170886..18ffc58dd15 100644 --- a/lib/private/Server.php +++ b/lib/private/Server.php @@ -846,11 +846,13 @@ class Server extends ServerContainer implements IServerContainer { $cacheFactory = $c->get(ICacheFactory::class); if ($cacheFactory->isAvailable()) { $backend = new \OC\Security\RateLimiting\Backend\MemoryCacheBackend( + $c->get(AllConfig::class), $this->get(ICacheFactory::class), new \OC\AppFramework\Utility\TimeFactory() ); } else { $backend = new \OC\Security\RateLimiting\Backend\DatabaseBackend( + $c->get(AllConfig::class), $c->get(IDBConnection::class), new \OC\AppFramework\Utility\TimeFactory() ); @@ -1199,16 +1201,10 @@ class Server extends ServerContainer implements IServerContainer { $this->registerAlias(\OC_Defaults::class, 'ThemingDefaults'); $this->registerService('ThemingDefaults', function (Server $c) { - /* - * Dark magic for autoloader. - * If we do a class_exists it will try to load the class which will - * make composer cache the result. Resulting in errors when enabling - * the theming app. - */ - $prefixes = \OC::$composerAutoloader->getPrefixesPsr4(); - if (isset($prefixes['OCA\\Theming\\'])) { - $classExists = true; - } else { + try { + $classExists = class_exists('OCA\Theming\ThemingDefaults'); + } catch (\OCP\AutoloadNotAllowedException $e) { + // App disabled or in maintenance mode $classExists = false; } |