Добавлен функционал очистки устаревших AccountSessions

This commit is contained in:
ErickSkrauch 2017-09-29 02:04:16 +03:00
parent ec0b25e88d
commit 22ed0942e8
5 changed files with 67 additions and 8 deletions

View File

@ -3,6 +3,7 @@ namespace common\models;
use Yii; use Yii;
use yii\behaviors\TimestampBehavior; use yii\behaviors\TimestampBehavior;
use yii\db\ActiveQuery;
use yii\db\ActiveRecord; use yii\db\ActiveRecord;
/** /**
@ -22,32 +23,32 @@ use yii\db\ActiveRecord;
*/ */
class AccountSession extends ActiveRecord { class AccountSession extends ActiveRecord {
public static function tableName() { public static function tableName(): string {
return '{{%accounts_sessions}}'; return '{{%accounts_sessions}}';
} }
public function behaviors() { public function behaviors(): array {
return [ return [
[ [
'class' => TimestampBehavior::class, 'class' => TimestampBehavior::class,
'updatedAtAttribute' => 'last_refreshed_at', 'updatedAtAttribute' => 'last_refreshed_at',
] ],
]; ];
} }
public function getAccount() { public function getAccount(): ActiveQuery {
return $this->hasOne(Account::class, ['id' => 'account_id']); return $this->hasOne(Account::class, ['id' => 'account_id']);
} }
public function generateRefreshToken() { public function generateRefreshToken(): void {
$this->refresh_token = Yii::$app->security->generateRandomString(96); $this->refresh_token = Yii::$app->security->generateRandomString(96);
} }
public function setIp($ip) { public function setIp($ip): void {
$this->last_used_ip = ip2long($ip); $this->last_used_ip = ip2long($ip);
} }
public function getReadableIp() { public function getReadableIp(): string {
return long2ip($this->last_used_ip); return long2ip($this->last_used_ip);
} }

View File

@ -1,6 +1,7 @@
<?php <?php
namespace console\controllers; namespace console\controllers;
use common\models\AccountSession;
use common\models\EmailActivation; use common\models\EmailActivation;
use common\models\MinecraftAccessKey; use common\models\MinecraftAccessKey;
use yii\console\Controller; use yii\console\Controller;
@ -40,6 +41,28 @@ class CleanupController extends Controller {
return self::EXIT_CODE_NORMAL; return self::EXIT_CODE_NORMAL;
} }
/**
* Нужно удалить те сессии, которые не рефрешились 90 дней,
* а также сессии, которые ни разу не рефрешились с момента своей выписки
* более чем 2 недели назад.
*
* У модели AccountSession нет внешних связей, так что целевые записи
* могут быть удалены без использования циклов.
*/
public function actionWebSessions() {
AccountSession::deleteAll([
'OR',
['<', 'last_refreshed_at', time() - 7776000], // 90 days
[
'AND',
'created_at = last_refreshed_at',
['<', 'created_at', time() - 1209600], // 2 weeks
],
]);
return self::EXIT_CODE_NORMAL;
}
private function getEmailActivationsDurationsMap(): array { private function getEmailActivationsDurationsMap(): array {
$durationsMap = []; $durationsMap = [];
foreach (EmailActivation::getClassMap() as $typeId => $className) { foreach (EmailActivation::getClassMap() as $typeId => $className) {

View File

@ -1,3 +1,4 @@
# https://crontab.guru/every-day # https://crontab.guru/every-day
0 0 * * * root /usr/local/bin/php /var/www/html/yii cleanup/email-keys >/dev/null 2>&1 0 0 * * * root /usr/local/bin/php /var/www/html/yii cleanup/email-keys >/dev/null 2>&1
0 1 * * * root /usr/local/bin/php /var/www/html/yii cleanup/minecraft-sessions >/dev/null 2>&1 0 1 * * * root /usr/local/bin/php /var/www/html/yii cleanup/minecraft-sessions >/dev/null 2>&1
0 2 * * * root /usr/local/bin/php /var/www/html/yii cleanup/web-sessions >/dev/null 2>&1

View File

@ -24,4 +24,20 @@ return [
'created_at' => time(), 'created_at' => time(),
'last_refreshed_at' => time(), 'last_refreshed_at' => time(),
], ],
'very-expired-session' => [
'id' => 4,
'account_id' => 1,
'refresh_token' => 'dkzIbUdtVLU3LOotSofUU0BQTvClMqmiIGwVKz2VHXOENifj',
'last_used_ip' => ip2long('127.0.0.1'),
'created_at' => 1477414260,
'last_refreshed_at' => 1480092660,
],
'not-refreshed-session' => [
'id' => 5,
'account_id' => 1,
'refresh_token' => 'NM9g7fZyn1o3F87BkDtRCQaHLuudDxyuup3ttyDRIjmwPPJx',
'last_used_ip' => ip2long('127.0.0.1'),
'created_at' => time() - 1814400, // 3 weeks
'last_refreshed_at' => time() - 1814400, // 3 weeks
],
]; ];

View File

@ -1,9 +1,11 @@
<?php <?php
namespace codeception\console\unit\controllers; namespace codeception\console\unit\controllers;
use common\models\AccountSession;
use common\models\EmailActivation; use common\models\EmailActivation;
use common\models\MinecraftAccessKey; use common\models\MinecraftAccessKey;
use console\controllers\CleanupController; use console\controllers\CleanupController;
use tests\codeception\common\fixtures\AccountSessionFixture;
use tests\codeception\common\fixtures\EmailActivationFixture; use tests\codeception\common\fixtures\EmailActivationFixture;
use tests\codeception\common\fixtures\MinecraftAccessKeyFixture; use tests\codeception\common\fixtures\MinecraftAccessKeyFixture;
use tests\codeception\console\unit\TestCase; use tests\codeception\console\unit\TestCase;
@ -14,7 +16,8 @@ class CleanupControllerTest extends TestCase {
public function _fixtures() { public function _fixtures() {
return [ return [
'emailActivations' => EmailActivationFixture::class, 'emailActivations' => EmailActivationFixture::class,
'minecraftSessions' => MinecraftAccessKeyFixture::class 'minecraftSessions' => MinecraftAccessKeyFixture::class,
'accountsSessions' => AccountSessionFixture::class,
]; ];
} }
@ -38,4 +41,19 @@ class CleanupControllerTest extends TestCase {
$this->tester->cantSeeRecord(MinecraftAccessKey::class, ['access_token' => $expiredSession->access_token]); $this->tester->cantSeeRecord(MinecraftAccessKey::class, ['access_token' => $expiredSession->access_token]);
} }
public function testActionWebSessions() {
/** @var AccountSession $expiredSession */
$expiredSession = $this->tester->grabFixture('accountsSessions', 'very-expired-session');
/** @var AccountSession $notRefreshedSession */
$notRefreshedSession = $this->tester->grabFixture('accountsSessions', 'not-refreshed-session');
$totalSessionsCount = AccountSession::find()->count();
$controller = new CleanupController('cleanup', Yii::$app);
$this->assertEquals(0, $controller->actionWebSessions());
$this->tester->cantSeeRecord(AccountSession::class, ['id' => $expiredSession->id]);
$this->tester->cantSeeRecord(AccountSession::class, ['id' => $notRefreshedSession->id]);
$this->assertEquals($totalSessionsCount - 2, AccountSession::find()->count());
}
} }