Signed-off-by: Lukas Reschke <lukas@statuscode.ch>tags/v23.0.0beta1
@@ -35,11 +35,11 @@ class Version23000Date20210906132259 extends SimpleMigrationStep { | |||
'notnull' => true, | |||
'length' => 128, | |||
]); | |||
$table->addColumn('timestamp', 'datetime', [ | |||
$table->addColumn('delete_after', 'datetime', [ | |||
'notnull' => true, | |||
]); | |||
$table->addIndex(['hash'], 'ratelimit_hash_idx'); | |||
$table->addIndex(['timestamp'], 'ratelimit_timestamp_idx'); | |||
$table->addIndex(['delete_after'], 'ratelimit_delete_after_idx'); | |||
} | |||
return $schema; |
@@ -6,10 +6,6 @@ $vendorDir = dirname(dirname(__FILE__)); | |||
$baseDir = dirname(dirname($vendorDir)); | |||
return array( | |||
'Bamarni\\Composer\\Bin\\BinCommand' => $vendorDir . '/bamarni/composer-bin-plugin/src/BinCommand.php', | |||
'Bamarni\\Composer\\Bin\\CommandProvider' => $vendorDir . '/bamarni/composer-bin-plugin/src/CommandProvider.php', | |||
'Bamarni\\Composer\\Bin\\Config' => $vendorDir . '/bamarni/composer-bin-plugin/src/Config.php', | |||
'Bamarni\\Composer\\Bin\\Plugin' => $vendorDir . '/bamarni/composer-bin-plugin/src/Plugin.php', | |||
'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php', | |||
'OCP\\Accounts\\IAccount' => $baseDir . '/lib/public/Accounts/IAccount.php', | |||
'OCP\\Accounts\\IAccountManager' => $baseDir . '/lib/public/Accounts/IAccountManager.php', | |||
@@ -973,7 +969,6 @@ return array( | |||
'OC\\Core\\Migrations\\Version21000Date20210309185126' => $baseDir . '/core/Migrations/Version21000Date20210309185126.php', | |||
'OC\\Core\\Migrations\\Version21000Date20210309185127' => $baseDir . '/core/Migrations/Version21000Date20210309185127.php', | |||
'OC\\Core\\Migrations\\Version22000Date20210216080825' => $baseDir . '/core/Migrations/Version22000Date20210216080825.php', | |||
'OC\\Core\\Migrations\\Version23000Date20210906132259' => $baseDir . '/core/Migrations/Version23000Date20210906132259.php', | |||
'OC\\Core\\Notification\\CoreNotifier' => $baseDir . '/core/Notification/CoreNotifier.php', | |||
'OC\\Core\\Service\\LoginFlowV2Service' => $baseDir . '/core/Service/LoginFlowV2Service.php', | |||
'OC\\DB\\Adapter' => $baseDir . '/lib/private/DB/Adapter.php', | |||
@@ -1370,7 +1365,6 @@ return array( | |||
'OC\\Security\\IdentityProof\\Manager' => $baseDir . '/lib/private/Security/IdentityProof/Manager.php', | |||
'OC\\Security\\IdentityProof\\Signer' => $baseDir . '/lib/private/Security/IdentityProof/Signer.php', | |||
'OC\\Security\\Normalizer\\IpAddress' => $baseDir . '/lib/private/Security/Normalizer/IpAddress.php', | |||
'OC\\Security\\RateLimiting\\Backend\\DatabaseBackend' => $baseDir . '/lib/private/Security/RateLimiting/Backend/DatabaseBackend.php', | |||
'OC\\Security\\RateLimiting\\Backend\\IBackend' => $baseDir . '/lib/private/Security/RateLimiting/Backend/IBackend.php', | |||
'OC\\Security\\RateLimiting\\Backend\\MemoryCache' => $baseDir . '/lib/private/Security/RateLimiting/Backend/MemoryCache.php', | |||
'OC\\Security\\RateLimiting\\Exception\\RateLimitExceededException' => $baseDir . '/lib/private/Security/RateLimiting/Exception/RateLimitExceededException.php', |
@@ -9,6 +9,5 @@ return array( | |||
'OC\\Core\\' => array($baseDir . '/core'), | |||
'OC\\' => array($baseDir . '/lib/private'), | |||
'OCP\\' => array($baseDir . '/lib/public'), | |||
'Bamarni\\Composer\\Bin\\' => array($vendorDir . '/bamarni/composer-bin-plugin/src'), | |||
'' => array($baseDir . '/lib/private/legacy'), | |||
); |
@@ -13,10 +13,6 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c | |||
'OC\\' => 3, | |||
'OCP\\' => 4, | |||
), | |||
'B' => | |||
array ( | |||
'Bamarni\\Composer\\Bin\\' => 21, | |||
), | |||
); | |||
public static $prefixDirsPsr4 = array ( | |||
@@ -32,10 +28,6 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c | |||
array ( | |||
0 => __DIR__ . '/../../..' . '/lib/public', | |||
), | |||
'Bamarni\\Composer\\Bin\\' => | |||
array ( | |||
0 => __DIR__ . '/..' . '/bamarni/composer-bin-plugin/src', | |||
), | |||
); | |||
public static $fallbackDirsPsr4 = array ( | |||
@@ -43,10 +35,6 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c | |||
); | |||
public static $classMap = array ( | |||
'Bamarni\\Composer\\Bin\\BinCommand' => __DIR__ . '/..' . '/bamarni/composer-bin-plugin/src/BinCommand.php', | |||
'Bamarni\\Composer\\Bin\\CommandProvider' => __DIR__ . '/..' . '/bamarni/composer-bin-plugin/src/CommandProvider.php', | |||
'Bamarni\\Composer\\Bin\\Config' => __DIR__ . '/..' . '/bamarni/composer-bin-plugin/src/Config.php', | |||
'Bamarni\\Composer\\Bin\\Plugin' => __DIR__ . '/..' . '/bamarni/composer-bin-plugin/src/Plugin.php', | |||
'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php', | |||
'OCP\\Accounts\\IAccount' => __DIR__ . '/../../..' . '/lib/public/Accounts/IAccount.php', | |||
'OCP\\Accounts\\IAccountManager' => __DIR__ . '/../../..' . '/lib/public/Accounts/IAccountManager.php', | |||
@@ -1010,7 +998,6 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c | |||
'OC\\Core\\Migrations\\Version21000Date20210309185126' => __DIR__ . '/../../..' . '/core/Migrations/Version21000Date20210309185126.php', | |||
'OC\\Core\\Migrations\\Version21000Date20210309185127' => __DIR__ . '/../../..' . '/core/Migrations/Version21000Date20210309185127.php', | |||
'OC\\Core\\Migrations\\Version22000Date20210216080825' => __DIR__ . '/../../..' . '/core/Migrations/Version22000Date20210216080825.php', | |||
'OC\\Core\\Migrations\\Version23000Date20210906132259' => __DIR__ . '/../../..' . '/core/Migrations/Version23000Date20210906132259.php', | |||
'OC\\Core\\Notification\\CoreNotifier' => __DIR__ . '/../../..' . '/core/Notification/CoreNotifier.php', | |||
'OC\\Core\\Service\\LoginFlowV2Service' => __DIR__ . '/../../..' . '/core/Service/LoginFlowV2Service.php', | |||
'OC\\DB\\Adapter' => __DIR__ . '/../../..' . '/lib/private/DB/Adapter.php', | |||
@@ -1407,7 +1394,6 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c | |||
'OC\\Security\\IdentityProof\\Manager' => __DIR__ . '/../../..' . '/lib/private/Security/IdentityProof/Manager.php', | |||
'OC\\Security\\IdentityProof\\Signer' => __DIR__ . '/../../..' . '/lib/private/Security/IdentityProof/Signer.php', | |||
'OC\\Security\\Normalizer\\IpAddress' => __DIR__ . '/../../..' . '/lib/private/Security/Normalizer/IpAddress.php', | |||
'OC\\Security\\RateLimiting\\Backend\\DatabaseBackend' => __DIR__ . '/../../..' . '/lib/private/Security/RateLimiting/Backend/DatabaseBackend.php', | |||
'OC\\Security\\RateLimiting\\Backend\\IBackend' => __DIR__ . '/../../..' . '/lib/private/Security/RateLimiting/Backend/IBackend.php', | |||
'OC\\Security\\RateLimiting\\Backend\\MemoryCache' => __DIR__ . '/../../..' . '/lib/private/Security/RateLimiting/Backend/MemoryCache.php', | |||
'OC\\Security\\RateLimiting\\Exception\\RateLimitExceededException' => __DIR__ . '/../../..' . '/lib/private/Security/RateLimiting/Exception/RateLimitExceededException.php', |
@@ -1,61 +1,5 @@ | |||
{ | |||
"packages": [ | |||
{ | |||
"name": "bamarni/composer-bin-plugin", | |||
"version": "1.4.1", | |||
"version_normalized": "1.4.1.0", | |||
"source": { | |||
"type": "git", | |||
"url": "https://github.com/bamarni/composer-bin-plugin.git", | |||
"reference": "9329fb0fbe29e0e1b2db8f4639a193e4f5406225" | |||
}, | |||
"dist": { | |||
"type": "zip", | |||
"url": "https://api.github.com/repos/bamarni/composer-bin-plugin/zipball/9329fb0fbe29e0e1b2db8f4639a193e4f5406225", | |||
"reference": "9329fb0fbe29e0e1b2db8f4639a193e4f5406225", | |||
"shasum": "" | |||
}, | |||
"require": { | |||
"composer-plugin-api": "^1.0 || ^2.0", | |||
"php": "^5.5.9 || ^7.0 || ^8.0" | |||
}, | |||
"require-dev": { | |||
"composer/composer": "^1.0 || ^2.0", | |||
"symfony/console": "^2.5 || ^3.0 || ^4.0" | |||
}, | |||
"time": "2020-05-03T08:27:20+00:00", | |||
"type": "composer-plugin", | |||
"extra": { | |||
"class": "Bamarni\\Composer\\Bin\\Plugin" | |||
}, | |||
"installation-source": "dist", | |||
"autoload": { | |||
"psr-4": { | |||
"Bamarni\\Composer\\Bin\\": "src" | |||
} | |||
}, | |||
"notification-url": "https://packagist.org/downloads/", | |||
"license": [ | |||
"MIT" | |||
], | |||
"description": "No conflicts for your bin dependencies", | |||
"keywords": [ | |||
"composer", | |||
"conflict", | |||
"dependency", | |||
"executable", | |||
"isolation", | |||
"tool" | |||
], | |||
"support": { | |||
"issues": "https://github.com/bamarni/composer-bin-plugin/issues", | |||
"source": "https://github.com/bamarni/composer-bin-plugin/tree/master" | |||
}, | |||
"install-path": "../bamarni/composer-bin-plugin" | |||
} | |||
], | |||
"dev": true, | |||
"dev-package-names": [ | |||
"bamarni/composer-bin-plugin" | |||
] | |||
"packages": [], | |||
"dev": false, | |||
"dev-package-names": [] | |||
} |
@@ -5,9 +5,9 @@ | |||
'type' => 'library', | |||
'install_path' => __DIR__ . '/../../../', | |||
'aliases' => array(), | |||
'reference' => '33a0b75c83a1c56fa84b98d3a07a26b5c4932b65', | |||
'reference' => '66144c300395458ff38b86e50cd92174443cd85e', | |||
'name' => '__root__', | |||
'dev' => true, | |||
'dev' => false, | |||
), | |||
'versions' => array( | |||
'__root__' => array( | |||
@@ -16,17 +16,8 @@ | |||
'type' => 'library', | |||
'install_path' => __DIR__ . '/../../../', | |||
'aliases' => array(), | |||
'reference' => '33a0b75c83a1c56fa84b98d3a07a26b5c4932b65', | |||
'reference' => '66144c300395458ff38b86e50cd92174443cd85e', | |||
'dev_requirement' => false, | |||
), | |||
'bamarni/composer-bin-plugin' => array( | |||
'pretty_version' => '1.4.1', | |||
'version' => '1.4.1.0', | |||
'type' => 'composer-plugin', | |||
'install_path' => __DIR__ . '/../bamarni/composer-bin-plugin', | |||
'aliases' => array(), | |||
'reference' => '9329fb0fbe29e0e1b2db8f4639a193e4f5406225', | |||
'dev_requirement' => true, | |||
), | |||
), | |||
); |
@@ -71,21 +71,28 @@ class DatabaseBackend implements IBackend { | |||
* @throws \OCP\DB\Exception | |||
*/ | |||
private function getExistingAttemptCount( | |||
string $identifier, | |||
int $seconds | |||
string $identifier | |||
): int { | |||
$currentTime = $this->timeFactory->getDateTime(); | |||
$qb = $this->dbConnection->getQueryBuilder(); | |||
$notOlderThan = $this->timeFactory->getDateTime()->sub(new \DateInterval("PT{$seconds}S")); | |||
$qb->delete(self::TABLE_NAME) | |||
->where( | |||
$qb->expr()->lte('delete_after', $qb->createParameter('currentTime')) | |||
) | |||
->setParameter('currentTime', $currentTime, 'datetime') | |||
->executeStatement(); | |||
$qb = $this->dbConnection->getQueryBuilder(); | |||
$qb->selectAlias($qb->createFunction('COUNT(*)'), 'count') | |||
->from(self::TABLE_NAME) | |||
->where( | |||
$qb->expr()->eq('hash', $qb->createNamedParameter($identifier, IQueryBuilder::PARAM_STR)) | |||
) | |||
->andWhere( | |||
$qb->expr()->gte('timestamp', $qb->createParameter('notOlderThan')) | |||
$qb->expr()->gte('delete_after', $qb->createParameter('currentTime')) | |||
) | |||
->setParameter('notOlderThan', $notOlderThan, 'datetime'); | |||
->setParameter('currentTime', $currentTime, 'datetime'); | |||
$cursor = $qb->executeQuery(); | |||
$row = $cursor->fetch(); | |||
@@ -98,10 +105,9 @@ class DatabaseBackend implements IBackend { | |||
* {@inheritDoc} | |||
*/ | |||
public function getAttempts(string $methodIdentifier, | |||
string $userIdentifier, | |||
int $seconds): int { | |||
string $userIdentifier): int { | |||
$identifier = $this->hash($methodIdentifier, $userIdentifier); | |||
return $this->getExistingAttemptCount($identifier, $seconds); | |||
return $this->getExistingAttemptCount($identifier); | |||
} | |||
/** | |||
@@ -111,25 +117,14 @@ class DatabaseBackend implements IBackend { | |||
string $userIdentifier, | |||
int $period) { | |||
$identifier = $this->hash($methodIdentifier, $userIdentifier); | |||
$currentTime = $this->timeFactory->getDateTime(); | |||
$notOlderThan = $this->timeFactory->getDateTime('@' . $period); | |||
$deleteAfter = $this->timeFactory->getDateTime()->add(new \DateInterval("PT{$period}S")); | |||
$qb = $this->dbConnection->getQueryBuilder(); | |||
$qb->delete(self::TABLE_NAME) | |||
->where( | |||
$qb->expr()->eq('hash', $qb->createNamedParameter($identifier, IQueryBuilder::PARAM_STR)) | |||
) | |||
->andWhere( | |||
$qb->expr()->lt('timestamp', $qb->createParameter('notOlderThan')) | |||
) | |||
->setParameter('notOlderThan', $notOlderThan, 'datetime') | |||
->executeStatement(); | |||
$qb->insert(self::TABLE_NAME) | |||
->values([ | |||
'hash' => $qb->createNamedParameter($identifier, IQueryBuilder::PARAM_STR), | |||
'timestamp' => $qb->createNamedParameter($currentTime, IQueryBuilder::PARAM_DATE), | |||
'delete_after' => $qb->createNamedParameter($deleteAfter, IQueryBuilder::PARAM_DATE), | |||
]) | |||
->executeStatement(); | |||
} |
@@ -35,16 +35,14 @@ namespace OC\Security\RateLimiting\Backend; | |||
*/ | |||
interface IBackend { | |||
/** | |||
* Gets the amount of attempts within the last specified seconds | |||
* Gets the amount of attempts for the specified method | |||
* | |||
* @param string $methodIdentifier Identifier for the method | |||
* @param string $userIdentifier Identifier for the user | |||
* @param int $seconds Seconds to look back at | |||
* @return int | |||
*/ | |||
public function getAttempts(string $methodIdentifier, | |||
string $userIdentifier, | |||
int $seconds): int; | |||
string $userIdentifier): int; | |||
/** | |||
* Registers an attempt |
@@ -33,12 +33,12 @@ use OCP\ICache; | |||
use OCP\ICacheFactory; | |||
/** | |||
* Class MemoryCache uses the configured distributed memory cache for storing | |||
* Class MemoryCacheBackend uses the configured distributed memory cache for storing | |||
* rate limiting data. | |||
* | |||
* @package OC\Security\RateLimiting\Backend | |||
*/ | |||
class MemoryCache implements IBackend { | |||
class MemoryCacheBackend implements IBackend { | |||
/** @var ICache */ | |||
private $cache; | |||
/** @var ITimeFactory */ | |||
@@ -86,16 +86,14 @@ class MemoryCache implements IBackend { | |||
* {@inheritDoc} | |||
*/ | |||
public function getAttempts(string $methodIdentifier, | |||
string $userIdentifier, | |||
int $seconds): int { | |||
string $userIdentifier): int { | |||
$identifier = $this->hash($methodIdentifier, $userIdentifier); | |||
$existingAttempts = $this->getExistingAttempts($identifier); | |||
$count = 0; | |||
$currentTime = $this->timeFactory->getTime(); | |||
/** @var array $existingAttempts */ | |||
foreach ($existingAttempts as $attempt) { | |||
if (($attempt + $seconds) > $currentTime) { | |||
foreach ($existingAttempts as $expirationTime) { | |||
if ($expirationTime > $currentTime) { | |||
$count++; | |||
} | |||
} | |||
@@ -113,16 +111,16 @@ class MemoryCache implements IBackend { | |||
$existingAttempts = $this->getExistingAttempts($identifier); | |||
$currentTime = $this->timeFactory->getTime(); | |||
// Unset all attempts older than $period | |||
foreach ($existingAttempts as $key => $attempt) { | |||
if (($attempt + $period) < $currentTime) { | |||
// Unset all attempts that are already expired | |||
foreach ($existingAttempts as $key => $expirationTime) { | |||
if ($expirationTime < $currentTime) { | |||
unset($existingAttempts[$key]); | |||
} | |||
} | |||
$existingAttempts = array_values($existingAttempts); | |||
// Store the new attempt | |||
$existingAttempts[] = (string)$currentTime; | |||
$existingAttempts[] = (string)($currentTime + $period); | |||
$this->cache->set($identifier, json_encode($existingAttempts)); | |||
} | |||
} |
@@ -35,17 +35,12 @@ use OCP\IUser; | |||
class Limiter { | |||
/** @var IBackend */ | |||
private $backend; | |||
/** @var ITimeFactory */ | |||
private $timeFactory; | |||
/** | |||
* @param ITimeFactory $timeFactory | |||
* @param IBackend $backend | |||
*/ | |||
public function __construct(ITimeFactory $timeFactory, | |||
IBackend $backend) { | |||
public function __construct(IBackend $backend) { | |||
$this->backend = $backend; | |||
$this->timeFactory = $timeFactory; | |||
} | |||
/** | |||
@@ -59,12 +54,12 @@ class Limiter { | |||
string $userIdentifier, | |||
int $period, | |||
int $limit): void { | |||
$existingAttempts = $this->backend->getAttempts($methodIdentifier, $userIdentifier, $period); | |||
$existingAttempts = $this->backend->getAttempts($methodIdentifier, $userIdentifier); | |||
if ($existingAttempts >= $limit) { | |||
throw new RateLimitExceededException(); | |||
} | |||
$this->backend->registerAttempt($methodIdentifier, $userIdentifier, $this->timeFactory->getTime()); | |||
$this->backend->registerAttempt($methodIdentifier, $userIdentifier, $period); | |||
} | |||
/** |
@@ -787,7 +787,7 @@ class Server extends ServerContainer implements IServerContainer { | |||
$this->registerService(\OC\Security\RateLimiting\Backend\IBackend::class, function ($c) { | |||
$cacheFactory = $c->get(ICacheFactory::class); | |||
if ($cacheFactory->isAvailable()) { | |||
$backend = new \OC\Security\RateLimiting\Backend\MemoryCache( | |||
$backend = new \OC\Security\RateLimiting\Backend\MemoryCacheBackend( | |||
$this->get(ICacheFactory::class), | |||
new \OC\AppFramework\Utility\TimeFactory() | |||
); |
@@ -24,20 +24,20 @@ declare(strict_types=1); | |||
namespace Test\Security\RateLimiting\Backend; | |||
use OC\Security\RateLimiting\Backend\MemoryCache; | |||
use OC\Security\RateLimiting\Backend\MemoryCacheBackend; | |||
use OCP\AppFramework\Utility\ITimeFactory; | |||
use OCP\ICache; | |||
use OCP\ICacheFactory; | |||
use Test\TestCase; | |||
class MemoryCacheTest extends TestCase { | |||
class MemoryCacheBackendTest extends TestCase { | |||
/** @var ICacheFactory|\PHPUnit\Framework\MockObject\MockObject */ | |||
private $cacheFactory; | |||
/** @var ITimeFactory|\PHPUnit\Framework\MockObject\MockObject */ | |||
private $timeFactory; | |||
/** @var ICache|\PHPUnit\Framework\MockObject\MockObject */ | |||
private $cache; | |||
/** @var MemoryCache */ | |||
/** @var MemoryCacheBackend */ | |||
private $memoryCache; | |||
protected function setUp(): void { | |||
@@ -50,10 +50,10 @@ class MemoryCacheTest extends TestCase { | |||
$this->cacheFactory | |||
->expects($this->once()) | |||
->method('createDistributed') | |||
->with('OC\Security\RateLimiting\Backend\MemoryCache') | |||
->with('OC\Security\RateLimiting\Backend\MemoryCacheBackend') | |||
->willReturn($this->cache); | |||
$this->memoryCache = new MemoryCache( | |||
$this->memoryCache = new MemoryCacheBackend( | |||
$this->cacheFactory, | |||
$this->timeFactory | |||
); | |||
@@ -66,7 +66,7 @@ class MemoryCacheTest extends TestCase { | |||
->with('eea460b8d756885099c7f0a4c083bf6a745069ee4a301984e726df58fd4510bffa2dac4b7fd5d835726a6753ffa8343ba31c7e902bbef78fc68c2e743667cb4b') | |||
->willReturn(null); | |||
$this->assertSame(0, $this->memoryCache->getAttempts('Method', 'User', 123)); | |||
$this->assertSame(0, $this->memoryCache->getAttempts('Method', 'User')); | |||
} | |||
public function testGetAttempts() { | |||
@@ -87,7 +87,7 @@ class MemoryCacheTest extends TestCase { | |||
'124', | |||
])); | |||
$this->assertSame(3, $this->memoryCache->getAttempts('Method', 'User', 123)); | |||
$this->assertSame(3, $this->memoryCache->getAttempts('Method', 'User')); | |||
} | |||
public function testRegisterAttemptWithNoAttemptsBefore() { |
@@ -26,13 +26,10 @@ namespace Test\Security\RateLimiting; | |||
use OC\Security\RateLimiting\Backend\IBackend; | |||
use OC\Security\RateLimiting\Limiter; | |||
use OCP\AppFramework\Utility\ITimeFactory; | |||
use OCP\IUser; | |||
use Test\TestCase; | |||
class LimiterTest extends TestCase { | |||
/** @var ITimeFactory|\PHPUnit\Framework\MockObject\MockObject */ | |||
private $timeFactory; | |||
/** @var IBackend|\PHPUnit\Framework\MockObject\MockObject */ | |||
private $backend; | |||
/** @var Limiter */ | |||
@@ -41,11 +38,9 @@ class LimiterTest extends TestCase { | |||
protected function setUp(): void { | |||
parent::setUp(); | |||
$this->timeFactory = $this->createMock(ITimeFactory::class); | |||
$this->backend = $this->createMock(IBackend::class); | |||
$this->limiter = new Limiter( | |||
$this->timeFactory, | |||
$this->backend | |||
); | |||
} | |||
@@ -69,10 +64,6 @@ class LimiterTest extends TestCase { | |||
} | |||
public function testRegisterAnonRequestSuccess() { | |||
$this->timeFactory | |||
->expects($this->once()) | |||
->method('getTime') | |||
->willReturn(2000); | |||
$this->backend | |||
->expects($this->once()) | |||
->method('getAttempts') | |||
@@ -126,10 +117,6 @@ class LimiterTest extends TestCase { | |||
->method('getUID') | |||
->willReturn('MyUid'); | |||
$this->timeFactory | |||
->expects($this->once()) | |||
->method('getTime') | |||
->willReturn(2000); | |||
$this->backend | |||
->expects($this->once()) | |||
->method('getAttempts') |