mirror of
https://github.com/elyby/accounts.git
synced 2026-10-20 12:48:07 +05:30
65 lines
2.2 KiB
PHP
65 lines
2.2 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
|
|
namespace api\tests\functional;
|
|
|
|
use api\tests\FunctionalTester;
|
|
use Yii;
|
|
|
|
final class CaptchaCest {
|
|
|
|
public function _before(FunctionalTester $I): void {
|
|
$this->resetRateLimit();
|
|
}
|
|
|
|
/**
|
|
* The rate limit test exhausts the limit, which would break the next tests requesting challenges
|
|
*/
|
|
public function _after(FunctionalTester $I): void {
|
|
$this->resetRateLimit();
|
|
}
|
|
|
|
public function testAltchaChallenge(FunctionalTester $I): void {
|
|
$I->wantTo('get a new altcha challenge without authorization');
|
|
$I->sendGET('/api/captcha/altcha/challenge');
|
|
$I->canSeeResponseCodeIs(200);
|
|
$I->canSeeResponseIsJson();
|
|
$I->canSeeHttpHeader('Cache-Control', 'no-store');
|
|
$I->canSeeResponseContainsJson([
|
|
'parameters' => [
|
|
'algorithm' => 'PBKDF2/SHA-256',
|
|
],
|
|
]);
|
|
$I->canSeeResponseJsonMatchesJsonPath('$.signature');
|
|
$I->canSeeResponseJsonMatchesJsonPath('$.parameters.keySignature');
|
|
$I->canSeeResponseJsonMatchesJsonPath('$.parameters.expiresAt');
|
|
$firstSignature = $I->grabDataFromResponseByJsonPath('$.signature')[0];
|
|
|
|
$I->wantTo('get a different challenge on the next request');
|
|
$I->sendGET('/api/captcha/altcha/challenge');
|
|
$I->canSeeResponseCodeIs(200);
|
|
$I->assertNotSame($firstSignature, $I->grabDataFromResponseByJsonPath('$.signature')[0]);
|
|
}
|
|
|
|
public function testRateLimit(FunctionalTester $I): void {
|
|
$I->wantTo('get 429 after exceeding the per minute limit');
|
|
for ($i = 0; $i < 30; $i++) {
|
|
$I->sendGET('/api/captcha/altcha/challenge');
|
|
$I->canSeeResponseCodeIs(200);
|
|
}
|
|
|
|
$I->sendGET('/api/captcha/altcha/challenge');
|
|
$I->canSeeResponseCodeIs(429);
|
|
}
|
|
|
|
private function resetRateLimit(): void {
|
|
// Rate limiter counters live in Redis and would leak between the tests otherwise.
|
|
// KEYS is fine for the test Redis, but must never be used in the app code
|
|
$keys = Yii::$app->redis->keys('captcha:altcha:challenge:ratelimit:*');
|
|
if ($keys !== []) {
|
|
Yii::$app->redis->del(...$keys);
|
|
}
|
|
}
|
|
|
|
}
|