1
0
Fork 0
mirror of synced 2024-06-02 10:54:44 +12:00

integrate abuse and audit

This commit is contained in:
Damodar Lohani 2021-06-07 11:02:29 +05:45
parent f1d75dc805
commit 12e01f8092
8 changed files with 280 additions and 196 deletions

View file

@ -21,7 +21,6 @@ use Utopia\Audit\Audit;
use Utopia\Audit\Adapters\MySQL as AuditAdapter;
use Utopia\Database\Document;
use Utopia\Database\Exception\Duplicate;
use Ahc\Jwt\JWT;
use Utopia\Database\Query;
use Utopia\Database\Validator\Authorization;
use Utopia\Database\Validator\UID;
@ -830,22 +829,19 @@ App::get('/v1/account/logs')
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
->label('sdk.response.model', Response::MODEL_LOG_LIST)
->inject('response')
->inject('register')
->inject('project')
->inject('user')
->inject('locale')
->inject('geodb')
->action(function ($response, $register, $project, $user, $locale, $geodb) {
->inject('dbForInternal')
->action(function ($response, $user, $locale, $geodb, $dbForInternal) {
/** @var Appwrite\Utopia\Response $response */
/** @var Appwrite\Database\Document $project */
/** @var Utopia\Database\Document $user */
/** @var Utopia\Locale\Locale $locale */
/** @var MaxMind\Db\Reader $geodb */
/** @var Utopia\Database\Database $dbForInternal */
$adapter = new AuditAdapter($register->get('db'));
$adapter->setNamespace('app_'.$project->getId());
$audit = new Audit($adapter);
$audit = new Audit($dbForInternal);
$countries = $locale->getText('countries');
$logs = $audit->getLogsByUserAndActions($user->getId(), [

View file

@ -1,25 +1,25 @@
<?php
use Utopia\App;
use Utopia\Exception;
use Utopia\Validator\ArrayList;
use Utopia\Validator\Boolean;
use Utopia\Validator\Text;
use Utopia\Validator\WhiteList;
use Appwrite\Network\Validator\URL;
use Utopia\Validator\Range;
use Utopia\Validator\Integer;
use Utopia\Config\Config;
use Utopia\Domains\Domain;
use Appwrite\Auth\Auth;
use Appwrite\Task\Validator\Cron;
use Appwrite\Network\Validator\CNAME;
use Appwrite\Network\Validator\Domain as DomainValidator;
use Appwrite\Network\Validator\URL;
use Appwrite\Task\Validator\Cron;
use Appwrite\Utopia\Response;
use Cron\CronExpression;
use Utopia\App;
use Utopia\Config\Config;
use Utopia\Database\Document;
use Utopia\Database\Query;
use Utopia\Database\Validator\UID;
use Utopia\Domains\Domain;
use Utopia\Exception;
use Utopia\Validator\ArrayList;
use Utopia\Validator\Boolean;
use Utopia\Validator\Integer;
use Utopia\Validator\Range;
use Utopia\Validator\Text;
use Utopia\Validator\WhiteList;
App::post('/v1/projects')
->desc('Create Project')
@ -60,8 +60,8 @@ App::post('/v1/projects')
$project = $dbForConsole->createDocument('projects', new Document([
'$collection' => 'projects',
'$read' => ['team:'.$teamId],
'$write' => ['team:'.$teamId.'/owner', 'team:'.$teamId.'/developer'],
'$read' => ['team:' . $teamId],
'$write' => ['team:' . $teamId . '/owner', 'team:' . $teamId . '/developer'],
'name' => $name,
'description' => $description,
'logo' => $logo,
@ -87,9 +87,9 @@ App::post('/v1/projects')
$collections = Config::getParam('collections2', []); /** @var array $collections */
$dbForInternal->setNamespace('project_'.$project->getId().'_internal');
$dbForInternal->setNamespace('project_' . $project->getId() . '_internal');
$dbForInternal->create();
$dbForExternal->setNamespace('project_'.$project->getId().'_external');
$dbForExternal->setNamespace('project_' . $project->getId() . '_external');
$dbForExternal->create();
foreach ($collections as $key => $collection) {
@ -206,7 +206,7 @@ App::get('/v1/projects/:projectId/usage')
throw new Exception('Project not found', 404);
}
if(App::getEnv('_APP_USAGE_STATS', 'enabled') == 'enabled') {
if (App::getEnv('_APP_USAGE_STATS', 'enabled') == 'enabled') {
$period = [
'24h' => [
@ -230,44 +230,44 @@ App::get('/v1/projects/:projectId/usage')
'group' => '1d',
],
];
$client = $register->get('influxdb');
$requests = [];
$network = [];
$functions = [];
if ($client) {
$start = $period[$range]['start']->format(DateTime::RFC3339);
$end = $period[$range]['end']->format(DateTime::RFC3339);
$database = $client->selectDB('telegraf');
// Requests
$result = $database->query('SELECT sum(value) AS "value" FROM "appwrite_usage_requests_all" WHERE time > \''.$start.'\' AND time < \''.$end.'\' AND "metric_type"=\'counter\' AND "project"=\''.$project->getId().'\' GROUP BY time('.$period[$range]['group'].') FILL(null)');
$result = $database->query('SELECT sum(value) AS "value" FROM "appwrite_usage_requests_all" WHERE time > \'' . $start . '\' AND time < \'' . $end . '\' AND "metric_type"=\'counter\' AND "project"=\'' . $project->getId() . '\' GROUP BY time(' . $period[$range]['group'] . ') FILL(null)');
$points = $result->getPoints();
foreach ($points as $point) {
$requests[] = [
'value' => (!empty($point['value'])) ? $point['value'] : 0,
'date' => \strtotime($point['time']),
];
}
// Network
$result = $database->query('SELECT sum(value) AS "value" FROM "appwrite_usage_network_all" WHERE time > \''.$start.'\' AND time < \''.$end.'\' AND "metric_type"=\'counter\' AND "project"=\''.$project->getId().'\' GROUP BY time('.$period[$range]['group'].') FILL(null)');
$result = $database->query('SELECT sum(value) AS "value" FROM "appwrite_usage_network_all" WHERE time > \'' . $start . '\' AND time < \'' . $end . '\' AND "metric_type"=\'counter\' AND "project"=\'' . $project->getId() . '\' GROUP BY time(' . $period[$range]['group'] . ') FILL(null)');
$points = $result->getPoints();
foreach ($points as $point) {
$network[] = [
'value' => (!empty($point['value'])) ? $point['value'] : 0,
'date' => \strtotime($point['time']),
];
}
// Functions
$result = $database->query('SELECT sum(value) AS "value" FROM "appwrite_usage_executions_all" WHERE time > \''.$start.'\' AND time < \''.$end.'\' AND "metric_type"=\'counter\' AND "project"=\''.$project->getId().'\' GROUP BY time('.$period[$range]['group'].') FILL(null)');
$result = $database->query('SELECT sum(value) AS "value" FROM "appwrite_usage_executions_all" WHERE time > \'' . $start . '\' AND time < \'' . $end . '\' AND "metric_type"=\'counter\' AND "project"=\'' . $project->getId() . '\' GROUP BY time(' . $period[$range]['group'] . ') FILL(null)');
$points = $result->getPoints();
foreach ($points as $point) {
$functions[] = [
'value' => (!empty($point['value'])) ? $point['value'] : 0,
@ -281,14 +281,13 @@ App::get('/v1/projects/:projectId/usage')
$functions = [];
}
// Users
$projectDB->getCollection([
'limit' => 0,
'offset' => 0,
'filters' => [
'$collection=users'
'$collection=users',
],
]);
@ -313,7 +312,7 @@ App::get('/v1/projects/:projectId/usage')
'limit' => 0,
'offset' => 0,
'filters' => [
'$collection='.$collection['$id'],
'$collection=' . $collection['$id'],
],
]);
@ -369,7 +368,7 @@ App::get('/v1/projects/:projectId/usage')
'$collection=files',
],
]
) +
) +
$projectDB->getCount(
[
'attribute' => 'size',
@ -416,16 +415,16 @@ App::patch('/v1/projects/:projectId')
}
$project = $dbForConsole->updateDocument('projects', $project->getId(), $project
->setAttribute('name', $name)
->setAttribute('description', $description)
->setAttribute('logo', $logo)
->setAttribute('url', $url)
->setAttribute('legalName', $legalName)
->setAttribute('legalCountry', $legalCountry)
->setAttribute('legalState', $legalState)
->setAttribute('legalCity', $legalCity)
->setAttribute('legalAddress', $legalAddress)
->setAttribute('legalTaxId', $legalTaxId)
->setAttribute('name', $name)
->setAttribute('description', $description)
->setAttribute('logo', $logo)
->setAttribute('url', $url)
->setAttribute('legalName', $legalName)
->setAttribute('legalCountry', $legalCountry)
->setAttribute('legalState', $legalState)
->setAttribute('legalCity', $legalCity)
->setAttribute('legalAddress', $legalAddress)
->setAttribute('legalTaxId', $legalTaxId)
);
$response->dynamic2($project, Response::MODEL_PROJECT);
@ -458,8 +457,8 @@ App::patch('/v1/projects/:projectId/oauth2')
}
$project = $dbForConsole->updateDocument('projects', $project->getId(), $project
->setAttribute('usersOauth2'.\ucfirst($provider).'Appid', $appId)
->setAttribute('usersOauth2'.\ucfirst($provider).'Secret', $secret)
->setAttribute('usersOauth2' . \ucfirst($provider) . 'Appid', $appId)
->setAttribute('usersOauth2' . \ucfirst($provider) . 'Secret', $secret)
);
$response->dynamic2($project, Response::MODEL_PROJECT);
@ -490,7 +489,7 @@ App::patch('/v1/projects/:projectId/auth/limit')
}
$dbForConsole->updateDocument('projects', $project->getId(), $project
->setAttribute('usersAuthLimit', $limit)
->setAttribute('usersAuthLimit', $limit)
);
$response->dynamic2($project, Response::MODEL_PROJECT);
@ -507,7 +506,7 @@ App::patch('/v1/projects/:projectId/auth/:method')
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
->label('sdk.response.model', Response::MODEL_PROJECT)
->param('projectId', '', new UID(), 'Project unique ID.')
->param('method', '', new WhiteList(\array_keys(Config::getParam('auth')), true), 'Auth Method. Possible values: '.implode(',', \array_keys(Config::getParam('auth'))), false)
->param('method', '', new WhiteList(\array_keys(Config::getParam('auth')), true), 'Auth Method. Possible values: ' . implode(',', \array_keys(Config::getParam('auth'))), false)
->param('status', false, new Boolean(true), 'Set the status of this auth method.')
->inject('response')
->inject('dbForConsole')
@ -525,7 +524,7 @@ App::patch('/v1/projects/:projectId/auth/:method')
}
$dbForConsole->updateDocument('projects', $project->getId(), $project
->setAttribute($authKey, $status)
->setAttribute($authKey, $status)
);
$response->dynamic2($project, Response::MODEL_PROJECT);
@ -566,7 +565,7 @@ App::delete('/v1/projects/:projectId')
->setParam('type', DELETE_TYPE_DOCUMENT)
->setParam('document', $project)
;
if (!$dbForConsole->deleteDocument('teams', $project->getAttribute('teamId', null))) {
throw new Exception('Failed to remove project team from DB', 500);
}
@ -622,7 +621,7 @@ App::post('/v1/projects/:projectId/webhooks')
]);
$project = $dbForConsole->updateDocument('projects', $project->getId(), $project
->setAttribute('webhooks', $webhook, Document::SET_TYPE_APPEND)
->setAttribute('webhooks', $webhook, Document::SET_TYPE_APPEND)
);
$response->setStatusCode(Response::STATUS_CODE_CREATED);
@ -732,16 +731,16 @@ App::put('/v1/projects/:projectId/webhooks/:webhookId')
}
$project->findAndReplace('$id', $webhook->getId(), $webhook
->setAttribute('name', $name)
->setAttribute('events', $events)
->setAttribute('url', $url)
->setAttribute('security', $security)
->setAttribute('httpUser', $httpUser)
->setAttribute('httpPass', $httpPass)
, 'webhooks');
->setAttribute('name', $name)
->setAttribute('events', $events)
->setAttribute('url', $url)
->setAttribute('security', $security)
->setAttribute('httpUser', $httpUser)
->setAttribute('httpPass', $httpPass)
, 'webhooks');
$dbForConsole->updateDocument('projects', $project->getId(), $project);
$response->dynamic2($webhook, Response::MODEL_WEBHOOK);
});
@ -812,7 +811,7 @@ App::post('/v1/projects/:projectId/keys')
]);
$project = $dbForConsole->updateDocument('projects', $project->getId(), $project
->setAttribute('keys', $key, Document::SET_TYPE_APPEND)
->setAttribute('keys', $key, Document::SET_TYPE_APPEND)
);
$response->setStatusCode(Response::STATUS_CODE_CREATED);
@ -835,7 +834,7 @@ App::get('/v1/projects/:projectId/keys')
->action(function ($projectId, $response, $dbForConsole) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForConsole */
$project = $dbForConsole->getDocument('projects', $projectId);
if ($project->isEmpty()) {
@ -913,12 +912,12 @@ App::put('/v1/projects/:projectId/keys/:keyId')
}
$project->findAndReplace('$id', $key->getId(), $key
->setAttribute('name', $name)
->setAttribute('scopes', $scopes)
, 'keys');
->setAttribute('name', $name)
->setAttribute('scopes', $scopes)
, 'keys');
$dbForConsole->updateDocument('projects', $project->getId(), $project);
$response->dynamic2($key, Response::MODEL_KEY);
});
@ -1011,7 +1010,7 @@ App::post('/v1/projects/:projectId/tasks')
]);
$project = $dbForConsole->updateDocument('projects', $project->getId(), $project
->setAttribute('tasks', $task, Document::SET_TYPE_APPEND)
->setAttribute('tasks', $task, Document::SET_TYPE_APPEND)
);
if ($next) {
@ -1131,18 +1130,18 @@ App::put('/v1/projects/:projectId/tasks/:taskId')
$security = ($security === '1' || $security === 'true' || $security === 1 || $security === true);
$project->findAndReplace('$id', $task->getId(), $task
->setAttribute('name', $name)
->setAttribute('status', $status)
->setAttribute('schedule', $schedule)
->setAttribute('updated', \time())
->setAttribute('next', $next)
->setAttribute('security', $security)
->setAttribute('httpMethod', $httpMethod)
->setAttribute('httpUrl', $httpUrl)
->setAttribute('httpHeaders', $httpHeaders)
->setAttribute('httpUser', $httpUser)
->setAttribute('httpPass', $httpPass)
, 'tasks');
->setAttribute('name', $name)
->setAttribute('status', $status)
->setAttribute('schedule', $schedule)
->setAttribute('updated', \time())
->setAttribute('next', $next)
->setAttribute('security', $security)
->setAttribute('httpMethod', $httpMethod)
->setAttribute('httpUrl', $httpUrl)
->setAttribute('httpHeaders', $httpHeaders)
->setAttribute('httpUser', $httpUser)
->setAttribute('httpPass', $httpPass)
, 'tasks');
$dbForConsole->updateDocument('projects', $project->getId(), $project);
@ -1227,13 +1226,13 @@ App::post('/v1/projects/:projectId/platforms')
]);
$project = $dbForConsole->updateDocument('projects', $project->getId(), $project
->setAttribute('platforms', $platform, Document::SET_TYPE_APPEND)
->setAttribute('platforms', $platform, Document::SET_TYPE_APPEND)
);
$response->setStatusCode(Response::STATUS_CODE_CREATED);
$response->dynamic2($platform, Response::MODEL_PLATFORM);
});
App::get('/v1/projects/:projectId/platforms')
->desc('List Platforms')
->groups(['api', 'projects'])
@ -1341,12 +1340,12 @@ App::put('/v1/projects/:projectId/platforms/:platformId')
;
$project->findAndReplace('$id', $platform->getId(), $platform
->setAttribute('name', $name)
->setAttribute('dateUpdated', \time())
->setAttribute('key', $key)
->setAttribute('store', $store)
->setAttribute('hostname', $hostname)
, 'platforms');
->setAttribute('name', $name)
->setAttribute('dateUpdated', \time())
->setAttribute('key', $key)
->setAttribute('store', $store)
->setAttribute('hostname', $hostname)
, 'platforms');
$dbForConsole->updateDocument('projects', $project->getId(), $project);
@ -1420,7 +1419,7 @@ App::post('/v1/projects/:projectId/domains')
$target = new Domain(App::getEnv('_APP_DOMAIN_TARGET', ''));
if (!$target->isKnown() || $target->isTest()) {
throw new Exception('Unreachable CNAME target ('.$target->get().'), please use a domain with a public suffix.', 500);
throw new Exception('Unreachable CNAME target (' . $target->get() . '), please use a domain with a public suffix.', 500);
}
$domain = new Domain($domain);
@ -1436,7 +1435,7 @@ App::post('/v1/projects/:projectId/domains')
]);
$project = $dbForConsole->updateDocument('projects', $project->getId(), $project
->setAttribute('domains', $domain, Document::SET_TYPE_APPEND)
->setAttribute('domains', $domain, Document::SET_TYPE_APPEND)
);
$response->setStatusCode(Response::STATUS_CODE_CREATED);
@ -1467,7 +1466,7 @@ App::get('/v1/projects/:projectId/domains')
}
$domains = $project->getAttribute('domains', []);
$response->dynamic2(new Document([
'domains' => $domains,
'sum' => count($domains),
@ -1540,7 +1539,7 @@ App::patch('/v1/projects/:projectId/domains/:domainId/verification')
$target = new Domain(App::getEnv('_APP_DOMAIN_TARGET', ''));
if (!$target->isKnown() || $target->isTest()) {
throw new Exception('Unreachable CNAME target ('.$target->get().'), please use a domain with a public suffix.', 500);
throw new Exception('Unreachable CNAME target (' . $target->get() . '), please use a domain with a public suffix.', 500);
}
if ($domain->getAttribute('verification') === true) {
@ -1554,8 +1553,8 @@ App::patch('/v1/projects/:projectId/domains/:domainId/verification')
}
$project->findAndReplace('$id', $domain->getId(), $domain
->setAttribute('verification', true)
, 'domains');
->setAttribute('verification', true)
, 'domains');
$dbForConsole->updateDocument('projects', $project->getId(), $project);
@ -1606,4 +1605,4 @@ App::delete('/v1/projects/:projectId/domains/:domainId')
;
$response->noContent();
});
});

View file

@ -13,7 +13,6 @@ use Utopia\Validator\Text;
use Utopia\Validator\Range;
use Utopia\Validator\Boolean;
use Utopia\Audit\Audit;
use Utopia\Audit\Adapters\MySQL as AuditAdapter;
use Utopia\Database\Document;
use Utopia\Database\Exception\Duplicate;
use Utopia\Database\Validator\UID;
@ -212,12 +211,10 @@ App::get('/v1/users/:userId/logs')
->label('sdk.response.model', Response::MODEL_LOG_LIST)
->param('userId', '', new UID(), 'User unique ID.')
->inject('response')
->inject('register')
->inject('project')
->inject('dbForInternal')
->inject('locale')
->inject('geodb')
->action(function ($userId, $response, $register, $project, $dbForInternal, $locale, $geodb) {
->action(function ($userId, $response, $dbForInternal, $locale, $geodb) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Registry\Registry $register */
/** @var Appwrite\Database\Document $project */
@ -231,10 +228,7 @@ App::get('/v1/users/:userId/logs')
throw new Exception('User not found', 404);
}
$adapter = new AuditAdapter($register->get('db'));
$adapter->setNamespace('app_'.$project->getId());
$audit = new Audit($adapter);
$audit = new Audit($dbForInternal);
$countries = $locale->getText('countries');

View file

@ -9,7 +9,7 @@ use Utopia\Abuse\Adapters\TimeLimit;
use Utopia\Storage\Device\Local;
use Utopia\Storage\Storage;
App::init(function ($utopia, $request, $response, $project, $user, $register, $events, $audits, $usage, $deletes) {
App::init(function ($utopia, $request, $response, $project, $user, $register, $events, $audits, $usage, $deletes, $dbForInternal) {
/** @var Utopia\App $utopia */
/** @var Utopia\Swoole\Request $request */
/** @var Appwrite\Utopia\Response $response */
@ -21,6 +21,7 @@ App::init(function ($utopia, $request, $response, $project, $user, $register, $e
/** @var Appwrite\Event\Event $usage */
/** @var Appwrite\Event\Event $deletes */
/** @var Appwrite\Event\Event $functions */
/** @var Utopia\Database\Database $dbForInternal */
Storage::setDevice('files', new Local(APP_STORAGE_UPLOADS.'/app-'.$project->getId()));
Storage::setDevice('functions', new Local(APP_STORAGE_FUNCTIONS.'/app-'.$project->getId()));
@ -31,47 +32,44 @@ App::init(function ($utopia, $request, $response, $project, $user, $register, $e
throw new Exception('Missing or unknown project ID', 400);
}
// /*
// * Abuse Check
// */
// $timeLimit = new TimeLimit($route->getLabel('abuse-key', 'url:{url},ip:{ip}'), $route->getLabel('abuse-limit', 0), $route->getLabel('abuse-time', 3600), function () use ($register) {
// return $register->get('db');
// });
// $timeLimit->setNamespace('app_'.$project->getId());
// $timeLimit
// ->setParam('{userId}', $user->getId())
// ->setParam('{userAgent}', $request->getUserAgent(''))
// ->setParam('{ip}', $request->getIP())
// ->setParam('{url}', $request->getHostname().$route->getURL())
// ;
/*
* Abuse Check
*/
$timeLimit = new TimeLimit($route->getLabel('abuse-key', 'url:{url},ip:{ip}'), $route->getLabel('abuse-limit', 0), $route->getLabel('abuse-time', 3600), $dbForInternal);
$timeLimit
->setParam('{userId}', $user->getId())
->setParam('{userAgent}', $request->getUserAgent(''))
->setParam('{ip}', $request->getIP())
->setParam('{url}', $request->getHostname().$route->getURL())
;
// //TODO make sure we get array here
//TODO make sure we get array here
// foreach ($request->getParams() as $key => $value) { // Set request params as potential abuse keys
// if(!empty($value)) {
// $timeLimit->setParam('{param-'.$key.'}', (\is_array($value)) ? \json_encode($value) : $value);
// }
// }
foreach ($request->getParams() as $key => $value) { // Set request params as potential abuse keys
if(!empty($value)) {
$timeLimit->setParam('{param-'.$key.'}', (\is_array($value)) ? \json_encode($value) : $value);
}
}
// $abuse = new Abuse($timeLimit);
$abuse = new Abuse($timeLimit);
// if ($timeLimit->limit()) {
// $response
// ->addHeader('X-RateLimit-Limit', $timeLimit->limit())
// ->addHeader('X-RateLimit-Remaining', $timeLimit->remaining())
// ->addHeader('X-RateLimit-Reset', $timeLimit->time() + $route->getLabel('abuse-time', 3600))
// ;
// }
if ($timeLimit->limit()) {
$response
->addHeader('X-RateLimit-Limit', $timeLimit->limit())
->addHeader('X-RateLimit-Remaining', $timeLimit->remaining())
->addHeader('X-RateLimit-Reset', $timeLimit->time() + $route->getLabel('abuse-time', 3600))
;
}
// $isPrivilegedUser = Auth::isPrivilegedUser(Authorization::$roles);
// $isAppUser = Auth::isAppUser(Authorization::$roles);
$isPrivilegedUser = Auth::isPrivilegedUser(Authorization::$roles);
$isAppUser = Auth::isAppUser(Authorization::$roles);
// if (($abuse->check() // Route is rate-limited
// && App::getEnv('_APP_OPTIONS_ABUSE', 'enabled') !== 'disabled') // Abuse is not diabled
// && (!$isAppUser && !$isPrivilegedUser)) // User is not an admin or API key
// {
// throw new Exception('Too many requests', 429);
// }
if (($abuse->check() // Route is rate-limited
&& App::getEnv('_APP_OPTIONS_ABUSE', 'enabled') !== 'disabled') // Abuse is not diabled
&& (!$isAppUser && !$isPrivilegedUser)) // User is not an admin or API key
{
throw new Exception('Too many requests', 429);
}
/*
* Background Jobs
@ -111,7 +109,7 @@ App::init(function ($utopia, $request, $response, $project, $user, $register, $e
->setParam('projectId', $project->getId())
;
}, ['utopia', 'request', 'response', 'project', 'user', 'register', 'events', 'audits', 'usage', 'deletes'], 'api');
}, ['utopia', 'request', 'response', 'project', 'user', 'register', 'events', 'audits', 'usage', 'deletes', 'dbForInternal'], 'api');
App::init(function ($utopia, $request, $response, $project, $user) {

View file

@ -2,7 +2,11 @@
use Utopia\Audit\Audit;
use Utopia\Audit\Adapters\MySQL as AuditAdapter;
use Utopia\Cache\Adapter\Redis;
use Utopia\Cache\Cache;
use Utopia\CLI\Console;
use Utopia\Database\Adapter\MariaDB;
use Utopia\Database\Database;
require_once __DIR__.'/../init.php';
@ -31,10 +35,11 @@ class AuditsV1
$data = $this->args['data'];
$db = $register->get('db', true);
$adapter = new AuditAdapter($db);
$adapter->setNamespace('app_'.$projectId);
$cache = new Cache(new Redis($register->get('cache')));
$dbForInternal = new Database(new MariaDB($db), $cache);
$dbForInternal->setNamespace('project_'.$projectId.'_internal');
$audit = new Audit($adapter);
$audit = new Audit($dbForInternal);
$audit->log($userId, $event, $resource, $userAgent, $ip, '', $data);
}

View file

@ -1,6 +1,8 @@
<?php
use Appwrite\Database\Database;
use Utopia\Database\Database as Database2;
use Utopia\Cache\Adapter\Redis as RedisCache;
use Appwrite\Database\Adapter\MySQL as MySQLAdapter;
use Appwrite\Database\Adapter\Redis as RedisAdapter;
use Appwrite\Database\Document;
@ -12,6 +14,8 @@ use Utopia\CLI\Console;
use Utopia\Config\Config;
use Utopia\Audit\Audit;
use Utopia\Audit\Adapters\MySQL as AuditAdapter;
use Utopia\Cache\Cache;
use Utopia\Database\Adapter\MariaDB;
require_once __DIR__.'/../init.php';
@ -167,12 +171,9 @@ class DeletesV1
throw new Exception('Failed to delete audit logs. No timestamp provided');
}
$timeLimit = new TimeLimit("", 0, 1, function () use ($register) {
return $register->get('db');
});
$this->deleteForProjectIds(function($projectId) use ($timeLimit, $timestamp){
$timeLimit->setNamespace('app_'.$projectId);
$this->deleteForProjectIds(function($projectId) use ($timestamp){
$timeLimit = new TimeLimit("", 0, 1, $this->getInternalDB($projectId));
$abuse = new Abuse($timeLimit);
$status = $abuse->cleanup($timestamp);
@ -189,9 +190,7 @@ class DeletesV1
throw new Exception('Failed to delete audit logs. No timestamp provided');
}
$this->deleteForProjectIds(function($projectId) use ($register, $timestamp){
$adapter = new AuditAdapter($register->get('db'));
$adapter->setNamespace('app_'.$projectId);
$audit = new Audit($adapter);
$audit = new Audit($this->getInternalDB($projectId));
$status = $audit->cleanup($timestamp);
if (!$status) {
throw new Exception('Failed to delete Audit logs for project'.$projectId);
@ -375,4 +374,18 @@ class DeletesV1
return $projectDB;
}
/**
* @return Database2
*/
protected function getInternalDB($projectId): Database2
{
global $register;
$cache = new Cache(new RedisCache($register->get('cache')));
$dbForInternal = new Database2(new MariaDB($register->get('db')), $cache);
$dbForInternal->setNamespace('project_'.$projectId.'_internal'); // Main DB
return $dbForInternal;
}
}

View file

@ -39,9 +39,9 @@
"appwrite/php-runtimes": "0.2.*",
"utopia-php/framework": "0.14.*",
"utopia-php/abuse": "0.4.*",
"utopia-php/abuse": "dev-feat-utopia-db-integration",
"utopia-php/analytics": "0.2.*",
"utopia-php/audit": "0.5.*",
"utopia-php/audit": "dev-feat-utopia-db-integration",
"utopia-php/cache": "0.4.*",
"utopia-php/cli": "0.11.*",
"utopia-php/config": "0.2.*",
@ -62,6 +62,16 @@
"adhocore/jwt": "1.1.2",
"slickdeals/statsd": "3.0.2"
},
"repositories": [
{
"type": "git",
"url": "https://github.com/lohanidamodar/audit"
},
{
"type": "git",
"url": "https://github.com/lohanidamodar/abuse"
}
],
"require-dev": {
"appwrite/sdk-generator": "0.10.6",
"swoole/ide-helper": "4.6.6",

143
composer.lock generated
View file

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "5cf39daf305902a168233757d4a00066",
"content-hash": "3eb7dc73e9524209a38bd6c33a540732",
"packages": [
{
"name": "adhocore/jwt",
@ -1603,21 +1603,22 @@
},
{
"name": "utopia-php/abuse",
"version": "0.4.0",
"version": "dev-feat-utopia-db-integration",
"source": {
"type": "git",
"url": "https://github.com/utopia-php/abuse.git",
"reference": "2b8cc40a67c045c137b44d1a11326f494acf50a4"
"url": "https://github.com/lohanidamodar/abuse.git",
"reference": "525cdf6674e11a7229cba31941915ac50a3e575a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/utopia-php/abuse/zipball/2b8cc40a67c045c137b44d1a11326f494acf50a4",
"reference": "2b8cc40a67c045c137b44d1a11326f494acf50a4",
"url": "https://api.github.com/repos/lohanidamodar/abuse/zipball/525cdf6674e11a7229cba31941915ac50a3e575a",
"reference": "525cdf6674e11a7229cba31941915ac50a3e575a",
"shasum": ""
},
"require": {
"ext-pdo": "*",
"php": ">=7.4"
"php": ">=7.4",
"utopia-php/database": "0.2.*"
},
"require-dev": {
"phpunit/phpunit": "^9.4",
@ -1629,7 +1630,6 @@
"Utopia\\Abuse\\": "src/Abuse"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
@ -1641,17 +1641,16 @@
],
"description": "A simple abuse library to manage application usage limits",
"keywords": [
"Abuse",
"abuse",
"framework",
"php",
"upf",
"utopia"
],
"support": {
"issues": "https://github.com/utopia-php/abuse/issues",
"source": "https://github.com/utopia-php/abuse/tree/0.4.0"
"source": "https://github.com/lohanidamodar/abuse/tree/feat-utopia-db-integration"
},
"time": "2021-03-17T20:21:24+00:00"
"time": "2021-06-04T08:40:29+00:00"
},
{
"name": "utopia-php/analytics",
@ -1710,21 +1709,22 @@
},
{
"name": "utopia-php/audit",
"version": "0.5.1",
"version": "dev-feat-utopia-db-integration",
"source": {
"type": "git",
"url": "https://github.com/utopia-php/audit.git",
"reference": "154a850170a58667a15e4b65fbabb6cd0b709dd9"
"url": "https://github.com/lohanidamodar/audit.git",
"reference": "3421b6a54740fbb29570004848cdc0b818717e83"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/utopia-php/audit/zipball/154a850170a58667a15e4b65fbabb6cd0b709dd9",
"reference": "154a850170a58667a15e4b65fbabb6cd0b709dd9",
"url": "https://api.github.com/repos/lohanidamodar/audit/zipball/3421b6a54740fbb29570004848cdc0b818717e83",
"reference": "3421b6a54740fbb29570004848cdc0b818717e83",
"shasum": ""
},
"require": {
"ext-pdo": "*",
"php": ">=7.1"
"php": ">=7.4",
"utopia-php/database": "0.2.*"
},
"require-dev": {
"phpunit/phpunit": "^9.3",
@ -1736,7 +1736,6 @@
"Utopia\\Audit\\": "src/Audit"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
@ -1748,17 +1747,16 @@
],
"description": "A simple audit library to manage application users logs",
"keywords": [
"Audit",
"audit",
"framework",
"php",
"upf",
"utopia"
],
"support": {
"issues": "https://github.com/utopia-php/audit/issues",
"source": "https://github.com/utopia-php/audit/tree/0.5.1"
"source": "https://github.com/lohanidamodar/audit/tree/feat-utopia-db-integration"
},
"time": "2020-12-21T17:28:53+00:00"
"time": "2021-06-04T08:41:19+00:00"
},
{
"name": "utopia-php/cache",
@ -5252,20 +5250,21 @@
},
{
"name": "symfony/console",
"version": "v5.2.8",
"version": "v5.3.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/console.git",
"reference": "864568fdc0208b3eba3638b6000b69d2386e6768"
"reference": "058553870f7809087fa80fa734704a21b9bcaeb2"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/console/zipball/864568fdc0208b3eba3638b6000b69d2386e6768",
"reference": "864568fdc0208b3eba3638b6000b69d2386e6768",
"url": "https://api.github.com/repos/symfony/console/zipball/058553870f7809087fa80fa734704a21b9bcaeb2",
"reference": "058553870f7809087fa80fa734704a21b9bcaeb2",
"shasum": ""
},
"require": {
"php": ">=7.2.5",
"symfony/deprecation-contracts": "^2.1",
"symfony/polyfill-mbstring": "~1.0",
"symfony/polyfill-php73": "^1.8",
"symfony/polyfill-php80": "^1.15",
@ -5329,7 +5328,7 @@
"terminal"
],
"support": {
"source": "https://github.com/symfony/console/tree/v5.2.8"
"source": "https://github.com/symfony/console/tree/v5.3.0"
},
"funding": [
{
@ -5345,7 +5344,74 @@
"type": "tidelift"
}
],
"time": "2021-05-11T15:45:21+00:00"
"time": "2021-05-26T17:43:10+00:00"
},
{
"name": "symfony/deprecation-contracts",
"version": "v2.4.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/deprecation-contracts.git",
"reference": "5f38c8804a9e97d23e0c8d63341088cd8a22d627"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/5f38c8804a9e97d23e0c8d63341088cd8a22d627",
"reference": "5f38c8804a9e97d23e0c8d63341088cd8a22d627",
"shasum": ""
},
"require": {
"php": ">=7.1"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "2.4-dev"
},
"thanks": {
"name": "symfony/contracts",
"url": "https://github.com/symfony/contracts"
}
},
"autoload": {
"files": [
"function.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "A generic function and convention to trigger deprecation notices",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/deprecation-contracts/tree/v2.4.0"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2021-03-23T23:28:01+00:00"
},
{
"name": "symfony/polyfill-intl-grapheme",
@ -5752,16 +5818,16 @@
},
{
"name": "symfony/string",
"version": "v5.2.8",
"version": "v5.3.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/string.git",
"reference": "01b35eb64cac8467c3f94cd0ce2d0d376bb7d1db"
"reference": "a9a0f8b6aafc5d2d1c116dcccd1573a95153515b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/string/zipball/01b35eb64cac8467c3f94cd0ce2d0d376bb7d1db",
"reference": "01b35eb64cac8467c3f94cd0ce2d0d376bb7d1db",
"url": "https://api.github.com/repos/symfony/string/zipball/a9a0f8b6aafc5d2d1c116dcccd1573a95153515b",
"reference": "a9a0f8b6aafc5d2d1c116dcccd1573a95153515b",
"shasum": ""
},
"require": {
@ -5815,7 +5881,7 @@
"utf8"
],
"support": {
"source": "https://github.com/symfony/string/tree/v5.2.8"
"source": "https://github.com/symfony/string/tree/v5.3.0"
},
"funding": [
{
@ -5831,7 +5897,7 @@
"type": "tidelift"
}
],
"time": "2021-05-10T14:56:10+00:00"
"time": "2021-05-26T17:43:10+00:00"
},
{
"name": "theseer/tokenizer",
@ -6120,7 +6186,10 @@
],
"aliases": [],
"minimum-stability": "stable",
"stability-flags": [],
"stability-flags": {
"utopia-php/abuse": 20,
"utopia-php/audit": 20
},
"prefer-stable": false,
"prefer-lowest": false,
"platform": {
@ -6143,4 +6212,4 @@
"php": "8.0"
},
"plugin-api-version": "2.0.0"
}
}