mirror of
https://github.com/appwrite/appwrite.git
synced 2026-05-26 13:51:13 +00:00
Merge pull request #10953 from appwrite/feat-audits-upgrade
Feat: Audits upgrade
This commit is contained in:
+9
-4
@@ -72,10 +72,11 @@ class XList extends Action
|
||||
->inject('dbForProject')
|
||||
->inject('locale')
|
||||
->inject('geodb')
|
||||
->inject('audit')
|
||||
->callback($this->action(...));
|
||||
}
|
||||
|
||||
public function action(string $databaseId, string $collectionId, string $documentId, array $queries, UtopiaResponse $response, Database $dbForProject, Locale $locale, Reader $geodb): void
|
||||
public function action(string $databaseId, string $collectionId, string $documentId, array $queries, UtopiaResponse $response, Database $dbForProject, Locale $locale, Reader $geodb, Audit $audit): void
|
||||
{
|
||||
$database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
|
||||
if ($database->isEmpty()) {
|
||||
@@ -98,12 +99,16 @@ class XList extends Action
|
||||
throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage());
|
||||
}
|
||||
|
||||
$audit = new Audit($dbForProject);
|
||||
$type = $this->getCollectionsEventsContext();
|
||||
$context = $this->getContext();
|
||||
$resource = "database/$databaseId/$type/$collectionId/$context/{$document->getId()}";
|
||||
|
||||
$logs = $audit->getLogsByResource($resource, $queries);
|
||||
|
||||
$grouped = Query::groupByType($queries);
|
||||
$limit = $grouped['limit'] ?? 25;
|
||||
$offset = $grouped['offset'] ?? 0;
|
||||
|
||||
$logs = $audit->getLogsByResource($resource, limit: $limit, offset: $offset);
|
||||
|
||||
$output = [];
|
||||
|
||||
@@ -152,7 +157,7 @@ class XList extends Action
|
||||
|
||||
$response->dynamic(new Document([
|
||||
'logs' => $output,
|
||||
'total' => $audit->countLogsByResource($resource, $queries),
|
||||
'total' => $audit->countLogsByResource($resource),
|
||||
]), $this->getResponseModel());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,10 +71,11 @@ class XList extends Action
|
||||
->inject('dbForProject')
|
||||
->inject('locale')
|
||||
->inject('geodb')
|
||||
->inject('audit')
|
||||
->callback($this->action(...));
|
||||
}
|
||||
|
||||
public function action(string $databaseId, string $collectionId, array $queries, UtopiaResponse $response, Database $dbForProject, Locale $locale, Reader $geodb): void
|
||||
public function action(string $databaseId, string $collectionId, array $queries, UtopiaResponse $response, Database $dbForProject, Locale $locale, Reader $geodb, Audit $audit): void
|
||||
{
|
||||
$database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
|
||||
|
||||
@@ -95,10 +96,13 @@ class XList extends Action
|
||||
throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage());
|
||||
}
|
||||
|
||||
$audit = new Audit($dbForProject);
|
||||
$grouped = Query::groupByType($queries);
|
||||
$limit = $grouped['limit'] ?? 25;
|
||||
$offset = $grouped['offset'] ?? 0;
|
||||
|
||||
$context = $this->getContext();
|
||||
$resource = "database/$databaseId/$context/$collectionId";
|
||||
$logs = $audit->getLogsByResource($resource, $queries);
|
||||
$logs = $audit->getLogsByResource($resource, limit: $limit, offset: $offset);
|
||||
|
||||
$output = [];
|
||||
|
||||
@@ -147,7 +151,7 @@ class XList extends Action
|
||||
|
||||
$response->dynamic(new Document([
|
||||
'logs' => $output,
|
||||
'total' => $audit->countLogsByResource($resource, $queries),
|
||||
'total' => $audit->countLogsByResource($resource),
|
||||
]), $this->getResponseModel());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,10 +67,11 @@ class XList extends Action
|
||||
->inject('dbForProject')
|
||||
->inject('locale')
|
||||
->inject('geodb')
|
||||
->inject('audit')
|
||||
->callback($this->action(...));
|
||||
}
|
||||
|
||||
public function action(string $databaseId, array $queries, UtopiaResponse $response, Database $dbForProject, Locale $locale, Reader $geodb): void
|
||||
public function action(string $databaseId, array $queries, UtopiaResponse $response, Database $dbForProject, Locale $locale, Reader $geodb, Audit $audit): void
|
||||
{
|
||||
$database = $dbForProject->getDocument('databases', $databaseId);
|
||||
|
||||
@@ -84,9 +85,13 @@ class XList extends Action
|
||||
throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage());
|
||||
}
|
||||
|
||||
$audit = new Audit($dbForProject);
|
||||
|
||||
$grouped = Query::groupByType($queries);
|
||||
$limit = $grouped['limit'] ?? 25;
|
||||
$offset = $grouped['offset'] ?? 0;
|
||||
|
||||
$resource = 'database/' . $databaseId;
|
||||
$logs = $audit->getLogsByResource($resource, $queries);
|
||||
$logs = $audit->getLogsByResource($resource, limit: $limit, offset: $offset);
|
||||
|
||||
$output = [];
|
||||
|
||||
@@ -133,7 +138,7 @@ class XList extends Action
|
||||
}
|
||||
|
||||
$response->dynamic(new Document([
|
||||
'total' => $audit->countLogsByResource($resource, $queries),
|
||||
'total' => $audit->countLogsByResource($resource),
|
||||
'logs' => $output,
|
||||
]), UtopiaResponse::MODEL_LOG_LIST);
|
||||
}
|
||||
|
||||
@@ -62,10 +62,11 @@ class XList extends Action
|
||||
->inject('dbForProject')
|
||||
->inject('locale')
|
||||
->inject('geodb')
|
||||
->inject('audit')
|
||||
->callback($this->action(...));
|
||||
}
|
||||
|
||||
public function action(string $databaseId, array $queries, UtopiaResponse $response, Database $dbForProject, Locale $locale, Reader $geodb): void
|
||||
public function action(string $databaseId, array $queries, UtopiaResponse $response, Database $dbForProject, Locale $locale, Reader $geodb, Audit $audit): void
|
||||
{
|
||||
$database = $dbForProject->getDocument('databases', $databaseId);
|
||||
|
||||
@@ -79,9 +80,12 @@ class XList extends Action
|
||||
throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage());
|
||||
}
|
||||
|
||||
$audit = new Audit($dbForProject);
|
||||
$grouped = Query::groupByType($queries);
|
||||
$limit = $grouped['limit'] ?? 25;
|
||||
$offset = $grouped['offset'] ?? 0;
|
||||
|
||||
$resource = 'database/' . $databaseId;
|
||||
$logs = $audit->getLogsByResource($resource, $queries);
|
||||
$logs = $audit->getLogsByResource($resource, limit: $limit, offset: $offset);
|
||||
|
||||
$output = [];
|
||||
|
||||
@@ -128,7 +132,7 @@ class XList extends Action
|
||||
}
|
||||
|
||||
$response->dynamic(new Document([
|
||||
'total' => $audit->countLogsByResource($resource, $queries),
|
||||
'total' => $audit->countLogsByResource($resource),
|
||||
'logs' => $output,
|
||||
]), UtopiaResponse::MODEL_LOG_LIST);
|
||||
}
|
||||
|
||||
@@ -50,6 +50,7 @@ class XList extends CollectionLogXList
|
||||
->inject('dbForProject')
|
||||
->inject('locale')
|
||||
->inject('geodb')
|
||||
->inject('audit')
|
||||
->callback($this->action(...));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,6 +51,7 @@ class XList extends DocumentLogXList
|
||||
->inject('dbForProject')
|
||||
->inject('locale')
|
||||
->inject('geodb')
|
||||
->inject('audit')
|
||||
->callback($this->action(...));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ namespace Appwrite\Platform\Workers;
|
||||
|
||||
use Exception;
|
||||
use Throwable;
|
||||
use Utopia\Audit\Audit;
|
||||
use Utopia\CLI\Console;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Database\Exception\Authorization;
|
||||
@@ -42,8 +41,8 @@ class Audits extends Action
|
||||
$this
|
||||
->desc('Audits worker')
|
||||
->inject('message')
|
||||
->inject('getProjectDB')
|
||||
->inject('project')
|
||||
->inject('getAudit')
|
||||
->callback($this->action(...));
|
||||
|
||||
$this->lastTriggeredTime = time();
|
||||
@@ -54,13 +53,14 @@ class Audits extends Action
|
||||
* @param Message $message
|
||||
* @param callable $getProjectDB
|
||||
* @param Document $project
|
||||
* @param callable $getAudit
|
||||
* @return Commit|NoCommit
|
||||
* @throws Throwable
|
||||
* @throws \Utopia\Database\Exception
|
||||
* @throws Authorization
|
||||
* @throws Structure
|
||||
*/
|
||||
public function action(Message $message, callable $getProjectDB, Document $project): Commit|NoCommit
|
||||
public function action(Message $message, Document $project, callable $getAudit): Commit|NoCommit
|
||||
{
|
||||
$payload = $message->getPayload() ?? [];
|
||||
|
||||
@@ -102,7 +102,7 @@ class Audits extends Action
|
||||
'mode' => $mode,
|
||||
'data' => $auditPayload,
|
||||
],
|
||||
'timestamp' => date("Y-m-d H:i:s", $message->getTimestamp()),
|
||||
'time' => date("Y-m-d H:i:s", $message->getTimestamp()),
|
||||
];
|
||||
|
||||
if (isset($this->logs[$project->getSequence()])) {
|
||||
@@ -135,8 +135,7 @@ class Audits extends Action
|
||||
Console::log('Processing Project "' . $sequence . '" batch with ' . count($projectLogs['logs']) . ' events');
|
||||
|
||||
$projectDocument = $projectLogs['project'];
|
||||
$dbForProject = $getProjectDB($projectDocument);
|
||||
$audit = new Audit($dbForProject);
|
||||
$audit = $getAudit($projectDocument);
|
||||
$audit->logBatch($projectLogs['logs']);
|
||||
|
||||
Console::success('Audit logs processed successfully');
|
||||
|
||||
@@ -9,6 +9,7 @@ use Appwrite\Extend\Exception;
|
||||
use Executor\Executor;
|
||||
use Throwable;
|
||||
use Utopia\Abuse\Adapters\TimeLimit\Database as AbuseDatabase;
|
||||
use Utopia\Audit\Adapter\SQL;
|
||||
use Utopia\Audit\Audit;
|
||||
use Utopia\Cache\Adapter\Filesystem;
|
||||
use Utopia\Cache\Cache;
|
||||
@@ -62,6 +63,7 @@ class Deletes extends Action
|
||||
->inject('executionRetention')
|
||||
->inject('auditRetention')
|
||||
->inject('log')
|
||||
->inject('getAudit')
|
||||
->callback($this->action(...));
|
||||
}
|
||||
|
||||
@@ -84,7 +86,8 @@ class Deletes extends Action
|
||||
Executor $executor,
|
||||
string $executionRetention,
|
||||
string $auditRetention,
|
||||
Log $log
|
||||
Log $log,
|
||||
callable $getAudit,
|
||||
): void {
|
||||
$payload = $message->getPayload() ?? [];
|
||||
|
||||
@@ -145,7 +148,7 @@ class Deletes extends Action
|
||||
break;
|
||||
case DELETE_TYPE_AUDIT:
|
||||
if (!$project->isEmpty()) {
|
||||
$this->deleteAuditLogs($project, $getProjectDB, $auditRetention);
|
||||
$this->deleteAuditLogs($project, $auditRetention, $getAudit);
|
||||
}
|
||||
break;
|
||||
case DELETE_TYPE_REALTIME:
|
||||
@@ -517,7 +520,7 @@ class Deletes extends Action
|
||||
|
||||
$projectCollectionIds = [
|
||||
...\array_keys(Config::getParam('collections', [])['projects']),
|
||||
Audit::COLLECTION,
|
||||
SQL::COLLECTION,
|
||||
AbuseDatabase::COLLECTION,
|
||||
];
|
||||
|
||||
@@ -783,23 +786,20 @@ class Deletes extends Action
|
||||
* @param Database $dbForPlatform
|
||||
* @param callable $getProjectDB
|
||||
* @param string $auditRetention
|
||||
* @param callable $getAudit
|
||||
* @return void
|
||||
* @throws Exception
|
||||
*/
|
||||
private function deleteAuditLogs(Document $project, callable $getProjectDB, string $auditRetention): void
|
||||
private function deleteAuditLogs(Document $project, string $auditRetention, callable $getAudit): void
|
||||
{
|
||||
$projectId = $project->getId();
|
||||
$dbForProject = $getProjectDB($project);
|
||||
/** @var Audit $audit */
|
||||
$audit = $getAudit($project);
|
||||
|
||||
try {
|
||||
$this->deleteByGroup(Audit::COLLECTION, [
|
||||
Query::select([...$this->selects, 'time']),
|
||||
Query::lessThan('time', $auditRetention),
|
||||
Query::orderDesc('time'),
|
||||
Query::orderAsc(),
|
||||
], $dbForProject);
|
||||
} catch (DatabaseException $e) {
|
||||
Console::error('Failed to delete audit logs for project ' . $projectId . ': ' . $e->getMessage());
|
||||
$audit->cleanup(new \DateTime($auditRetention));
|
||||
} catch (Throwable $th) {
|
||||
Console::error('Failed to delete audit logs for project ' . $projectId . ': ' . $th->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user