Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: delete old sessions with maintenance task #3324

Merged
merged 2 commits into from
Jun 7, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 2 additions & 2 deletions app/controllers/api/projects.php
Original file line number Diff line number Diff line change
Expand Up @@ -776,7 +776,7 @@
->param('projectId', null, new UID(), 'Project unique ID.')
->param('name', null, new Text(128), 'Key name. Max length: 128 chars.')
->param('scopes', null, new ArrayList(new WhiteList(array_keys(Config::getParam('scopes')), true), APP_LIMIT_ARRAY_PARAMS_SIZE), 'Key scopes list. Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' scopes are allowed.')
->param('expire', 0, new Integer() , 'Key expiration time in Unix timestamp. Use 0 for unlimited expiration.', true)
->param('expire', 0, new Integer(), 'Key expiration time in Unix timestamp. Use 0 for unlimited expiration.', true)
->inject('response')
->inject('dbForConsole')
->action(function (string $projectId, string $name, array $scopes, int $expire, Response $response, Database $dbForConsole) {
Expand Down Expand Up @@ -885,7 +885,7 @@
->param('keyId', null, new UID(), 'Key unique ID.')
->param('name', null, new Text(128), 'Key name. Max length: 128 chars.')
->param('scopes', null, new ArrayList(new WhiteList(array_keys(Config::getParam('scopes')), true), APP_LIMIT_ARRAY_PARAMS_SIZE), 'Key scopes list. Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' events are allowed.')
->param('expire', 0, new Integer() , 'Key expiration time in Unix timestamp. Use 0 for unlimited expiration.', true)
->param('expire', 0, new Integer(), 'Key expiration time in Unix timestamp. Use 0 for unlimited expiration.', true)
->inject('response')
->inject('dbForConsole')
->action(function (string $projectId, string $keyId, string $name, array $scopes, int $expire, Response $response, Database $dbForConsole) {
Expand Down
4 changes: 2 additions & 2 deletions app/controllers/general.php
Original file line number Diff line number Diff line change
Expand Up @@ -281,9 +281,9 @@

$expire = $key->getAttribute('expire', 0);

if(!empty($expire) && $expire < \time()){
if (!empty($expire) && $expire < \time()) {
throw new AppwriteException('Project key expired', 401, AppwriteException:: PROJECT_KEY_EXPIRED);
}
}

Authorization::setRole('role:' . Auth::USER_ROLE_APP);
Authorization::setDefaultStatus(false); // Cancel security segmentation for API keys.
Expand Down
1 change: 1 addition & 0 deletions app/init.php
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@
const DELETE_TYPE_USAGE = 'usage';
const DELETE_TYPE_REALTIME = 'realtime';
const DELETE_TYPE_BUCKETS = 'buckets';
const DELETE_TYPE_SESSIONS = 'sessions';
// Mail Types
const MAIL_TYPE_VERIFICATION = 'verification';
const MAIL_TYPE_MAGIC_SESSION = 'magicSession';
Expand Down
10 changes: 10 additions & 0 deletions app/tasks/maintenance.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
global $cli;
global $register;

use Appwrite\Auth\Auth;
use Appwrite\Event\Certificate;
use Appwrite\Event\Delete;
use Utopia\App;
Expand Down Expand Up @@ -93,6 +94,14 @@ function notifyDeleteConnections()
->trigger();
}

function notifyDeleteExpiredSessions()
{
(new Delete())
->setType(DELETE_TYPE_SESSIONS)
->setTimestamp(time() - Auth::TOKEN_EXPIRATION_LOGIN_LONG)
->trigger();
}

function renewCertificates($dbForConsole)
{
$time = date('d-m-Y H:i:s', time());
Expand Down Expand Up @@ -136,6 +145,7 @@ function renewCertificates($dbForConsole)
notifyDeleteAuditLogs($auditLogRetention);
notifyDeleteUsageStats($usageStatsRetention30m, $usageStatsRetention1d);
notifyDeleteConnections();
notifyDeleteExpiredSessions();
renewCertificates($database);
}, $interval);
});
18 changes: 18 additions & 0 deletions app/workers/deletes.php
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,10 @@ public function run(): void
$this->deleteRealtimeUsage($this->args['timestamp']);
break;

case DELETE_TYPE_SESSIONS:
$this->deleteExpiredSessions($this->args['timestamp']);
break;

case DELETE_TYPE_CERTIFICATES:
$document = new Document($this->args['document']);
$this->deleteCertificates($document);
Expand Down Expand Up @@ -250,6 +254,20 @@ protected function deleteExecutionLogs(int $timestamp): void
});
}

/**
* @param int $timestamp
*/
protected function deleteExpiredSessions(int $timestamp): void
{
$this->deleteForProjectIds(function (string $projectId) use ($timestamp) {
$dbForProject = $this->getProjectDB($projectId);
// Delete Sessions
$this->deleteByGroup('sessions', [
new Query('expire', Query::TYPE_LESSER, [$timestamp])
], $dbForProject);
});
}

/**
* @param int $timestamp
*/
Expand Down
13 changes: 6 additions & 7 deletions tests/e2e/Services/Projects/ProjectsConsoleClientTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1260,10 +1260,10 @@ public function testValidateProjectKey($data): void
], $this->getHeaders()), [
'name' => 'Key Test',
'scopes' => ['health.read'],
'expire' => time()+3600,
'expire' => time() + 3600,
]);

$response = $this->client->call(Client::METHOD_GET, '/health' , [
$response = $this->client->call(Client::METHOD_GET, '/health', [
'content-type' => 'application/json',
'x-appwrite-project' => $id,
'x-appwrite-key' => $response['body']['secret']
Expand All @@ -1283,7 +1283,7 @@ public function testValidateProjectKey($data): void
'expire' => 0,
]);

$response = $this->client->call(Client::METHOD_GET, '/health' , [
$response = $this->client->call(Client::METHOD_GET, '/health', [
'content-type' => 'application/json',
'x-appwrite-project' => $id,
'x-appwrite-key' => $response['body']['secret']
Expand All @@ -1300,17 +1300,16 @@ public function testValidateProjectKey($data): void
], $this->getHeaders()), [
'name' => 'Key Test',
'scopes' => ['health.read'],
'expire' => time()-3600,
'expire' => time() - 3600,
]);

$response = $this->client->call(Client::METHOD_GET, '/health' , [
$response = $this->client->call(Client::METHOD_GET, '/health', [
'content-type' => 'application/json',
'x-appwrite-project' => $id,
'x-appwrite-key' => $response['body']['secret']
], []);

$this->assertEquals(401, $response['headers']['status-code']);

}


Expand All @@ -1328,7 +1327,7 @@ public function testUpdateProjectKey($data): array
], $this->getHeaders()), [
'name' => 'Key Test Update',
'scopes' => ['users.read', 'users.write', 'collections.read'],
'expire' => time()+360,
'expire' => time() + 360,
]);

$this->assertEquals(200, $response['headers']['status-code']);
Expand Down