Merge pull request #9121 from appwrite/migrate-to-redis-abuse

chore: use redis adapter for abuse
This commit is contained in:
Christy Jacob 2024-12-20 22:26:28 +05:30 committed by GitHub
commit ef032a7af0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 152 additions and 106 deletions

View file

@ -24,7 +24,6 @@ use Appwrite\Utopia\Response\Model\Rule;
use Executor\Executor; use Executor\Executor;
use MaxMind\Db\Reader; use MaxMind\Db\Reader;
use Utopia\Abuse\Abuse; use Utopia\Abuse\Abuse;
use Utopia\Abuse\Adapters\Database\TimeLimit;
use Utopia\App; use Utopia\App;
use Utopia\CLI\Console; use Utopia\CLI\Console;
use Utopia\Config\Config; use Utopia\Config\Config;
@ -180,22 +179,23 @@ App::post('/v1/functions')
->inject('request') ->inject('request')
->inject('response') ->inject('response')
->inject('dbForProject') ->inject('dbForProject')
->inject('timelimit')
->inject('project') ->inject('project')
->inject('user') ->inject('user')
->inject('queueForEvents') ->inject('queueForEvents')
->inject('queueForBuilds') ->inject('queueForBuilds')
->inject('dbForPlatform') ->inject('dbForPlatform')
->inject('gitHub') ->inject('gitHub')
->action(function (string $functionId, string $name, string $runtime, array $execute, array $events, string $schedule, int $timeout, bool $enabled, bool $logging, string $entrypoint, string $commands, array $scopes, string $installationId, string $providerRepositoryId, string $providerBranch, bool $providerSilentMode, string $providerRootDirectory, string $templateRepository, string $templateOwner, string $templateRootDirectory, string $templateVersion, string $specification, Request $request, Response $response, Database $dbForProject, Document $project, Document $user, Event $queueForEvents, Build $queueForBuilds, Database $dbForPlatform, GitHub $github) use ($redeployVcs) { ->action(function (string $functionId, string $name, string $runtime, array $execute, array $events, string $schedule, int $timeout, bool $enabled, bool $logging, string $entrypoint, string $commands, array $scopes, string $installationId, string $providerRepositoryId, string $providerBranch, bool $providerSilentMode, string $providerRootDirectory, string $templateRepository, string $templateOwner, string $templateRootDirectory, string $templateVersion, string $specification, Request $request, Response $response, Database $dbForProject, callable $timelimit, Document $project, Document $user, Event $queueForEvents, Build $queueForBuilds, Database $dbForPlatform, GitHub $github) use ($redeployVcs) {
$functionId = ($functionId == 'unique()') ? ID::unique() : $functionId; $functionId = ($functionId == 'unique()') ? ID::unique() : $functionId;
// Temporary abuse check // Temporary abuse check
$abuseCheck = function () use ($project, $dbForProject, $response) { $abuseCheck = function () use ($project, $timelimit, $response) {
$abuseKey = "projectId:{projectId},url:{url}"; $abuseKey = "projectId:{projectId},url:{url}";
$abuseLimit = App::getEnv('_APP_FUNCTIONS_CREATION_ABUSE_LIMIT', 50); $abuseLimit = App::getEnv('_APP_FUNCTIONS_CREATION_ABUSE_LIMIT', 50);
$abuseTime = 86400; // 1 day $abuseTime = 86400; // 1 day
$timeLimit = new TimeLimit($abuseKey, $abuseLimit, $abuseTime, $dbForProject); $timeLimit = $timelimit($abuseKey, $abuseLimit, $abuseTime);
$timeLimit $timeLimit
->setParam('{projectId}', $project->getId()) ->setParam('{projectId}', $project->getId())
->setParam('{url}', '/v1/functions'); ->setParam('{url}', '/v1/functions');
@ -203,7 +203,7 @@ App::post('/v1/functions')
$abuse = new Abuse($timeLimit); $abuse = new Abuse($timeLimit);
$remaining = $timeLimit->remaining(); $remaining = $timeLimit->remaining();
$limit = $timeLimit->limit(); $limit = $timeLimit->limit();
$time = (new \DateTime($timeLimit->time()))->getTimestamp() + $abuseTime; $time = $timeLimit->time() + $abuseTime;
$response $response
->addHeader('X-RateLimit-Limit', $limit) ->addHeader('X-RateLimit-Limit', $limit)

View file

@ -16,7 +16,6 @@ use Appwrite\Utopia\Database\Validator\Queries\Projects;
use Appwrite\Utopia\Request; use Appwrite\Utopia\Request;
use Appwrite\Utopia\Response; use Appwrite\Utopia\Response;
use PHPMailer\PHPMailer\PHPMailer; use PHPMailer\PHPMailer\PHPMailer;
use Utopia\Abuse\Adapters\Database\TimeLimit;
use Utopia\App; use Utopia\App;
use Utopia\Audit\Audit; use Utopia\Audit\Audit;
use Utopia\Cache\Cache; use Utopia\Cache\Cache;
@ -229,9 +228,6 @@ App::post('/v1/projects')
if ($create || $projectTables) { if ($create || $projectTables) {
$audit = new Audit($dbForProject); $audit = new Audit($dbForProject);
$audit->setup(); $audit->setup();
$abuse = new TimeLimit('', 0, 1, $dbForProject);
$abuse->setup();
} }
if (!$create && $sharedTablesV1) { if (!$create && $sharedTablesV1) {
@ -245,17 +241,6 @@ App::post('/v1/projects')
'indexes' => $indexes, 'indexes' => $indexes,
'documentSecurity' => true 'documentSecurity' => true
])); ]));
$attributes = \array_map(fn ($attribute) => new Document($attribute), TimeLimit::ATTRIBUTES);
$indexes = \array_map(fn (array $index) => new Document($index), TimeLimit::INDEXES);
$dbForProject->createDocument(Database::METADATA, new Document([
'$id' => ID::custom('abuse'),
'$permissions' => [Permission::create(Role::any())],
'name' => 'abuse',
'attributes' => $attributes,
'indexes' => $indexes,
'documentSecurity' => true
]));
} }
if ($create || $sharedTablesV1) { if ($create || $sharedTablesV1) {

View file

@ -19,7 +19,6 @@ use Appwrite\Extend\Exception as AppwriteException;
use Appwrite\Utopia\Request; use Appwrite\Utopia\Request;
use Appwrite\Utopia\Response; use Appwrite\Utopia\Response;
use Utopia\Abuse\Abuse; use Utopia\Abuse\Abuse;
use Utopia\Abuse\Adapters\Database\TimeLimit;
use Utopia\App; use Utopia\App;
use Utopia\Cache\Adapter\Filesystem; use Utopia\Cache\Adapter\Filesystem;
use Utopia\Cache\Cache; use Utopia\Cache\Cache;
@ -420,8 +419,9 @@ App::init()
->inject('queueForBuilds') ->inject('queueForBuilds')
->inject('queueForUsage') ->inject('queueForUsage')
->inject('dbForProject') ->inject('dbForProject')
->inject('timelimit')
->inject('mode') ->inject('mode')
->action(function (App $utopia, Request $request, Response $response, Document $project, Document $user, Connection $queue, Event $queueForEvents, Messaging $queueForMessaging, Audit $queueForAudits, Delete $queueForDeletes, EventDatabase $queueForDatabase, Build $queueForBuilds, Usage $queueForUsage, Database $dbForProject, string $mode) use ($usageDatabaseListener, $eventDatabaseListener) { ->action(function (App $utopia, Request $request, Response $response, Document $project, Document $user, Connection $queue, Event $queueForEvents, Messaging $queueForMessaging, Audit $queueForAudits, Delete $queueForDeletes, EventDatabase $queueForDatabase, Build $queueForBuilds, Usage $queueForUsage, Database $dbForProject, callable $timelimit, string $mode) use ($usageDatabaseListener, $eventDatabaseListener) {
$route = $utopia->getRoute(); $route = $utopia->getRoute();
@ -444,7 +444,7 @@ App::init()
foreach ($abuseKeyLabel as $abuseKey) { foreach ($abuseKeyLabel as $abuseKey) {
$start = $request->getContentRangeStart(); $start = $request->getContentRangeStart();
$end = $request->getContentRangeEnd(); $end = $request->getContentRangeEnd();
$timeLimit = new TimeLimit($abuseKey, $route->getLabel('abuse-limit', 0), $route->getLabel('abuse-time', 3600), $dbForProject); $timeLimit = $timelimit($abuseKey, $route->getLabel('abuse-limit', 0), $route->getLabel('abuse-time', 3600));
$timeLimit $timeLimit
->setParam('{projectId}', $project->getId()) ->setParam('{projectId}', $project->getId())
->setParam('{userId}', $user->getId()) ->setParam('{userId}', $user->getId())
@ -472,7 +472,7 @@ App::init()
$abuse = new Abuse($timeLimit); $abuse = new Abuse($timeLimit);
$remaining = $timeLimit->remaining(); $remaining = $timeLimit->remaining();
$limit = $timeLimit->limit(); $limit = $timeLimit->limit();
$time = (new \DateTime($timeLimit->time()))->getTimestamp() + $route->getLabel('abuse-time', 3600); $time = $timeLimit->time() + $route->getLabel('abuse-time', 3600);
if ($limit && ($remaining < $closestLimit || is_null($closestLimit))) { if ($limit && ($remaining < $closestLimit || is_null($closestLimit))) {
$closestLimit = $remaining; $closestLimit = $remaining;

View file

@ -10,10 +10,8 @@ use Swoole\Http\Response as SwooleResponse;
use Swoole\Http\Server; use Swoole\Http\Server;
use Swoole\Process; use Swoole\Process;
use Swoole\Table; use Swoole\Table;
use Utopia\Abuse\Adapters\Database\TimeLimit;
use Utopia\App; use Utopia\App;
use Utopia\Audit\Audit; use Utopia\Audit\Audit;
use Utopia\Cache\Cache;
use Utopia\CLI\Console; use Utopia\CLI\Console;
use Utopia\Config\Config; use Utopia\Config\Config;
use Utopia\Database\Database; use Utopia\Database\Database;
@ -200,11 +198,6 @@ $http->on(Constant::EVENT_START, function (Server $http) use ($payloadSize, $reg
$audit->setup(); $audit->setup();
} }
if ($dbForPlatform->getCollection(TimeLimit::COLLECTION)->isEmpty()) {
$adapter = new TimeLimit("", 0, 1, $dbForPlatform);
$adapter->setup();
}
/** @var array $collections */ /** @var array $collections */
$collections = Config::getParam('collections', []); $collections = Config::getParam('collections', []);
$consoleCollections = $collections['console']; $consoleCollections = $collections['console'];

View file

@ -48,6 +48,7 @@ use Appwrite\Utopia\Request;
use MaxMind\Db\Reader; use MaxMind\Db\Reader;
use PHPMailer\PHPMailer\PHPMailer; use PHPMailer\PHPMailer\PHPMailer;
use Swoole\Database\PDOProxy; use Swoole\Database\PDOProxy;
use Utopia\Abuse\Adapters\TimeLimit\Redis as TimeLimitRedis;
use Utopia\App; use Utopia\App;
use Utopia\Cache\Adapter\Redis as RedisCache; use Utopia\Cache\Adapter\Redis as RedisCache;
use Utopia\Cache\Adapter\Sharding; use Utopia\Cache\Adapter\Sharding;
@ -853,31 +854,31 @@ $register->set('pools', function () {
$connections = [ $connections = [
'console' => [ 'console' => [
'type' => 'database', 'type' => 'database',
'dsns' => System::getEnv('_APP_CONNECTIONS_DB_CONSOLE', $fallbackForDB), 'dsns' => $fallbackForDB,
'multiple' => false, 'multiple' => false,
'schemes' => ['mariadb', 'mysql'], 'schemes' => ['mariadb', 'mysql'],
], ],
'database' => [ 'database' => [
'type' => 'database', 'type' => 'database',
'dsns' => System::getEnv('_APP_CONNECTIONS_DB_PROJECT', $fallbackForDB), 'dsns' => $fallbackForDB,
'multiple' => true, 'multiple' => true,
'schemes' => ['mariadb', 'mysql'], 'schemes' => ['mariadb', 'mysql'],
], ],
'queue' => [ 'queue' => [
'type' => 'queue', 'type' => 'queue',
'dsns' => System::getEnv('_APP_CONNECTIONS_QUEUE', $fallbackForRedis), 'dsns' => $fallbackForRedis,
'multiple' => false, 'multiple' => false,
'schemes' => ['redis'], 'schemes' => ['redis'],
], ],
'pubsub' => [ 'pubsub' => [
'type' => 'pubsub', 'type' => 'pubsub',
'dsns' => System::getEnv('_APP_CONNECTIONS_PUBSUB', $fallbackForRedis), 'dsns' => $fallbackForRedis,
'multiple' => false, 'multiple' => false,
'schemes' => ['redis'], 'schemes' => ['redis'],
], ],
'cache' => [ 'cache' => [
'type' => 'cache', 'type' => 'cache',
'dsns' => System::getEnv('_APP_CONNECTIONS_CACHE', $fallbackForRedis), 'dsns' => $fallbackForRedis,
'multiple' => true, 'multiple' => true,
'schemes' => ['redis'], 'schemes' => ['redis'],
], ],
@ -949,12 +950,12 @@ $register->set('pools', function () {
}); });
}, },
'redis' => function () use ($dsnHost, $dsnPort, $dsnPass) { 'redis' => function () use ($dsnHost, $dsnPort, $dsnPass) {
$redis = new Redis(); $redis = new \Redis();
@$redis->pconnect($dsnHost, (int)$dsnPort); @$redis->pconnect($dsnHost, (int)$dsnPort);
if ($dsnPass) { if ($dsnPass) {
$redis->auth($dsnPass); $redis->auth($dsnPass);
} }
$redis->setOption(Redis::OPT_READ_TIMEOUT, -1); $redis->setOption(\Redis::OPT_READ_TIMEOUT, -1);
return $redis; return $redis;
}, },
@ -1531,6 +1532,27 @@ App::setResource('cache', function (Group $pools) {
return new Cache(new Sharding($adapters)); return new Cache(new Sharding($adapters));
}, ['pools']); }, ['pools']);
App::setResource('redis', function () {
$host = System::getEnv('_APP_REDIS_HOST', 'localhost');
$port = System::getEnv('_APP_REDIS_PORT', 6379);
$pass = System::getEnv('_APP_REDIS_PASS', '');
$redis = new \Redis();
@$redis->pconnect($host, (int)$port);
if ($pass) {
$redis->auth($pass);
}
$redis->setOption(\Redis::OPT_READ_TIMEOUT, -1);
return $redis;
});
App::setResource('timelimit', function (\Redis $redis) {
return function (string $key, int $limit, int $time) use ($redis) {
return new TimeLimitRedis($key, $limit, $time, $redis);
};
}, ['redis']);
App::setResource('deviceForLocal', function () { App::setResource('deviceForLocal', function () {
return new Local(); return new Local();
}); });

View file

@ -13,7 +13,7 @@ use Swoole\Runtime;
use Swoole\Table; use Swoole\Table;
use Swoole\Timer; use Swoole\Timer;
use Utopia\Abuse\Abuse; use Utopia\Abuse\Abuse;
use Utopia\Abuse\Adapters\Database\TimeLimit; use Utopia\Abuse\Adapters\TimeLimit\Redis as TimeLimitRedis;
use Utopia\App; use Utopia\App;
use Utopia\Cache\Adapter\Sharding; use Utopia\Cache\Adapter\Sharding;
use Utopia\Cache\Cache; use Utopia\Cache\Cache;
@ -138,6 +138,32 @@ if (!function_exists('getCache')) {
} }
} }
// Allows overriding
if (!function_exists('getRedis')) {
function getRedis(): \Redis
{
$host = System::getEnv('_APP_REDIS_HOST', 'localhost');
$port = System::getEnv('_APP_REDIS_PORT', 6379);
$pass = System::getEnv('_APP_REDIS_PASS', '');
$redis = new \Redis();
@$redis->pconnect($host, (int)$port);
if ($pass) {
$redis->auth($pass);
}
$redis->setOption(\Redis::OPT_READ_TIMEOUT, -1);
return $redis;
}
}
if (!function_exists('getTimelimit')) {
function getTimelimit(): TimeLimitRedis
{
return new TimeLimitRedis("", 0, 1, getRedis());
}
}
if (!function_exists('getRealtime')) { if (!function_exists('getRealtime')) {
function getRealtime(): Realtime function getRealtime(): Realtime
{ {
@ -481,7 +507,7 @@ $server->onOpen(function (int $connection, SwooleRequest $request) use ($server,
throw new AppwriteException(AppwriteException::GENERAL_API_DISABLED); throw new AppwriteException(AppwriteException::GENERAL_API_DISABLED);
} }
$dbForProject = getProjectDB($project); $timelimit = $app->getResource('timelimit');
$console = $app->getResource('console'); /** @var Document $console */ $console = $app->getResource('console'); /** @var Document $console */
$user = $app->getResource('user'); /** @var Document $user */ $user = $app->getResource('user'); /** @var Document $user */
@ -490,12 +516,12 @@ $server->onOpen(function (int $connection, SwooleRequest $request) use ($server,
* *
* Abuse limits are connecting 128 times per minute and ip address. * Abuse limits are connecting 128 times per minute and ip address.
*/ */
$timeLimit = new TimeLimit('url:{url},ip:{ip}', 128, 60, $dbForProject); $timelimit = $timelimit('url:{url},ip:{ip}', 128, 60);
$timeLimit $timelimit
->setParam('{ip}', $request->getIP()) ->setParam('{ip}', $request->getIP())
->setParam('{url}', $request->getURI()); ->setParam('{url}', $request->getURI());
$abuse = new Abuse($timeLimit); $abuse = new Abuse($timelimit);
if (System::getEnv('_APP_OPTIONS_ABUSE', 'enabled') === 'enabled' && $abuse->check()) { if (System::getEnv('_APP_OPTIONS_ABUSE', 'enabled') === 'enabled' && $abuse->check()) {
throw new Exception(Exception::REALTIME_TOO_MANY_MESSAGES, 'Too many requests'); throw new Exception(Exception::REALTIME_TOO_MANY_MESSAGES, 'Too many requests');
@ -593,7 +619,7 @@ $server->onMessage(function (int $connection, string $message) use ($server, $re
* *
* Abuse limits are sending 32 times per minute and connection. * Abuse limits are sending 32 times per minute and connection.
*/ */
$timeLimit = new TimeLimit('url:{url},connection:{connection}', 32, 60, $database); $timeLimit = getTimelimit('url:{url},connection:{connection}', 32, 60);
$timeLimit $timeLimit
->setParam('{connection}', $connection) ->setParam('{connection}', $connection)

View file

@ -17,6 +17,7 @@ use Appwrite\Event\Usage;
use Appwrite\Event\UsageDump; use Appwrite\Event\UsageDump;
use Appwrite\Platform\Appwrite; use Appwrite\Platform\Appwrite;
use Swoole\Runtime; use Swoole\Runtime;
use Utopia\Abuse\Adapters\TimeLimit\Redis as TimeLimitRedis;
use Utopia\Cache\Adapter\Sharding; use Utopia\Cache\Adapter\Sharding;
use Utopia\Cache\Cache; use Utopia\Cache\Cache;
use Utopia\CLI\Console; use Utopia\CLI\Console;
@ -200,6 +201,27 @@ Server::setResource('cache', function (Registry $register) {
return new Cache(new Sharding($adapters)); return new Cache(new Sharding($adapters));
}, ['register']); }, ['register']);
Server::setResource('redis', function () {
$host = System::getEnv('_APP_REDIS_HOST', 'localhost');
$port = System::getEnv('_APP_REDIS_PORT', 6379);
$pass = System::getEnv('_APP_REDIS_PASS', '');
$redis = new \Redis();
@$redis->pconnect($host, (int)$port);
if ($pass) {
$redis->auth($pass);
}
$redis->setOption(\Redis::OPT_READ_TIMEOUT, -1);
return $redis;
});
Server::setResource('timelimit', function (\Redis $redis) {
return function (string $key, int $limit, int $time) use ($redis) {
return new TimeLimitRedis($key, $limit, $time, $redis);
};
}, ['redis']);
Server::setResource('log', fn () => new Log()); Server::setResource('log', fn () => new Log());
Server::setResource('queueForUsage', function (Connection $queue) { Server::setResource('queueForUsage', function (Connection $queue) {

View file

@ -45,7 +45,7 @@
"ext-sockets": "*", "ext-sockets": "*",
"appwrite/php-runtimes": "0.16.*", "appwrite/php-runtimes": "0.16.*",
"appwrite/php-clamav": "2.0.*", "appwrite/php-clamav": "2.0.*",
"utopia-php/abuse": "0.43.*", "utopia-php/abuse": "0.45.*",
"utopia-php/analytics": "0.10.*", "utopia-php/analytics": "0.10.*",
"utopia-php/audit": "0.43.*", "utopia-php/audit": "0.43.*",
"utopia-php/cache": "0.11.*", "utopia-php/cache": "0.11.*",

102
composer.lock generated
View file

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "fae350df93342992edd8f639948e1570", "content-hash": "db3b63ba1be2561ee4a112e5b9c6bd53",
"packages": [ "packages": [
{ {
"name": "adhocore/jwt", "name": "adhocore/jwt",
@ -709,16 +709,16 @@
}, },
{ {
"name": "google/protobuf", "name": "google/protobuf",
"version": "v4.29.1", "version": "v4.29.2",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/protocolbuffers/protobuf-php.git", "url": "https://github.com/protocolbuffers/protobuf-php.git",
"reference": "6042b5483f8029e42473faeb8ef75ba266278381" "reference": "79aa5014efeeec3d137df5cdb0ae2fc163953945"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/protocolbuffers/protobuf-php/zipball/6042b5483f8029e42473faeb8ef75ba266278381", "url": "https://api.github.com/repos/protocolbuffers/protobuf-php/zipball/79aa5014efeeec3d137df5cdb0ae2fc163953945",
"reference": "6042b5483f8029e42473faeb8ef75ba266278381", "reference": "79aa5014efeeec3d137df5cdb0ae2fc163953945",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -747,9 +747,9 @@
"proto" "proto"
], ],
"support": { "support": {
"source": "https://github.com/protocolbuffers/protobuf-php/tree/v4.29.1" "source": "https://github.com/protocolbuffers/protobuf-php/tree/v4.29.2"
}, },
"time": "2024-12-03T22:07:45+00:00" "time": "2024-12-18T14:11:12+00:00"
}, },
{ {
"name": "jean85/pretty-package-versions", "name": "jean85/pretty-package-versions",
@ -1237,16 +1237,16 @@
}, },
{ {
"name": "open-telemetry/api", "name": "open-telemetry/api",
"version": "1.1.1", "version": "1.1.2",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/opentelemetry-php/api.git", "url": "https://github.com/opentelemetry-php/api.git",
"reference": "542064815d38a6df55af7957cd6f1d7d967c99c6" "reference": "04c85a1e41a3d59fa9bdc801a5de1df6624b95ed"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/opentelemetry-php/api/zipball/542064815d38a6df55af7957cd6f1d7d967c99c6", "url": "https://api.github.com/repos/opentelemetry-php/api/zipball/04c85a1e41a3d59fa9bdc801a5de1df6624b95ed",
"reference": "542064815d38a6df55af7957cd6f1d7d967c99c6", "reference": "04c85a1e41a3d59fa9bdc801a5de1df6624b95ed",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -1260,13 +1260,13 @@
}, },
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": {
"dev-main": "1.1.x-dev"
},
"spi": { "spi": {
"OpenTelemetry\\API\\Instrumentation\\AutoInstrumentation\\HookManagerInterface": [ "OpenTelemetry\\API\\Instrumentation\\AutoInstrumentation\\HookManagerInterface": [
"OpenTelemetry\\API\\Instrumentation\\AutoInstrumentation\\ExtensionHookManager" "OpenTelemetry\\API\\Instrumentation\\AutoInstrumentation\\ExtensionHookManager"
] ]
},
"branch-alias": {
"dev-main": "1.1.x-dev"
} }
}, },
"autoload": { "autoload": {
@ -1303,7 +1303,7 @@
"issues": "https://github.com/open-telemetry/opentelemetry-php/issues", "issues": "https://github.com/open-telemetry/opentelemetry-php/issues",
"source": "https://github.com/open-telemetry/opentelemetry-php" "source": "https://github.com/open-telemetry/opentelemetry-php"
}, },
"time": "2024-10-15T22:42:37+00:00" "time": "2024-11-16T04:32:30+00:00"
}, },
{ {
"name": "open-telemetry/context", "name": "open-telemetry/context",
@ -1530,13 +1530,13 @@
}, },
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": {
"dev-main": "1.0.x-dev"
},
"spi": { "spi": {
"OpenTelemetry\\API\\Instrumentation\\AutoInstrumentation\\HookManagerInterface": [ "OpenTelemetry\\API\\Instrumentation\\AutoInstrumentation\\HookManagerInterface": [
"OpenTelemetry\\API\\Instrumentation\\AutoInstrumentation\\ExtensionHookManager" "OpenTelemetry\\API\\Instrumentation\\AutoInstrumentation\\ExtensionHookManager"
] ]
},
"branch-alias": {
"dev-main": "1.0.x-dev"
} }
}, },
"autoload": { "autoload": {
@ -2453,23 +2453,23 @@
}, },
{ {
"name": "symfony/http-client", "name": "symfony/http-client",
"version": "v7.2.0", "version": "v7.2.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/http-client.git", "url": "https://github.com/symfony/http-client.git",
"reference": "955e43336aff03df1e8a8e17daefabb0127a313b" "reference": "ff4df2b68d1c67abb9fef146e6540ea16b58d99e"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/http-client/zipball/955e43336aff03df1e8a8e17daefabb0127a313b", "url": "https://api.github.com/repos/symfony/http-client/zipball/ff4df2b68d1c67abb9fef146e6540ea16b58d99e",
"reference": "955e43336aff03df1e8a8e17daefabb0127a313b", "reference": "ff4df2b68d1c67abb9fef146e6540ea16b58d99e",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": ">=8.2", "php": ">=8.2",
"psr/log": "^1|^2|^3", "psr/log": "^1|^2|^3",
"symfony/deprecation-contracts": "^2.5|^3", "symfony/deprecation-contracts": "^2.5|^3",
"symfony/http-client-contracts": "~3.4.3|^3.5.1", "symfony/http-client-contracts": "~3.4.4|^3.5.2",
"symfony/service-contracts": "^2.5|^3" "symfony/service-contracts": "^2.5|^3"
}, },
"conflict": { "conflict": {
@ -2528,7 +2528,7 @@
"http" "http"
], ],
"support": { "support": {
"source": "https://github.com/symfony/http-client/tree/v7.2.0" "source": "https://github.com/symfony/http-client/tree/v7.2.1"
}, },
"funding": [ "funding": [
{ {
@ -2544,20 +2544,20 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2024-11-29T08:22:02+00:00" "time": "2024-12-07T08:50:44+00:00"
}, },
{ {
"name": "symfony/http-client-contracts", "name": "symfony/http-client-contracts",
"version": "v3.5.1", "version": "v3.5.2",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/http-client-contracts.git", "url": "https://github.com/symfony/http-client-contracts.git",
"reference": "c2f3ad828596624ca39ea40f83617ef51ca8bbf9" "reference": "ee8d807ab20fcb51267fdace50fbe3494c31e645"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/c2f3ad828596624ca39ea40f83617ef51ca8bbf9", "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/ee8d807ab20fcb51267fdace50fbe3494c31e645",
"reference": "c2f3ad828596624ca39ea40f83617ef51ca8bbf9", "reference": "ee8d807ab20fcb51267fdace50fbe3494c31e645",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -2606,7 +2606,7 @@
"standards" "standards"
], ],
"support": { "support": {
"source": "https://github.com/symfony/http-client-contracts/tree/v3.5.1" "source": "https://github.com/symfony/http-client-contracts/tree/v3.5.2"
}, },
"funding": [ "funding": [
{ {
@ -2622,7 +2622,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2024-11-25T12:02:18+00:00" "time": "2024-12-07T08:49:48+00:00"
}, },
{ {
"name": "symfony/polyfill-mbstring", "name": "symfony/polyfill-mbstring",
@ -2650,8 +2650,8 @@
"type": "library", "type": "library",
"extra": { "extra": {
"thanks": { "thanks": {
"name": "symfony/polyfill", "url": "https://github.com/symfony/polyfill",
"url": "https://github.com/symfony/polyfill" "name": "symfony/polyfill"
} }
}, },
"autoload": { "autoload": {
@ -3136,16 +3136,16 @@
}, },
{ {
"name": "utopia-php/abuse", "name": "utopia-php/abuse",
"version": "0.43.2", "version": "0.45.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/utopia-php/abuse.git", "url": "https://github.com/utopia-php/abuse.git",
"reference": "374536b86d8d39066960a7da161d444a099bbc56" "reference": "54a58355df1eb26c9be7834738debe6754e5581d"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/utopia-php/abuse/zipball/374536b86d8d39066960a7da161d444a099bbc56", "url": "https://api.github.com/repos/utopia-php/abuse/zipball/54a58355df1eb26c9be7834738debe6754e5581d",
"reference": "374536b86d8d39066960a7da161d444a099bbc56", "reference": "54a58355df1eb26c9be7834738debe6754e5581d",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -3181,9 +3181,9 @@
], ],
"support": { "support": {
"issues": "https://github.com/utopia-php/abuse/issues", "issues": "https://github.com/utopia-php/abuse/issues",
"source": "https://github.com/utopia-php/abuse/tree/0.43.2" "source": "https://github.com/utopia-php/abuse/tree/0.45.0"
}, },
"time": "2024-12-12T19:43:24+00:00" "time": "2024-12-20T16:18:52+00:00"
}, },
{ {
"name": "utopia-php/analytics", "name": "utopia-php/analytics",
@ -4807,16 +4807,16 @@
"packages-dev": [ "packages-dev": [
{ {
"name": "appwrite/sdk-generator", "name": "appwrite/sdk-generator",
"version": "0.39.25", "version": "0.39.27",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/appwrite/sdk-generator.git", "url": "https://github.com/appwrite/sdk-generator.git",
"reference": "5b5323636a8d75a1c4faaae9728098dd6a6a47d1" "reference": "27d8ecde30e40cbfe1124cc0430c406d3e144849"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/5b5323636a8d75a1c4faaae9728098dd6a6a47d1", "url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/27d8ecde30e40cbfe1124cc0430c406d3e144849",
"reference": "5b5323636a8d75a1c4faaae9728098dd6a6a47d1", "reference": "27d8ecde30e40cbfe1124cc0430c406d3e144849",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -4852,9 +4852,9 @@
"description": "Appwrite PHP library for generating API SDKs for multiple programming languages and platforms", "description": "Appwrite PHP library for generating API SDKs for multiple programming languages and platforms",
"support": { "support": {
"issues": "https://github.com/appwrite/sdk-generator/issues", "issues": "https://github.com/appwrite/sdk-generator/issues",
"source": "https://github.com/appwrite/sdk-generator/tree/0.39.25" "source": "https://github.com/appwrite/sdk-generator/tree/0.39.27"
}, },
"time": "2024-11-08T10:16:34+00:00" "time": "2024-12-16T11:32:02+00:00"
}, },
{ {
"name": "doctrine/annotations", "name": "doctrine/annotations",
@ -7576,16 +7576,16 @@
}, },
{ {
"name": "symfony/console", "name": "symfony/console",
"version": "v7.2.0", "version": "v7.2.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/console.git", "url": "https://github.com/symfony/console.git",
"reference": "23c8aae6d764e2bae02d2a99f7532a7f6ed619cf" "reference": "fefcc18c0f5d0efe3ab3152f15857298868dc2c3"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/console/zipball/23c8aae6d764e2bae02d2a99f7532a7f6ed619cf", "url": "https://api.github.com/repos/symfony/console/zipball/fefcc18c0f5d0efe3ab3152f15857298868dc2c3",
"reference": "23c8aae6d764e2bae02d2a99f7532a7f6ed619cf", "reference": "fefcc18c0f5d0efe3ab3152f15857298868dc2c3",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -7649,7 +7649,7 @@
"terminal" "terminal"
], ],
"support": { "support": {
"source": "https://github.com/symfony/console/tree/v7.2.0" "source": "https://github.com/symfony/console/tree/v7.2.1"
}, },
"funding": [ "funding": [
{ {
@ -7665,7 +7665,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2024-11-06T14:24:19+00:00" "time": "2024-12-11T03:49:26+00:00"
}, },
{ {
"name": "symfony/filesystem", "name": "symfony/filesystem",

View file

@ -8,7 +8,6 @@ use Appwrite\Extend\Exception;
use Executor\Executor; use Executor\Executor;
use Throwable; use Throwable;
use Utopia\Abuse\Abuse; use Utopia\Abuse\Abuse;
use Utopia\Abuse\Adapters\Database\TimeLimit;
use Utopia\Audit\Audit; use Utopia\Audit\Audit;
use Utopia\Cache\Adapter\Filesystem; use Utopia\Cache\Adapter\Filesystem;
use Utopia\Cache\Cache; use Utopia\Cache\Cache;
@ -47,6 +46,7 @@ class Deletes extends Action
->inject('message') ->inject('message')
->inject('dbForPlatform') ->inject('dbForPlatform')
->inject('getProjectDB') ->inject('getProjectDB')
->inject('timelimit')
->inject('deviceForFiles') ->inject('deviceForFiles')
->inject('deviceForFunctions') ->inject('deviceForFunctions')
->inject('deviceForBuilds') ->inject('deviceForBuilds')
@ -57,8 +57,8 @@ class Deletes extends Action
->inject('auditRetention') ->inject('auditRetention')
->inject('log') ->inject('log')
->callback( ->callback(
fn ($message, $dbForPlatform, callable $getProjectDB, Device $deviceForFiles, Device $deviceForFunctions, Device $deviceForBuilds, Device $deviceForCache, CertificatesAdapter $certificates, string $abuseRetention, string $executionRetention, string $auditRetention, Log $log) => fn ($message, $dbForPlatform, callable $getProjectDB, callable $timelimit, Device $deviceForFiles, Device $deviceForFunctions, Device $deviceForBuilds, Device $deviceForCache, CertificatesAdapter $certificates, string $abuseRetention, string $executionRetention, string $auditRetention, Log $log) =>
$this->action($message, $dbForPlatform, $getProjectDB, $deviceForFiles, $deviceForFunctions, $deviceForBuilds, $deviceForCache, $certificates, $abuseRetention, $executionRetention, $auditRetention, $log) $this->action($message, $dbForPlatform, $getProjectDB, $timelimit, $deviceForFiles, $deviceForFunctions, $deviceForBuilds, $deviceForCache, $certificates, $abuseRetention, $executionRetention, $auditRetention, $log)
); );
} }
@ -66,7 +66,7 @@ class Deletes extends Action
* @throws Exception * @throws Exception
* @throws Throwable * @throws Throwable
*/ */
public function action(Message $message, Database $dbForPlatform, callable $getProjectDB, Device $deviceForFiles, Device $deviceForFunctions, Device $deviceForBuilds, Device $deviceForCache, CertificatesAdapter $certificates, string $abuseRetention, string $executionRetention, string $auditRetention, Log $log): void public function action(Message $message, Database $dbForPlatform, callable $getProjectDB, callable $timelimit, Device $deviceForFiles, Device $deviceForFunctions, Device $deviceForBuilds, Device $deviceForCache, CertificatesAdapter $certificates, string $abuseRetention, string $executionRetention, string $auditRetention, Log $log): void
{ {
$payload = $message->getPayload() ?? []; $payload = $message->getPayload() ?? [];
@ -126,7 +126,7 @@ class Deletes extends Action
} }
break; break;
case DELETE_TYPE_ABUSE: case DELETE_TYPE_ABUSE:
$this->deleteAbuseLogs($project, $getProjectDB, $abuseRetention); $this->deleteAbuseLogs($project, $timelimit, $abuseRetention);
break; break;
case DELETE_TYPE_REALTIME: case DELETE_TYPE_REALTIME:
$this->deleteRealtimeUsage($dbForPlatform, $datetime); $this->deleteRealtimeUsage($dbForPlatform, $datetime);
@ -494,8 +494,7 @@ class Deletes extends Action
$projectCollectionIds = [ $projectCollectionIds = [
...\array_keys(Config::getParam('collections', [])['projects']), ...\array_keys(Config::getParam('collections', [])['projects']),
Audit::COLLECTION, Audit::COLLECTION
TimeLimit::COLLECTION,
]; ];
$limit = \count($projectCollectionIds) + 25; $limit = \count($projectCollectionIds) + 25;
@ -708,11 +707,10 @@ class Deletes extends Action
* @return void * @return void
* @throws Exception * @throws Exception
*/ */
private function deleteAbuseLogs(Document $project, callable $getProjectDB, string $abuseRetention): void private function deleteAbuseLogs(Document $project, callable $timelimit, string $abuseRetention): void
{ {
$projectId = $project->getId(); $projectId = $project->getId();
$dbForProject = $getProjectDB($project); $timeLimit = $timelimit("", 0, 1);
$timeLimit = new TimeLimit("", 0, 1, $dbForProject);
$abuse = new Abuse($timeLimit); $abuse = new Abuse($timeLimit);
try { try {