Добавлен функционал очистки устаревших 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\behaviors\TimestampBehavior;
use yii\db\ActiveQuery;
use yii\db\ActiveRecord;
/**
@ -22,32 +23,32 @@ use yii\db\ActiveRecord;
*/
class AccountSession extends ActiveRecord {
public static function tableName() {
public static function tableName(): string {
return '{{%accounts_sessions}}';
}
public function behaviors() {
public function behaviors(): array {
return [
[
'class' => TimestampBehavior::class,
'updatedAtAttribute' => 'last_refreshed_at',
]
],
];
}
public function getAccount() {
public function getAccount(): ActiveQuery {
return $this->hasOne(Account::class, ['id' => 'account_id']);
}
public function generateRefreshToken() {
public function generateRefreshToken(): void {
$this->refresh_token = Yii::$app->security->generateRandomString(96);
}
public function setIp($ip) {
public function setIp($ip): void {
$this->last_used_ip = ip2long($ip);
}
public function getReadableIp() {
public function getReadableIp(): string {
return long2ip($this->last_used_ip);
}

View File

@ -1,6 +1,7 @@
<?php
namespace console\controllers;
use common\models\AccountSession;
use common\models\EmailActivation;
use common\models\MinecraftAccessKey;
use yii\console\Controller;
@ -40,6 +41,28 @@ class CleanupController extends Controller {
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 {
$durationsMap = [];
foreach (EmailActivation::getClassMap() as $typeId => $className) {

View File

@ -1,3 +1,4 @@
# https://crontab.guru/every-day
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 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(),
'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
namespace codeception\console\unit\controllers;
use common\models\AccountSession;
use common\models\EmailActivation;
use common\models\MinecraftAccessKey;
use console\controllers\CleanupController;
use tests\codeception\common\fixtures\AccountSessionFixture;
use tests\codeception\common\fixtures\EmailActivationFixture;
use tests\codeception\common\fixtures\MinecraftAccessKeyFixture;
use tests\codeception\console\unit\TestCase;
@ -14,7 +16,8 @@ class CleanupControllerTest extends TestCase {
public function _fixtures() {
return [
'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]);
}
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());
}
}