From d5f959454b3f569136984fa04d8fa4dd72dbd6b9 Mon Sep 17 00:00:00 2001 From: Torsten Dittmann Date: Mon, 15 Nov 2021 10:48:32 +0100 Subject: [PATCH 01/13] feat(controllers): add pagination to logs endpoints --- app/controllers/api/account.php | 7 +++++-- app/controllers/api/database.php | 6 ++++-- app/controllers/api/users.php | 6 ++++-- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php index ded17b58c1..caf8e5cdaf 100644 --- a/app/controllers/api/account.php +++ b/app/controllers/api/account.php @@ -23,6 +23,7 @@ use Utopia\Database\Validator\UID; use Utopia\Exception; use Utopia\Validator\ArrayList; use Utopia\Validator\Assoc; +use Utopia\Validator\Range; use Utopia\Validator\Text; use Utopia\Validator\WhiteList; @@ -1182,13 +1183,15 @@ App::get('/v1/account/logs') ->label('sdk.response.code', Response::STATUS_CODE_OK) ->label('sdk.response.type', Response::CONTENT_TYPE_JSON) ->label('sdk.response.model', Response::MODEL_LOG_LIST) + ->param('limit', 25, new Range(0, 100), 'Maximum number of documents to return in response. Use this value to manage pagination. By default will return maximum 25 results. Maximum of 100 results allowed per request.', true) + ->param('offset', 0, new Range(0, 900000000), 'Offset value. The default value is 0. Use this param to manage pagination.', true) ->inject('response') ->inject('user') ->inject('locale') ->inject('geodb') ->inject('dbForInternal') ->inject('usage') - ->action(function ($response, $user, $locale, $geodb, $dbForInternal, $usage) { + ->action(function ($limit, $offset, $response, $user, $locale, $geodb, $dbForInternal, $usage) { /** @var Appwrite\Utopia\Response $response */ /** @var Utopia\Database\Document $project */ /** @var Utopia\Database\Document $user */ @@ -1215,7 +1218,7 @@ App::get('/v1/account/logs') 'teams.membership.create', 'teams.membership.update', 'teams.membership.delete', - ]); + ], $limit, $offset); $output = []; diff --git a/app/controllers/api/database.php b/app/controllers/api/database.php index 5b228d6004..568b049341 100644 --- a/app/controllers/api/database.php +++ b/app/controllers/api/database.php @@ -458,12 +458,14 @@ App::get('/v1/database/collections/:collectionId/logs') ->label('sdk.response.type', Response::CONTENT_TYPE_JSON) ->label('sdk.response.model', Response::MODEL_LOG_LIST) ->param('collectionId', '', new UID(), 'Collection unique ID.') + ->param('limit', 25, new Range(0, 100), 'Maximum number of documents to return in response. Use this value to manage pagination. By default will return maximum 25 results. Maximum of 100 results allowed per request.', true) + ->param('offset', 0, new Range(0, 900000000), 'Offset value. The default value is 0. Use this param to manage pagination.', true) ->inject('response') ->inject('dbForInternal') ->inject('dbForExternal') ->inject('locale') ->inject('geodb') - ->action(function ($collectionId, $response, $dbForInternal, $dbForExternal, $locale, $geodb) { + ->action(function ($collectionId, $limit, $offset, $response, $dbForInternal, $dbForExternal, $locale, $geodb) { /** @var Appwrite\Utopia\Response $response */ /** @var Utopia\Database\Document $project */ /** @var Utopia\Database\Database $dbForInternal */ @@ -479,7 +481,7 @@ App::get('/v1/database/collections/:collectionId/logs') $audit = new Audit($dbForInternal); - $logs = $audit->getLogsByResource('collection/'.$collection->getId()); + $logs = $audit->getLogsByResource('collection/'.$collection->getId(), $limit, $offset); $output = []; diff --git a/app/controllers/api/users.php b/app/controllers/api/users.php index d6c9f1212f..923f82b451 100644 --- a/app/controllers/api/users.php +++ b/app/controllers/api/users.php @@ -259,12 +259,14 @@ App::get('/v1/users/:userId/logs') ->label('sdk.response.type', Response::CONTENT_TYPE_JSON) ->label('sdk.response.model', Response::MODEL_LOG_LIST) ->param('userId', '', new UID(), 'User unique ID.') + ->param('limit', 25, new Range(0, 100), 'Maximum number of documents to return in response. Use this value to manage pagination. By default will return maximum 25 results. Maximum of 100 results allowed per request.', true) + ->param('offset', 0, new Range(0, 900000000), 'Offset value. The default value is 0. Use this param to manage pagination.', true) ->inject('response') ->inject('dbForInternal') ->inject('locale') ->inject('geodb') ->inject('usage') - ->action(function ($userId, $response, $dbForInternal, $locale, $geodb, $usage) { + ->action(function ($userId, $limit, $offset, $response, $dbForInternal, $locale, $geodb, $usage) { /** @var Appwrite\Utopia\Response $response */ /** @var Utopia\Database\Document $project */ /** @var Utopia\Database\Database $dbForInternal */ @@ -296,7 +298,7 @@ App::get('/v1/users/:userId/logs') 'teams.membership.create', 'teams.membership.update', 'teams.membership.delete', - ]); + ], $limit, $offset); $output = []; From b1263e96038f52d3f664dbc5146308e33625bba2 Mon Sep 17 00:00:00 2001 From: Torsten Dittmann Date: Mon, 15 Nov 2021 10:49:11 +0100 Subject: [PATCH 02/13] tests(logs): test pagination on logs endpoints --- tests/e2e/Services/Account/AccountBase.php | 61 +++++++++++++++++-- .../Database/DatabaseConsoleClientTest.php | 54 +++++++++++++++- tests/e2e/Services/Users/UsersBase.php | 59 +++++++++++++++--- 3 files changed, 158 insertions(+), 16 deletions(-) diff --git a/tests/e2e/Services/Account/AccountBase.php b/tests/e2e/Services/Account/AccountBase.php index bcb4208917..200cdc3ddb 100644 --- a/tests/e2e/Services/Account/AccountBase.php +++ b/tests/e2e/Services/Account/AccountBase.php @@ -283,10 +283,10 @@ trait AccountBase $this->assertEquals('', $response['body']['sessions'][0]['deviceBrand']); $this->assertEquals('', $response['body']['sessions'][0]['deviceModel']); $this->assertEquals($response['body']['sessions'][0]['ip'], filter_var($response['body']['sessions'][0]['ip'], FILTER_VALIDATE_IP)); - + $this->assertEquals('--', $response['body']['sessions'][0]['countryCode']); $this->assertEquals('Unknown', $response['body']['sessions'][0]['countryName']); - + $this->assertEquals(true, $response['body']['sessions'][0]['current']); /** @@ -325,7 +325,7 @@ trait AccountBase $this->assertIsArray($response['body']['logs']); $this->assertNotEmpty($response['body']['logs']); $this->assertCount(2, $response['body']['logs']); - + $this->assertContains($response['body']['logs'][0]['event'], ['account.create', 'account.sessions.create']); $this->assertEquals($response['body']['logs'][0]['ip'], filter_var($response['body']['logs'][0]['ip'], FILTER_VALIDATE_IP)); $this->assertIsNumeric($response['body']['logs'][0]['time']); @@ -344,7 +344,7 @@ trait AccountBase $this->assertEquals('', $response['body']['logs'][0]['deviceBrand']); $this->assertEquals('', $response['body']['logs'][0]['deviceModel']); $this->assertEquals($response['body']['logs'][0]['ip'], filter_var($response['body']['logs'][0]['ip'], FILTER_VALIDATE_IP)); - + $this->assertEquals('--', $response['body']['logs'][0]['countryCode']); $this->assertEquals('Unknown', $response['body']['logs'][0]['countryName']); @@ -366,10 +366,59 @@ trait AccountBase $this->assertEquals('', $response['body']['logs'][1]['deviceBrand']); $this->assertEquals('', $response['body']['logs'][1]['deviceModel']); $this->assertEquals($response['body']['logs'][1]['ip'], filter_var($response['body']['logs'][1]['ip'], FILTER_VALIDATE_IP)); - + $this->assertEquals('--', $response['body']['logs'][1]['countryCode']); $this->assertEquals('Unknown', $response['body']['logs'][1]['countryName']); - + + $responseLimit = $this->client->call(Client::METHOD_GET, '/account/logs', array_merge([ + 'origin' => 'http://localhost', + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'cookie' => 'a_session_'.$this->getProject()['$id'].'=' . $session, + ]), [ + 'limit' => 1 + ]); + + $this->assertEquals($responseLimit['headers']['status-code'], 200); + $this->assertIsArray($responseLimit['body']['logs']); + $this->assertNotEmpty($responseLimit['body']['logs']); + $this->assertCount(1, $responseLimit['body']['logs']); + + $this->assertEquals($response['body']['logs'][0], $responseLimit['body']['logs'][0]); + + + $responseOffset = $this->client->call(Client::METHOD_GET, '/account/logs', array_merge([ + 'origin' => 'http://localhost', + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'cookie' => 'a_session_'.$this->getProject()['$id'].'=' . $session, + ]), [ + 'offset' => 1 + ]); + + $this->assertEquals($responseOffset['headers']['status-code'], 200); + $this->assertIsArray($responseOffset['body']['logs']); + $this->assertNotEmpty($responseOffset['body']['logs']); + $this->assertCount(1, $responseOffset['body']['logs']); + + $this->assertEquals($response['body']['logs'][1], $responseOffset['body']['logs'][0]); + + $responseLimitOffset = $this->client->call(Client::METHOD_GET, '/account/logs', array_merge([ + 'origin' => 'http://localhost', + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'cookie' => 'a_session_'.$this->getProject()['$id'].'=' . $session, + ]), [ + 'limit' => 1, + 'offset' => 1 + ]); + + $this->assertEquals($responseLimitOffset['headers']['status-code'], 200); + $this->assertIsArray($responseLimitOffset['body']['logs']); + $this->assertNotEmpty($responseLimitOffset['body']['logs']); + $this->assertCount(1, $responseLimitOffset['body']['logs']); + + $this->assertEquals($response['body']['logs'][1], $responseLimitOffset['body']['logs'][0]); /** * Test for FAILURE */ diff --git a/tests/e2e/Services/Database/DatabaseConsoleClientTest.php b/tests/e2e/Services/Database/DatabaseConsoleClientTest.php index 625f26107b..c98614c5f4 100644 --- a/tests/e2e/Services/Database/DatabaseConsoleClientTest.php +++ b/tests/e2e/Services/Database/DatabaseConsoleClientTest.php @@ -33,7 +33,7 @@ class DatabaseConsoleClientTest extends Scope return ['moviesId' => $movies['body']['$id']]; } - + public function testGetDatabaseUsage() { /** @@ -48,7 +48,7 @@ class DatabaseConsoleClientTest extends Scope ]); $this->assertEquals($response['headers']['status-code'], 400); - + /** * Test for SUCCESS */ @@ -122,4 +122,54 @@ class DatabaseConsoleClientTest extends Scope $this->assertIsArray($response['body']['documents.update']); $this->assertIsArray($response['body']['documents.delete']); } + + /** + * @depends testCreateCollection + */ + public function testGetCollectionLogs(array $data) + { + /** + * Test for SUCCESS + */ + $logs = $this->client->call(Client::METHOD_GET, '/database/collections/' . $data['moviesId'] . '/logs', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals($logs['headers']['status-code'], 200); + $this->assertIsArray($logs['body']['logs']); + + $logs = $this->client->call(Client::METHOD_GET, '/database/collections/' . $data['moviesId'] . '/logs', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'limit' => 1 + ]); + + $this->assertEquals($logs['headers']['status-code'], 200); + $this->assertIsArray($logs['body']['logs']); + $this->assertLessThanOrEqual(1, count($logs['body']['logs'])); + + $logs = $this->client->call(Client::METHOD_GET, '/database/collections/' . $data['moviesId'] . '/logs', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'offset' => 1 + ]); + + $this->assertEquals($logs['headers']['status-code'], 200); + $this->assertIsArray($logs['body']['logs']); + + $logs = $this->client->call(Client::METHOD_GET, '/database/collections/' . $data['moviesId'] . '/logs', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'offset' => 1, + 'limit' => 1 + ]); + + $this->assertEquals($logs['headers']['status-code'], 200); + $this->assertIsArray($logs['body']['logs']); + $this->assertLessThanOrEqual(1, count($logs['body']['logs'])); + } } \ No newline at end of file diff --git a/tests/e2e/Services/Users/UsersBase.php b/tests/e2e/Services/Users/UsersBase.php index 89c9cdf8ac..2d51be8312 100644 --- a/tests/e2e/Services/Users/UsersBase.php +++ b/tests/e2e/Services/Users/UsersBase.php @@ -204,14 +204,6 @@ trait UsersBase $this->assertEquals($sessions['headers']['status-code'], 200); $this->assertIsArray($sessions['body']); - $logs = $this->client->call(Client::METHOD_GET, '/users/' . $data['userId'] . '/logs', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders())); - - $this->assertEquals($logs['headers']['status-code'], 200); - $this->assertIsArray($logs['body']); - $users = $this->client->call(Client::METHOD_GET, '/users', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], @@ -428,6 +420,57 @@ trait UsersBase return $data; } + + /** + * @depends testGetUser + */ + public function testGetLogs(array $data): void + { + /** + * Test for SUCCESS + */ + $logs = $this->client->call(Client::METHOD_GET, '/users/' . $data['userId'] . '/logs', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals($logs['headers']['status-code'], 200); + $this->assertIsArray($logs['body']['logs']); + + $logs = $this->client->call(Client::METHOD_GET, '/users/' . $data['userId'] . '/logs', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'limit' => 1 + ]); + + $this->assertEquals($logs['headers']['status-code'], 200); + $this->assertIsArray($logs['body']['logs']); + $this->assertLessThanOrEqual(1, count($logs['body']['logs'])); + + $logs = $this->client->call(Client::METHOD_GET, '/users/' . $data['userId'] . '/logs', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'offset' => 1 + ]); + + $this->assertEquals($logs['headers']['status-code'], 200); + $this->assertIsArray($logs['body']['logs']); + + $logs = $this->client->call(Client::METHOD_GET, '/users/' . $data['userId'] . '/logs', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'offset' => 1, + 'limit' => 1 + ]); + + $this->assertEquals($logs['headers']['status-code'], 200); + $this->assertIsArray($logs['body']['logs']); + $this->assertLessThanOrEqual(1, count($logs['body']['logs'])); + } + /** * @depends testGetUser */ From fd3e46bbcb7c7d65a7114f4137a30ef8e547c1b6 Mon Sep 17 00:00:00 2001 From: Torsten Dittmann Date: Mon, 15 Nov 2021 10:49:21 +0100 Subject: [PATCH 03/13] feat(chore): update composer lock --- composer.lock | 104 +++++++++++++++++++++++++------------------------- 1 file changed, 52 insertions(+), 52 deletions(-) diff --git a/composer.lock b/composer.lock index 9ad7258756..220869038e 100644 --- a/composer.lock +++ b/composer.lock @@ -2138,16 +2138,16 @@ }, { "name": "utopia-php/database", - "version": "0.10.0", + "version": "0.10.1", "source": { "type": "git", "url": "https://github.com/utopia-php/database.git", - "reference": "b7c60b0ec769a9050dd2b939b78ff1f5d4fa27e8" + "reference": "9b4697612a2cd1ad55beeb6a02570f6ffe26dc1e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/database/zipball/b7c60b0ec769a9050dd2b939b78ff1f5d4fa27e8", - "reference": "b7c60b0ec769a9050dd2b939b78ff1f5d4fa27e8", + "url": "https://api.github.com/repos/utopia-php/database/zipball/9b4697612a2cd1ad55beeb6a02570f6ffe26dc1e", + "reference": "9b4697612a2cd1ad55beeb6a02570f6ffe26dc1e", "shasum": "" }, "require": { @@ -2195,9 +2195,9 @@ ], "support": { "issues": "https://github.com/utopia-php/database/issues", - "source": "https://github.com/utopia-php/database/tree/0.10.0" + "source": "https://github.com/utopia-php/database/tree/0.10.1" }, - "time": "2021-10-04T17:23:25+00:00" + "time": "2021-11-02T15:10:39+00:00" }, { "name": "utopia-php/domains", @@ -2304,20 +2304,19 @@ }, { "name": "utopia-php/image", - "version": "0.5.2", + "version": "0.5.3", "source": { "type": "git", "url": "https://github.com/utopia-php/image.git", - "reference": "049446fea7cb53db8a431455ec382e30e6d1482a" + "reference": "4a8429b62dcf56562b038d6712375f75166f0c02" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/image/zipball/049446fea7cb53db8a431455ec382e30e6d1482a", - "reference": "049446fea7cb53db8a431455ec382e30e6d1482a", + "url": "https://api.github.com/repos/utopia-php/image/zipball/4a8429b62dcf56562b038d6712375f75166f0c02", + "reference": "4a8429b62dcf56562b038d6712375f75166f0c02", "shasum": "" }, "require": { - "chillerlan/php-qrcode": "4.3.1", "ext-imagick": "*", "php": ">=7.4" }, @@ -2351,9 +2350,9 @@ ], "support": { "issues": "https://github.com/utopia-php/image/issues", - "source": "https://github.com/utopia-php/image/tree/0.5.2" + "source": "https://github.com/utopia-php/image/tree/0.5.3" }, - "time": "2021-10-18T06:41:05+00:00" + "time": "2021-11-02T05:47:16+00:00" }, { "name": "utopia-php/locale", @@ -3656,16 +3655,16 @@ }, { "name": "nikic/php-parser", - "version": "v4.13.0", + "version": "v4.13.1", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "50953a2691a922aa1769461637869a0a2faa3f53" + "reference": "63a79e8daa781cac14e5195e63ed8ae231dd10fd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/50953a2691a922aa1769461637869a0a2faa3f53", - "reference": "50953a2691a922aa1769461637869a0a2faa3f53", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/63a79e8daa781cac14e5195e63ed8ae231dd10fd", + "reference": "63a79e8daa781cac14e5195e63ed8ae231dd10fd", "shasum": "" }, "require": { @@ -3706,9 +3705,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v4.13.0" + "source": "https://github.com/nikic/PHP-Parser/tree/v4.13.1" }, - "time": "2021-09-20T12:20:58+00:00" + "time": "2021-11-03T20:52:16+00:00" }, { "name": "openlss/lib-array2xml", @@ -4103,23 +4102,23 @@ }, { "name": "phpunit/php-code-coverage", - "version": "9.2.7", + "version": "9.2.8", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "d4c798ed8d51506800b441f7a13ecb0f76f12218" + "reference": "cf04e88a2e3c56fc1a65488afd493325b4c1bc3e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/d4c798ed8d51506800b441f7a13ecb0f76f12218", - "reference": "d4c798ed8d51506800b441f7a13ecb0f76f12218", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/cf04e88a2e3c56fc1a65488afd493325b4c1bc3e", + "reference": "cf04e88a2e3c56fc1a65488afd493325b4c1bc3e", "shasum": "" }, "require": { "ext-dom": "*", "ext-libxml": "*", "ext-xmlwriter": "*", - "nikic/php-parser": "^4.12.0", + "nikic/php-parser": "^4.13.0", "php": ">=7.3", "phpunit/php-file-iterator": "^3.0.3", "phpunit/php-text-template": "^2.0.2", @@ -4168,7 +4167,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.7" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.8" }, "funding": [ { @@ -4176,7 +4175,7 @@ "type": "github" } ], - "time": "2021-09-17T05:39:03+00:00" + "time": "2021-10-30T08:01:38+00:00" }, { "name": "phpunit/php-file-iterator", @@ -4524,20 +4523,20 @@ }, { "name": "psr/container", - "version": "1.1.1", + "version": "1.1.2", "source": { "type": "git", "url": "https://github.com/php-fig/container.git", - "reference": "8622567409010282b7aeebe4bb841fe98b58dcaf" + "reference": "513e0666f7216c7459170d56df27dfcefe1689ea" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/container/zipball/8622567409010282b7aeebe4bb841fe98b58dcaf", - "reference": "8622567409010282b7aeebe4bb841fe98b58dcaf", + "url": "https://api.github.com/repos/php-fig/container/zipball/513e0666f7216c7459170d56df27dfcefe1689ea", + "reference": "513e0666f7216c7459170d56df27dfcefe1689ea", "shasum": "" }, "require": { - "php": ">=7.2.0" + "php": ">=7.4.0" }, "type": "library", "autoload": { @@ -4566,9 +4565,9 @@ ], "support": { "issues": "https://github.com/php-fig/container/issues", - "source": "https://github.com/php-fig/container/tree/1.1.1" + "source": "https://github.com/php-fig/container/tree/1.1.2" }, - "time": "2021-03-05T17:36:06+00:00" + "time": "2021-11-05T16:50:12+00:00" }, { "name": "sebastian/cli-parser", @@ -4999,16 +4998,16 @@ }, { "name": "sebastian/exporter", - "version": "4.0.3", + "version": "4.0.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "d89cc98761b8cb5a1a235a6b703ae50d34080e65" + "reference": "65e8b7db476c5dd267e65eea9cab77584d3cfff9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/d89cc98761b8cb5a1a235a6b703ae50d34080e65", - "reference": "d89cc98761b8cb5a1a235a6b703ae50d34080e65", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/65e8b7db476c5dd267e65eea9cab77584d3cfff9", + "reference": "65e8b7db476c5dd267e65eea9cab77584d3cfff9", "shasum": "" }, "require": { @@ -5057,14 +5056,14 @@ } ], "description": "Provides the functionality to export PHP variables for visualization", - "homepage": "http://www.github.com/sebastianbergmann/exporter", + "homepage": "https://www.github.com/sebastianbergmann/exporter", "keywords": [ "export", "exporter" ], "support": { "issues": "https://github.com/sebastianbergmann/exporter/issues", - "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.3" + "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.4" }, "funding": [ { @@ -5072,7 +5071,7 @@ "type": "github" } ], - "time": "2020-09-28T05:24:23+00:00" + "time": "2021-11-11T14:18:36+00:00" }, { "name": "sebastian/global-state", @@ -5588,16 +5587,16 @@ }, { "name": "symfony/console", - "version": "v5.3.7", + "version": "v5.3.10", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "8b1008344647462ae6ec57559da166c2bfa5e16a" + "reference": "d4e409d9fbcfbf71af0e5a940abb7b0b4bad0bd3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/8b1008344647462ae6ec57559da166c2bfa5e16a", - "reference": "8b1008344647462ae6ec57559da166c2bfa5e16a", + "url": "https://api.github.com/repos/symfony/console/zipball/d4e409d9fbcfbf71af0e5a940abb7b0b4bad0bd3", + "reference": "d4e409d9fbcfbf71af0e5a940abb7b0b4bad0bd3", "shasum": "" }, "require": { @@ -5667,7 +5666,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v5.3.7" + "source": "https://github.com/symfony/console/tree/v5.3.10" }, "funding": [ { @@ -5683,7 +5682,7 @@ "type": "tidelift" } ], - "time": "2021-08-25T20:02:16+00:00" + "time": "2021-10-26T09:30:15+00:00" }, { "name": "symfony/polyfill-intl-grapheme", @@ -6090,16 +6089,16 @@ }, { "name": "symfony/string", - "version": "v5.3.7", + "version": "v5.3.10", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "8d224396e28d30f81969f083a58763b8b9ceb0a5" + "reference": "d70c35bb20bbca71fc4ab7921e3c6bda1a82a60c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/8d224396e28d30f81969f083a58763b8b9ceb0a5", - "reference": "8d224396e28d30f81969f083a58763b8b9ceb0a5", + "url": "https://api.github.com/repos/symfony/string/zipball/d70c35bb20bbca71fc4ab7921e3c6bda1a82a60c", + "reference": "d70c35bb20bbca71fc4ab7921e3c6bda1a82a60c", "shasum": "" }, "require": { @@ -6153,7 +6152,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v5.3.7" + "source": "https://github.com/symfony/string/tree/v5.3.10" }, "funding": [ { @@ -6169,7 +6168,7 @@ "type": "tidelift" } ], - "time": "2021-08-26T08:00:08+00:00" + "time": "2021-10-27T18:21:46+00:00" }, { "name": "textalk/websocket", @@ -6502,6 +6501,7 @@ "issues": "https://github.com/webmozart/path-util/issues", "source": "https://github.com/webmozart/path-util/tree/2.3.0" }, + "abandoned": "symfony/filesystem", "time": "2015-12-17T08:42:14+00:00" } ], From f8731e8d65b86ecbf9a20eeb7260736668d55909 Mon Sep 17 00:00:00 2001 From: Torsten Dittmann Date: Tue, 16 Nov 2021 12:02:11 +0100 Subject: [PATCH 04/13] fix(api): logs limit param description --- app/controllers/api/account.php | 2 +- app/controllers/api/database.php | 2 +- app/controllers/api/users.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php index caf8e5cdaf..be0532a460 100644 --- a/app/controllers/api/account.php +++ b/app/controllers/api/account.php @@ -1183,7 +1183,7 @@ App::get('/v1/account/logs') ->label('sdk.response.code', Response::STATUS_CODE_OK) ->label('sdk.response.type', Response::CONTENT_TYPE_JSON) ->label('sdk.response.model', Response::MODEL_LOG_LIST) - ->param('limit', 25, new Range(0, 100), 'Maximum number of documents to return in response. Use this value to manage pagination. By default will return maximum 25 results. Maximum of 100 results allowed per request.', true) + ->param('limit', 25, new Range(0, 100), 'Maximum number of logs to return in response. Use this value to manage pagination. By default will return maximum 25 results. Maximum of 100 results allowed per request.', true) ->param('offset', 0, new Range(0, 900000000), 'Offset value. The default value is 0. Use this param to manage pagination.', true) ->inject('response') ->inject('user') diff --git a/app/controllers/api/database.php b/app/controllers/api/database.php index 568b049341..200b2cff04 100644 --- a/app/controllers/api/database.php +++ b/app/controllers/api/database.php @@ -458,7 +458,7 @@ App::get('/v1/database/collections/:collectionId/logs') ->label('sdk.response.type', Response::CONTENT_TYPE_JSON) ->label('sdk.response.model', Response::MODEL_LOG_LIST) ->param('collectionId', '', new UID(), 'Collection unique ID.') - ->param('limit', 25, new Range(0, 100), 'Maximum number of documents to return in response. Use this value to manage pagination. By default will return maximum 25 results. Maximum of 100 results allowed per request.', true) + ->param('limit', 25, new Range(0, 100), 'Maximum number of logs to return in response. Use this value to manage pagination. By default will return maximum 25 results. Maximum of 100 results allowed per request.', true) ->param('offset', 0, new Range(0, 900000000), 'Offset value. The default value is 0. Use this param to manage pagination.', true) ->inject('response') ->inject('dbForInternal') diff --git a/app/controllers/api/users.php b/app/controllers/api/users.php index 923f82b451..489b807705 100644 --- a/app/controllers/api/users.php +++ b/app/controllers/api/users.php @@ -259,7 +259,7 @@ App::get('/v1/users/:userId/logs') ->label('sdk.response.type', Response::CONTENT_TYPE_JSON) ->label('sdk.response.model', Response::MODEL_LOG_LIST) ->param('userId', '', new UID(), 'User unique ID.') - ->param('limit', 25, new Range(0, 100), 'Maximum number of documents to return in response. Use this value to manage pagination. By default will return maximum 25 results. Maximum of 100 results allowed per request.', true) + ->param('limit', 25, new Range(0, 100), 'Maximum number of logs to return in response. Use this value to manage pagination. By default will return maximum 25 results. Maximum of 100 results allowed per request.', true) ->param('offset', 0, new Range(0, 900000000), 'Offset value. The default value is 0. Use this param to manage pagination.', true) ->inject('response') ->inject('dbForInternal') From 058b4dd97571092514f6c3a9984f47aef57961b8 Mon Sep 17 00:00:00 2001 From: Torsten Dittmann Date: Tue, 16 Nov 2021 12:20:14 +0100 Subject: [PATCH 05/13] fix(api): add after pagination to logs endpoints --- app/controllers/api/account.php | 13 +++++++++++-- app/controllers/api/database.php | 11 ++++++++++- app/controllers/api/users.php | 13 +++++++++++-- 3 files changed, 32 insertions(+), 5 deletions(-) diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php index be0532a460..db408d0548 100644 --- a/app/controllers/api/account.php +++ b/app/controllers/api/account.php @@ -1185,13 +1185,14 @@ App::get('/v1/account/logs') ->label('sdk.response.model', Response::MODEL_LOG_LIST) ->param('limit', 25, new Range(0, 100), 'Maximum number of logs to return in response. Use this value to manage pagination. By default will return maximum 25 results. Maximum of 100 results allowed per request.', true) ->param('offset', 0, new Range(0, 900000000), 'Offset value. The default value is 0. Use this param to manage pagination.', true) + ->param('after', '', new UID(), 'ID of the log used as the starting point for the query, excluding the document itself. Should be used for efficient pagination when working with large sets of data.', true) ->inject('response') ->inject('user') ->inject('locale') ->inject('geodb') ->inject('dbForInternal') ->inject('usage') - ->action(function ($limit, $offset, $response, $user, $locale, $geodb, $dbForInternal, $usage) { + ->action(function ($limit, $offset, $after, $response, $user, $locale, $geodb, $dbForInternal, $usage) { /** @var Appwrite\Utopia\Response $response */ /** @var Utopia\Database\Document $project */ /** @var Utopia\Database\Document $user */ @@ -1200,6 +1201,14 @@ App::get('/v1/account/logs') /** @var Utopia\Database\Database $dbForInternal */ /** @var Appwrite\Stats\Stats $usage */ + if (!empty($after)) { + $afterLog = $dbForInternal->getDocument('audit', $after); + + if ($afterLog->isEmpty()) { + throw new Exception("Log '{$after}' for the 'after' value not found.", 400); + } + } + $audit = new Audit($dbForInternal); $logs = $audit->getLogsByUserAndEvents($user->getId(), [ @@ -1218,7 +1227,7 @@ App::get('/v1/account/logs') 'teams.membership.create', 'teams.membership.update', 'teams.membership.delete', - ], $limit, $offset); + ], $limit, $offset, $afterLog ?? null); $output = []; diff --git a/app/controllers/api/database.php b/app/controllers/api/database.php index 200b2cff04..ce83c1abe3 100644 --- a/app/controllers/api/database.php +++ b/app/controllers/api/database.php @@ -460,6 +460,7 @@ App::get('/v1/database/collections/:collectionId/logs') ->param('collectionId', '', new UID(), 'Collection unique ID.') ->param('limit', 25, new Range(0, 100), 'Maximum number of logs to return in response. Use this value to manage pagination. By default will return maximum 25 results. Maximum of 100 results allowed per request.', true) ->param('offset', 0, new Range(0, 900000000), 'Offset value. The default value is 0. Use this param to manage pagination.', true) + ->param('after', '', new UID(), 'ID of the log used as the starting point for the query, excluding the document itself. Should be used for efficient pagination when working with large sets of data.', true) ->inject('response') ->inject('dbForInternal') ->inject('dbForExternal') @@ -479,9 +480,17 @@ App::get('/v1/database/collections/:collectionId/logs') throw new Exception('Collection not found', 404); } + if (!empty($after)) { + $afterLog = $dbForInternal->getDocument('audit', $after); + + if ($afterLog->isEmpty()) { + throw new Exception("Log '{$after}' for the 'after' value not found.", 400); + } + } + $audit = new Audit($dbForInternal); - $logs = $audit->getLogsByResource('collection/'.$collection->getId(), $limit, $offset); + $logs = $audit->getLogsByResource('collection/'.$collection->getId(), $limit, $offset, $afterLog ?? null); $output = []; diff --git a/app/controllers/api/users.php b/app/controllers/api/users.php index 489b807705..5cca14404e 100644 --- a/app/controllers/api/users.php +++ b/app/controllers/api/users.php @@ -261,12 +261,13 @@ App::get('/v1/users/:userId/logs') ->param('userId', '', new UID(), 'User unique ID.') ->param('limit', 25, new Range(0, 100), 'Maximum number of logs to return in response. Use this value to manage pagination. By default will return maximum 25 results. Maximum of 100 results allowed per request.', true) ->param('offset', 0, new Range(0, 900000000), 'Offset value. The default value is 0. Use this param to manage pagination.', true) + ->param('after', '', new UID(), 'ID of the log used as the starting point for the query, excluding the document itself. Should be used for efficient pagination when working with large sets of data.', true) ->inject('response') ->inject('dbForInternal') ->inject('locale') ->inject('geodb') ->inject('usage') - ->action(function ($userId, $limit, $offset, $response, $dbForInternal, $locale, $geodb, $usage) { + ->action(function ($userId, $limit, $offset, $after, $response, $dbForInternal, $locale, $geodb, $usage) { /** @var Appwrite\Utopia\Response $response */ /** @var Utopia\Database\Document $project */ /** @var Utopia\Database\Database $dbForInternal */ @@ -280,6 +281,14 @@ App::get('/v1/users/:userId/logs') throw new Exception('User not found', 404); } + if (!empty($after)) { + $afterLog = $dbForInternal->getDocument('audit', $after); + + if ($afterLog->isEmpty()) { + throw new Exception("Log '{$after}' for the 'after' value not found.", 400); + } + } + $audit = new Audit($dbForInternal); $logs = $audit->getLogsByUserAndEvents($user->getId(), [ @@ -298,7 +307,7 @@ App::get('/v1/users/:userId/logs') 'teams.membership.create', 'teams.membership.update', 'teams.membership.delete', - ], $limit, $offset); + ], $limit, $offset, $afterLog ?? null); $output = []; From 7034f84a6ea39662095cb1abab7b0aead456845e Mon Sep 17 00:00:00 2001 From: Torsten Dittmann Date: Tue, 16 Nov 2021 12:20:25 +0100 Subject: [PATCH 06/13] fix(response): add $id to Log --- src/Appwrite/Utopia/Response/Model/Log.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Appwrite/Utopia/Response/Model/Log.php b/src/Appwrite/Utopia/Response/Model/Log.php index 8752c6c872..ad468ce1c0 100644 --- a/src/Appwrite/Utopia/Response/Model/Log.php +++ b/src/Appwrite/Utopia/Response/Model/Log.php @@ -10,6 +10,12 @@ class Log extends Model public function __construct() { $this + ->addRule('$id', [ + 'type' => self::TYPE_STRING, + 'description' => 'Log ID.', + 'default' => '', + 'example' => '5e5ea5c16897e', + ]) ->addRule('event', [ 'type' => self::TYPE_STRING, 'description' => 'Event name.', From 78159ff8ca734209df28473a48faa4f1b0e0b9a5 Mon Sep 17 00:00:00 2001 From: Torsten Dittmann Date: Tue, 16 Nov 2021 14:37:28 +0100 Subject: [PATCH 07/13] Revert "fix(response): add $id to Log" This reverts commit 7034f84a6ea39662095cb1abab7b0aead456845e. --- src/Appwrite/Utopia/Response/Model/Log.php | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/Appwrite/Utopia/Response/Model/Log.php b/src/Appwrite/Utopia/Response/Model/Log.php index ad468ce1c0..8752c6c872 100644 --- a/src/Appwrite/Utopia/Response/Model/Log.php +++ b/src/Appwrite/Utopia/Response/Model/Log.php @@ -10,12 +10,6 @@ class Log extends Model public function __construct() { $this - ->addRule('$id', [ - 'type' => self::TYPE_STRING, - 'description' => 'Log ID.', - 'default' => '', - 'example' => '5e5ea5c16897e', - ]) ->addRule('event', [ 'type' => self::TYPE_STRING, 'description' => 'Event name.', From 19d01c17bba7edc5026555394f726497412c0481 Mon Sep 17 00:00:00 2001 From: Torsten Dittmann Date: Tue, 16 Nov 2021 14:37:33 +0100 Subject: [PATCH 08/13] Revert "fix(api): add after pagination to logs endpoints" This reverts commit 058b4dd97571092514f6c3a9984f47aef57961b8. --- app/controllers/api/account.php | 13 ++----------- app/controllers/api/database.php | 11 +---------- app/controllers/api/users.php | 13 ++----------- 3 files changed, 5 insertions(+), 32 deletions(-) diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php index db408d0548..be0532a460 100644 --- a/app/controllers/api/account.php +++ b/app/controllers/api/account.php @@ -1185,14 +1185,13 @@ App::get('/v1/account/logs') ->label('sdk.response.model', Response::MODEL_LOG_LIST) ->param('limit', 25, new Range(0, 100), 'Maximum number of logs to return in response. Use this value to manage pagination. By default will return maximum 25 results. Maximum of 100 results allowed per request.', true) ->param('offset', 0, new Range(0, 900000000), 'Offset value. The default value is 0. Use this param to manage pagination.', true) - ->param('after', '', new UID(), 'ID of the log used as the starting point for the query, excluding the document itself. Should be used for efficient pagination when working with large sets of data.', true) ->inject('response') ->inject('user') ->inject('locale') ->inject('geodb') ->inject('dbForInternal') ->inject('usage') - ->action(function ($limit, $offset, $after, $response, $user, $locale, $geodb, $dbForInternal, $usage) { + ->action(function ($limit, $offset, $response, $user, $locale, $geodb, $dbForInternal, $usage) { /** @var Appwrite\Utopia\Response $response */ /** @var Utopia\Database\Document $project */ /** @var Utopia\Database\Document $user */ @@ -1201,14 +1200,6 @@ App::get('/v1/account/logs') /** @var Utopia\Database\Database $dbForInternal */ /** @var Appwrite\Stats\Stats $usage */ - if (!empty($after)) { - $afterLog = $dbForInternal->getDocument('audit', $after); - - if ($afterLog->isEmpty()) { - throw new Exception("Log '{$after}' for the 'after' value not found.", 400); - } - } - $audit = new Audit($dbForInternal); $logs = $audit->getLogsByUserAndEvents($user->getId(), [ @@ -1227,7 +1218,7 @@ App::get('/v1/account/logs') 'teams.membership.create', 'teams.membership.update', 'teams.membership.delete', - ], $limit, $offset, $afterLog ?? null); + ], $limit, $offset); $output = []; diff --git a/app/controllers/api/database.php b/app/controllers/api/database.php index ce83c1abe3..200b2cff04 100644 --- a/app/controllers/api/database.php +++ b/app/controllers/api/database.php @@ -460,7 +460,6 @@ App::get('/v1/database/collections/:collectionId/logs') ->param('collectionId', '', new UID(), 'Collection unique ID.') ->param('limit', 25, new Range(0, 100), 'Maximum number of logs to return in response. Use this value to manage pagination. By default will return maximum 25 results. Maximum of 100 results allowed per request.', true) ->param('offset', 0, new Range(0, 900000000), 'Offset value. The default value is 0. Use this param to manage pagination.', true) - ->param('after', '', new UID(), 'ID of the log used as the starting point for the query, excluding the document itself. Should be used for efficient pagination when working with large sets of data.', true) ->inject('response') ->inject('dbForInternal') ->inject('dbForExternal') @@ -480,17 +479,9 @@ App::get('/v1/database/collections/:collectionId/logs') throw new Exception('Collection not found', 404); } - if (!empty($after)) { - $afterLog = $dbForInternal->getDocument('audit', $after); - - if ($afterLog->isEmpty()) { - throw new Exception("Log '{$after}' for the 'after' value not found.", 400); - } - } - $audit = new Audit($dbForInternal); - $logs = $audit->getLogsByResource('collection/'.$collection->getId(), $limit, $offset, $afterLog ?? null); + $logs = $audit->getLogsByResource('collection/'.$collection->getId(), $limit, $offset); $output = []; diff --git a/app/controllers/api/users.php b/app/controllers/api/users.php index 5cca14404e..489b807705 100644 --- a/app/controllers/api/users.php +++ b/app/controllers/api/users.php @@ -261,13 +261,12 @@ App::get('/v1/users/:userId/logs') ->param('userId', '', new UID(), 'User unique ID.') ->param('limit', 25, new Range(0, 100), 'Maximum number of logs to return in response. Use this value to manage pagination. By default will return maximum 25 results. Maximum of 100 results allowed per request.', true) ->param('offset', 0, new Range(0, 900000000), 'Offset value. The default value is 0. Use this param to manage pagination.', true) - ->param('after', '', new UID(), 'ID of the log used as the starting point for the query, excluding the document itself. Should be used for efficient pagination when working with large sets of data.', true) ->inject('response') ->inject('dbForInternal') ->inject('locale') ->inject('geodb') ->inject('usage') - ->action(function ($userId, $limit, $offset, $after, $response, $dbForInternal, $locale, $geodb, $usage) { + ->action(function ($userId, $limit, $offset, $response, $dbForInternal, $locale, $geodb, $usage) { /** @var Appwrite\Utopia\Response $response */ /** @var Utopia\Database\Document $project */ /** @var Utopia\Database\Database $dbForInternal */ @@ -281,14 +280,6 @@ App::get('/v1/users/:userId/logs') throw new Exception('User not found', 404); } - if (!empty($after)) { - $afterLog = $dbForInternal->getDocument('audit', $after); - - if ($afterLog->isEmpty()) { - throw new Exception("Log '{$after}' for the 'after' value not found.", 400); - } - } - $audit = new Audit($dbForInternal); $logs = $audit->getLogsByUserAndEvents($user->getId(), [ @@ -307,7 +298,7 @@ App::get('/v1/users/:userId/logs') 'teams.membership.create', 'teams.membership.update', 'teams.membership.delete', - ], $limit, $offset, $afterLog ?? null); + ], $limit, $offset); $output = []; From ced8c9ef0302168f2e128c72c91e7f066d4a3935 Mon Sep 17 00:00:00 2001 From: Torsten Dittmann Date: Tue, 16 Nov 2021 15:54:29 +0100 Subject: [PATCH 09/13] use updated audit library --- app/controllers/api/account.php | 13 +++++++++---- app/controllers/api/database.php | 9 ++++++--- app/controllers/api/users.php | 13 +++++++++---- composer.json | 2 +- composer.lock | 18 ++++++++++-------- tests/e2e/Services/Account/AccountBase.php | 4 ++++ .../Database/DatabaseConsoleClientTest.php | 4 ++++ tests/e2e/Services/Users/UsersBase.php | 4 ++++ 8 files changed, 47 insertions(+), 20 deletions(-) diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php index be0532a460..8dc221ecb7 100644 --- a/app/controllers/api/account.php +++ b/app/controllers/api/account.php @@ -1201,8 +1201,7 @@ App::get('/v1/account/logs') /** @var Appwrite\Stats\Stats $usage */ $audit = new Audit($dbForInternal); - - $logs = $audit->getLogsByUserAndEvents($user->getId(), [ + $auditEvents = [ 'account.create', 'account.delete', 'account.update.name', @@ -1218,7 +1217,9 @@ App::get('/v1/account/logs') 'teams.membership.create', 'teams.membership.update', 'teams.membership.delete', - ], $limit, $offset); + ]; + + $logs = $audit->getLogsByUserAndEvents($user->getId(), $auditEvents, $limit, $offset); $output = []; @@ -1248,7 +1249,11 @@ App::get('/v1/account/logs') $usage ->setParam('users.read', 1) ; - $response->dynamic(new Document(['logs' => $output]), Response::MODEL_LOG_LIST); + + $response->dynamic(new Document([ + 'sum' => $audit->getLogsByUserAndEventsCount($user->getId(), $auditEvents), + 'logs' => $output, + ]), Response::MODEL_LOG_LIST); }); App::get('/v1/account/sessions/:sessionId') diff --git a/app/controllers/api/database.php b/app/controllers/api/database.php index 200b2cff04..4095804f8b 100644 --- a/app/controllers/api/database.php +++ b/app/controllers/api/database.php @@ -480,8 +480,8 @@ App::get('/v1/database/collections/:collectionId/logs') } $audit = new Audit($dbForInternal); - - $logs = $audit->getLogsByResource('collection/'.$collection->getId(), $limit, $offset); + $resource = 'collection/'.$collection->getId(); + $logs = $audit->getLogsByResource($resource, $limit, $offset); $output = []; @@ -541,7 +541,10 @@ App::get('/v1/database/collections/:collectionId/logs') } } - $response->dynamic(new Document(['logs' => $output]), Response::MODEL_LOG_LIST); + $response->dynamic(new Document([ + 'sum' => $audit->getLogsByResourceCount($resource), + 'logs' => $output, + ]), Response::MODEL_LOG_LIST); }); App::put('/v1/database/collections/:collectionId') diff --git a/app/controllers/api/users.php b/app/controllers/api/users.php index 489b807705..d29bef8f04 100644 --- a/app/controllers/api/users.php +++ b/app/controllers/api/users.php @@ -281,8 +281,7 @@ App::get('/v1/users/:userId/logs') } $audit = new Audit($dbForInternal); - - $logs = $audit->getLogsByUserAndEvents($user->getId(), [ + $auditEvents = [ 'account.create', 'account.delete', 'account.update.name', @@ -298,7 +297,9 @@ App::get('/v1/users/:userId/logs') 'teams.membership.create', 'teams.membership.update', 'teams.membership.delete', - ], $limit, $offset); + ]; + + $logs = $audit->getLogsByUserAndEvents($user->getId(), $auditEvents, $limit, $offset); $output = []; @@ -357,7 +358,11 @@ App::get('/v1/users/:userId/logs') $usage ->setParam('users.read', 1) ; - $response->dynamic(new Document(['logs' => $output]), Response::MODEL_LOG_LIST); + + $response->dynamic(new Document([ + 'sum' => $audit->getLogsByUserAndEventsCount($user->getId(), $auditEvents), + 'logs' => $output, + ]), Response::MODEL_LOG_LIST); }); App::patch('/v1/users/:userId/status') diff --git a/composer.json b/composer.json index 8b0d69f1fe..0c0cb95862 100644 --- a/composer.json +++ b/composer.json @@ -41,7 +41,7 @@ "utopia-php/framework": "0.19.*", "utopia-php/abuse": "0.6.*", "utopia-php/analytics": "0.2.*", - "utopia-php/audit": "0.6.*", + "utopia-php/audit": "dev-feat-count-methods", "utopia-php/cache": "0.4.*", "utopia-php/cli": "0.11.*", "utopia-php/config": "0.2.*", diff --git a/composer.lock b/composer.lock index 220869038e..1601bbab0d 100644 --- a/composer.lock +++ b/composer.lock @@ -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": "fa378feaffc446f557a140035a1c77b6", + "content-hash": "14a12f23c3f26ad7650eb3ad912fd078", "packages": [ { "name": "adhocore/jwt", @@ -1928,16 +1928,16 @@ }, { "name": "utopia-php/audit", - "version": "0.6.3", + "version": "dev-feat-count-methods", "source": { "type": "git", "url": "https://github.com/utopia-php/audit.git", - "reference": "d79b467fbc7d03e5e02f12cdeb08761507a60ca0" + "reference": "e9a811cf3b7705e75649db8b5f255a12e0388220" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/audit/zipball/d79b467fbc7d03e5e02f12cdeb08761507a60ca0", - "reference": "d79b467fbc7d03e5e02f12cdeb08761507a60ca0", + "url": "https://api.github.com/repos/utopia-php/audit/zipball/e9a811cf3b7705e75649db8b5f255a12e0388220", + "reference": "e9a811cf3b7705e75649db8b5f255a12e0388220", "shasum": "" }, "require": { @@ -1975,9 +1975,9 @@ ], "support": { "issues": "https://github.com/utopia-php/audit/issues", - "source": "https://github.com/utopia-php/audit/tree/0.6.3" + "source": "https://github.com/utopia-php/audit/tree/feat-count-methods" }, - "time": "2021-08-16T18:49:55+00:00" + "time": "2021-11-16T14:45:05+00:00" }, { "name": "utopia-php/cache", @@ -6507,7 +6507,9 @@ ], "aliases": [], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": { + "utopia-php/audit": 20 + }, "prefer-stable": false, "prefer-lowest": false, "platform": { diff --git a/tests/e2e/Services/Account/AccountBase.php b/tests/e2e/Services/Account/AccountBase.php index 200cdc3ddb..18c5ff162c 100644 --- a/tests/e2e/Services/Account/AccountBase.php +++ b/tests/e2e/Services/Account/AccountBase.php @@ -325,6 +325,7 @@ trait AccountBase $this->assertIsArray($response['body']['logs']); $this->assertNotEmpty($response['body']['logs']); $this->assertCount(2, $response['body']['logs']); + $this->assertIsNumeric($response['body']['sum']); $this->assertContains($response['body']['logs'][0]['event'], ['account.create', 'account.sessions.create']); $this->assertEquals($response['body']['logs'][0]['ip'], filter_var($response['body']['logs'][0]['ip'], FILTER_VALIDATE_IP)); @@ -383,6 +384,7 @@ trait AccountBase $this->assertIsArray($responseLimit['body']['logs']); $this->assertNotEmpty($responseLimit['body']['logs']); $this->assertCount(1, $responseLimit['body']['logs']); + $this->assertIsNumeric($responseLimit['body']['sum']); $this->assertEquals($response['body']['logs'][0], $responseLimit['body']['logs'][0]); @@ -400,6 +402,7 @@ trait AccountBase $this->assertIsArray($responseOffset['body']['logs']); $this->assertNotEmpty($responseOffset['body']['logs']); $this->assertCount(1, $responseOffset['body']['logs']); + $this->assertIsNumeric($responseOffset['body']['sum']); $this->assertEquals($response['body']['logs'][1], $responseOffset['body']['logs'][0]); @@ -417,6 +420,7 @@ trait AccountBase $this->assertIsArray($responseLimitOffset['body']['logs']); $this->assertNotEmpty($responseLimitOffset['body']['logs']); $this->assertCount(1, $responseLimitOffset['body']['logs']); + $this->assertIsNumeric($responseLimitOffset['body']['sum']); $this->assertEquals($response['body']['logs'][1], $responseLimitOffset['body']['logs'][0]); /** diff --git a/tests/e2e/Services/Database/DatabaseConsoleClientTest.php b/tests/e2e/Services/Database/DatabaseConsoleClientTest.php index c98614c5f4..e0f1cc96c7 100644 --- a/tests/e2e/Services/Database/DatabaseConsoleClientTest.php +++ b/tests/e2e/Services/Database/DatabaseConsoleClientTest.php @@ -138,6 +138,7 @@ class DatabaseConsoleClientTest extends Scope $this->assertEquals($logs['headers']['status-code'], 200); $this->assertIsArray($logs['body']['logs']); + $this->assertIsNumeric($logs['body']['sum']); $logs = $this->client->call(Client::METHOD_GET, '/database/collections/' . $data['moviesId'] . '/logs', array_merge([ 'content-type' => 'application/json', @@ -149,6 +150,7 @@ class DatabaseConsoleClientTest extends Scope $this->assertEquals($logs['headers']['status-code'], 200); $this->assertIsArray($logs['body']['logs']); $this->assertLessThanOrEqual(1, count($logs['body']['logs'])); + $this->assertIsNumeric($logs['body']['sum']); $logs = $this->client->call(Client::METHOD_GET, '/database/collections/' . $data['moviesId'] . '/logs', array_merge([ 'content-type' => 'application/json', @@ -159,6 +161,7 @@ class DatabaseConsoleClientTest extends Scope $this->assertEquals($logs['headers']['status-code'], 200); $this->assertIsArray($logs['body']['logs']); + $this->assertIsNumeric($logs['body']['sum']); $logs = $this->client->call(Client::METHOD_GET, '/database/collections/' . $data['moviesId'] . '/logs', array_merge([ 'content-type' => 'application/json', @@ -171,5 +174,6 @@ class DatabaseConsoleClientTest extends Scope $this->assertEquals($logs['headers']['status-code'], 200); $this->assertIsArray($logs['body']['logs']); $this->assertLessThanOrEqual(1, count($logs['body']['logs'])); + $this->assertIsNumeric($logs['body']['sum']); } } \ No newline at end of file diff --git a/tests/e2e/Services/Users/UsersBase.php b/tests/e2e/Services/Users/UsersBase.php index 2d51be8312..17a28377f0 100644 --- a/tests/e2e/Services/Users/UsersBase.php +++ b/tests/e2e/Services/Users/UsersBase.php @@ -436,6 +436,7 @@ trait UsersBase $this->assertEquals($logs['headers']['status-code'], 200); $this->assertIsArray($logs['body']['logs']); + $this->assertIsNumeric($logs['body']['sum']); $logs = $this->client->call(Client::METHOD_GET, '/users/' . $data['userId'] . '/logs', array_merge([ 'content-type' => 'application/json', @@ -447,6 +448,7 @@ trait UsersBase $this->assertEquals($logs['headers']['status-code'], 200); $this->assertIsArray($logs['body']['logs']); $this->assertLessThanOrEqual(1, count($logs['body']['logs'])); + $this->assertIsNumeric($logs['body']['sum']); $logs = $this->client->call(Client::METHOD_GET, '/users/' . $data['userId'] . '/logs', array_merge([ 'content-type' => 'application/json', @@ -457,6 +459,7 @@ trait UsersBase $this->assertEquals($logs['headers']['status-code'], 200); $this->assertIsArray($logs['body']['logs']); + $this->assertIsNumeric($logs['body']['sum']); $logs = $this->client->call(Client::METHOD_GET, '/users/' . $data['userId'] . '/logs', array_merge([ 'content-type' => 'application/json', @@ -469,6 +472,7 @@ trait UsersBase $this->assertEquals($logs['headers']['status-code'], 200); $this->assertIsArray($logs['body']['logs']); $this->assertLessThanOrEqual(1, count($logs['body']['logs'])); + $this->assertIsNumeric($logs['body']['sum']); } /** From 3a255325240bfb3ebc66e6a9e071d29283505383 Mon Sep 17 00:00:00 2001 From: Torsten Dittmann Date: Tue, 16 Nov 2021 16:06:51 +0100 Subject: [PATCH 10/13] fix response model --- src/Appwrite/Utopia/Response.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Appwrite/Utopia/Response.php b/src/Appwrite/Utopia/Response.php index 76432ef88f..1cbc1321d5 100644 --- a/src/Appwrite/Utopia/Response.php +++ b/src/Appwrite/Utopia/Response.php @@ -194,7 +194,7 @@ class Response extends SwooleResponse ->setModel(new BaseList('Documents List', self::MODEL_DOCUMENT_LIST, 'documents', self::MODEL_DOCUMENT)) ->setModel(new BaseList('Users List', self::MODEL_USER_LIST, 'users', self::MODEL_USER)) ->setModel(new BaseList('Sessions List', self::MODEL_SESSION_LIST, 'sessions', self::MODEL_SESSION)) - ->setModel(new BaseList('Logs List', self::MODEL_LOG_LIST, 'logs', self::MODEL_LOG, false)) + ->setModel(new BaseList('Logs List', self::MODEL_LOG_LIST, 'logs', self::MODEL_LOG)) ->setModel(new BaseList('Files List', self::MODEL_FILE_LIST, 'files', self::MODEL_FILE)) ->setModel(new BaseList('Teams List', self::MODEL_TEAM_LIST, 'teams', self::MODEL_TEAM)) ->setModel(new BaseList('Memberships List', self::MODEL_MEMBERSHIP_LIST, 'memberships', self::MODEL_MEMBERSHIP)) From b7961446287dbde6d4d837fc9f979331b44fac1f Mon Sep 17 00:00:00 2001 From: Torsten Dittmann Date: Wed, 17 Nov 2021 11:18:47 +0100 Subject: [PATCH 11/13] chore(composer): update audit library --- app/controllers/api/account.php | 2 +- app/controllers/api/database.php | 2 +- app/controllers/api/users.php | 2 +- composer.json | 2 +- composer.lock | 37 ++++++++++++++++++++------------ 5 files changed, 27 insertions(+), 18 deletions(-) diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php index 8dc221ecb7..5af1bf7a4b 100644 --- a/app/controllers/api/account.php +++ b/app/controllers/api/account.php @@ -1251,7 +1251,7 @@ App::get('/v1/account/logs') ; $response->dynamic(new Document([ - 'sum' => $audit->getLogsByUserAndEventsCount($user->getId(), $auditEvents), + 'sum' => $audit->countLogsByUserAndEvents($user->getId(), $auditEvents), 'logs' => $output, ]), Response::MODEL_LOG_LIST); }); diff --git a/app/controllers/api/database.php b/app/controllers/api/database.php index 4095804f8b..df16918fd2 100644 --- a/app/controllers/api/database.php +++ b/app/controllers/api/database.php @@ -542,7 +542,7 @@ App::get('/v1/database/collections/:collectionId/logs') } $response->dynamic(new Document([ - 'sum' => $audit->getLogsByResourceCount($resource), + 'sum' => $audit->countLogsByResource($resource), 'logs' => $output, ]), Response::MODEL_LOG_LIST); }); diff --git a/app/controllers/api/users.php b/app/controllers/api/users.php index d29bef8f04..a398922c9d 100644 --- a/app/controllers/api/users.php +++ b/app/controllers/api/users.php @@ -360,7 +360,7 @@ App::get('/v1/users/:userId/logs') ; $response->dynamic(new Document([ - 'sum' => $audit->getLogsByUserAndEventsCount($user->getId(), $auditEvents), + 'sum' => $audit->countLogsByUserAndEvents($user->getId(), $auditEvents), 'logs' => $output, ]), Response::MODEL_LOG_LIST); }); diff --git a/composer.json b/composer.json index 0c0cb95862..4d352d2caf 100644 --- a/composer.json +++ b/composer.json @@ -45,7 +45,7 @@ "utopia-php/cache": "0.4.*", "utopia-php/cli": "0.11.*", "utopia-php/config": "0.2.*", - "utopia-php/database": "0.10.*", + "utopia-php/database": "dev-main as 0.10.1", "utopia-php/locale": "0.4.*", "utopia-php/orchestration": "0.2.*", "utopia-php/registry": "0.5.*", diff --git a/composer.lock b/composer.lock index 1601bbab0d..098ddc142c 100644 --- a/composer.lock +++ b/composer.lock @@ -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": "14a12f23c3f26ad7650eb3ad912fd078", + "content-hash": "a63c25e2c7daccf59d5337d13c79c8b5", "packages": [ { "name": "adhocore/jwt", @@ -1932,18 +1932,18 @@ "source": { "type": "git", "url": "https://github.com/utopia-php/audit.git", - "reference": "e9a811cf3b7705e75649db8b5f255a12e0388220" + "reference": "4d5f39733557bafe6247a8349656b511563e1b75" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/audit/zipball/e9a811cf3b7705e75649db8b5f255a12e0388220", - "reference": "e9a811cf3b7705e75649db8b5f255a12e0388220", + "url": "https://api.github.com/repos/utopia-php/audit/zipball/4d5f39733557bafe6247a8349656b511563e1b75", + "reference": "4d5f39733557bafe6247a8349656b511563e1b75", "shasum": "" }, "require": { "ext-pdo": "*", "php": ">=7.4", - "utopia-php/database": ">=0.6 <1.0" + "utopia-php/database": "dev-main" }, "require-dev": { "phpunit/phpunit": "^9.3", @@ -1977,7 +1977,7 @@ "issues": "https://github.com/utopia-php/audit/issues", "source": "https://github.com/utopia-php/audit/tree/feat-count-methods" }, - "time": "2021-11-16T14:45:05+00:00" + "time": "2021-11-17T10:01:36+00:00" }, { "name": "utopia-php/cache", @@ -2138,16 +2138,16 @@ }, { "name": "utopia-php/database", - "version": "0.10.1", + "version": "dev-main", "source": { "type": "git", "url": "https://github.com/utopia-php/database.git", - "reference": "9b4697612a2cd1ad55beeb6a02570f6ffe26dc1e" + "reference": "5fc0476d05567d1a156b00e17033f32148c93a38" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/database/zipball/9b4697612a2cd1ad55beeb6a02570f6ffe26dc1e", - "reference": "9b4697612a2cd1ad55beeb6a02570f6ffe26dc1e", + "url": "https://api.github.com/repos/utopia-php/database/zipball/5fc0476d05567d1a156b00e17033f32148c93a38", + "reference": "5fc0476d05567d1a156b00e17033f32148c93a38", "shasum": "" }, "require": { @@ -2165,6 +2165,7 @@ "utopia-php/cli": "^0.11.0", "vimeo/psalm": "4.0.1" }, + "default-branch": true, "type": "library", "autoload": { "psr-4": { @@ -2195,9 +2196,9 @@ ], "support": { "issues": "https://github.com/utopia-php/database/issues", - "source": "https://github.com/utopia-php/database/tree/0.10.1" + "source": "https://github.com/utopia-php/database/tree/main" }, - "time": "2021-11-02T15:10:39+00:00" + "time": "2021-11-17T09:53:02+00:00" }, { "name": "utopia-php/domains", @@ -6505,10 +6506,18 @@ "time": "2015-12-17T08:42:14+00:00" } ], - "aliases": [], + "aliases": [ + { + "package": "utopia-php/database", + "version": "dev-main", + "alias": "0.10.1", + "alias_normalized": "0.10.1.0" + } + ], "minimum-stability": "stable", "stability-flags": { - "utopia-php/audit": 20 + "utopia-php/audit": 20, + "utopia-php/database": 20 }, "prefer-stable": false, "prefer-lowest": false, From a0e49a0bfae794d2b59f513866cd3db43028807c Mon Sep 17 00:00:00 2001 From: Torsten Dittmann Date: Wed, 17 Nov 2021 11:22:20 +0100 Subject: [PATCH 12/13] Update tests/e2e/Services/Account/AccountBase.php Co-authored-by: kodumbeats --- tests/e2e/Services/Account/AccountBase.php | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/e2e/Services/Account/AccountBase.php b/tests/e2e/Services/Account/AccountBase.php index 18c5ff162c..fc615fef8e 100644 --- a/tests/e2e/Services/Account/AccountBase.php +++ b/tests/e2e/Services/Account/AccountBase.php @@ -388,7 +388,6 @@ trait AccountBase $this->assertEquals($response['body']['logs'][0], $responseLimit['body']['logs'][0]); - $responseOffset = $this->client->call(Client::METHOD_GET, '/account/logs', array_merge([ 'origin' => 'http://localhost', 'content-type' => 'application/json', From 41833d18da5bec99f558f3a4f04fa8a5610ebdbc Mon Sep 17 00:00:00 2001 From: Torsten Dittmann Date: Thu, 18 Nov 2021 11:15:32 +0100 Subject: [PATCH 13/13] chore(deps): update composer --- composer.json | 4 ++-- composer.lock | 43 ++++++++++++++++--------------------------- 2 files changed, 18 insertions(+), 29 deletions(-) diff --git a/composer.json b/composer.json index 78f9c46e47..0f5eb22d76 100644 --- a/composer.json +++ b/composer.json @@ -41,11 +41,11 @@ "utopia-php/framework": "0.19.*", "utopia-php/abuse": "0.6.*", "utopia-php/analytics": "0.2.*", - "utopia-php/audit": "dev-feat-count-methods", + "utopia-php/audit": "0.7.*", "utopia-php/cache": "0.4.*", "utopia-php/cli": "0.11.*", "utopia-php/config": "0.2.*", - "utopia-php/database": "dev-main as 0.10.1", + "utopia-php/database": "0.11.*", "utopia-php/locale": "0.4.*", "utopia-php/orchestration": "0.2.*", "utopia-php/registry": "0.5.*", diff --git a/composer.lock b/composer.lock index 169c870d0b..6af13d6184 100644 --- a/composer.lock +++ b/composer.lock @@ -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": "de8b7360734c246c97d8cee4779983e3", + "content-hash": "8427bbf013694d9771cd09341a81562e", "packages": [ { "name": "adhocore/jwt", @@ -1928,22 +1928,22 @@ }, { "name": "utopia-php/audit", - "version": "dev-feat-count-methods", + "version": "0.7.0", "source": { "type": "git", "url": "https://github.com/utopia-php/audit.git", - "reference": "4d5f39733557bafe6247a8349656b511563e1b75" + "reference": "485cdd2354db7eb8f7aa74bbe39c39b583e99c04" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/audit/zipball/4d5f39733557bafe6247a8349656b511563e1b75", - "reference": "4d5f39733557bafe6247a8349656b511563e1b75", + "url": "https://api.github.com/repos/utopia-php/audit/zipball/485cdd2354db7eb8f7aa74bbe39c39b583e99c04", + "reference": "485cdd2354db7eb8f7aa74bbe39c39b583e99c04", "shasum": "" }, "require": { "ext-pdo": "*", "php": ">=7.4", - "utopia-php/database": "dev-main" + "utopia-php/database": ">=0.11 <1.0" }, "require-dev": { "phpunit/phpunit": "^9.3", @@ -1975,9 +1975,9 @@ ], "support": { "issues": "https://github.com/utopia-php/audit/issues", - "source": "https://github.com/utopia-php/audit/tree/feat-count-methods" + "source": "https://github.com/utopia-php/audit/tree/0.7.0" }, - "time": "2021-11-17T10:01:36+00:00" + "time": "2021-11-17T17:23:42+00:00" }, { "name": "utopia-php/cache", @@ -2138,16 +2138,16 @@ }, { "name": "utopia-php/database", - "version": "0.10.1", + "version": "0.11.0", "source": { "type": "git", "url": "https://github.com/utopia-php/database.git", - "reference": "9b4697612a2cd1ad55beeb6a02570f6ffe26dc1e" + "reference": "5fc0476d05567d1a156b00e17033f32148c93a38" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/database/zipball/9b4697612a2cd1ad55beeb6a02570f6ffe26dc1e", - "reference": "9b4697612a2cd1ad55beeb6a02570f6ffe26dc1e", + "url": "https://api.github.com/repos/utopia-php/database/zipball/5fc0476d05567d1a156b00e17033f32148c93a38", + "reference": "5fc0476d05567d1a156b00e17033f32148c93a38", "shasum": "" }, "require": { @@ -2165,7 +2165,6 @@ "utopia-php/cli": "^0.11.0", "vimeo/psalm": "4.0.1" }, - "default-branch": true, "type": "library", "autoload": { "psr-4": { @@ -2196,9 +2195,9 @@ ], "support": { "issues": "https://github.com/utopia-php/database/issues", - "source": "https://github.com/utopia-php/database/tree/0.10.1" + "source": "https://github.com/utopia-php/database/tree/0.11.0" }, - "time": "2021-11-02T15:10:39+00:00" + "time": "2021-11-17T09:53:02+00:00" }, { "name": "utopia-php/domains", @@ -6506,19 +6505,9 @@ "time": "2015-12-17T08:42:14+00:00" } ], - "aliases": [ - { - "package": "utopia-php/database", - "version": "dev-main", - "alias": "0.10.1", - "alias_normalized": "0.10.1.0" - } - ], + "aliases": [], "minimum-stability": "stable", - "stability-flags": { - "utopia-php/audit": 20, - "utopia-php/database": 20 - }, + "stability-flags": [], "prefer-stable": false, "prefer-lowest": false, "platform": {