From 77793b4e01160922e0154a46d49b2260ea0ff020 Mon Sep 17 00:00:00 2001 From: Matej Baco Date: Tue, 21 Sep 2021 13:18:54 +0200 Subject: [PATCH 1/8] update instead of delete, adjust code to new attribute --- app/config/collections2.php | 11 +++ app/controllers/api/account.php | 23 ++++-- app/controllers/api/users.php | 47 ++++++++----- composer.lock | 119 ++++++++++++++++---------------- 4 files changed, 115 insertions(+), 85 deletions(-) diff --git a/app/config/collections2.php b/app/config/collections2.php index 9ba9635457..866d1cb1b6 100644 --- a/app/config/collections2.php +++ b/app/config/collections2.php @@ -695,6 +695,17 @@ $collections = [ 'array' => true, 'filters' => ['json'], ], + [ + '$id' => 'deleted', + 'type' => Database::VAR_BOOLEAN, + 'format' => '', + 'size' => 0, + 'signed' => true, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => [], + ], ], 'indexes' => [ [ diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php index bc34f81dda..3ad04efe81 100644 --- a/app/controllers/api/account.php +++ b/app/controllers/api/account.php @@ -78,7 +78,9 @@ App::post('/v1/account') $limit = $project->getAttribute('auths', [])['limit'] ?? 0; if ($limit !== 0) { - $sum = $dbForInternal->count('users', [], APP_LIMIT_USERS); + $sum = $dbForInternal->count('users', [ + new Query('deleted', Query::TYPE_EQUAL, [false]), + ], APP_LIMIT_USERS); if ($sum >= $limit) { throw new Exception('Project registration is restricted. Contact your administrator for more information.', 501); @@ -105,6 +107,7 @@ App::post('/v1/account') 'sessions' => [], 'tokens' => [], 'memberships' => [], + 'deleted' => false ])); } catch (Duplicate $th) { throw new Exception('Account already exists', 409); @@ -165,7 +168,7 @@ App::post('/v1/account/sessions') $email = \strtolower($email); $protocol = $request->getProtocol(); - $profile = $dbForInternal->findOne('users', [new Query('email', Query::TYPE_EQUAL, [$email])]); // Get user by email address + $profile = $dbForInternal->findOne('users', [new Query('deleted', Query::TYPE_EQUAL, [false]), new Query('email', Query::TYPE_EQUAL, [$email])]); // Get user by email address if (!$profile || !Auth::passwordVerify($password, $profile->getAttribute('password'))) { $audits @@ -462,13 +465,13 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect') $name = $oauth2->getUserName($accessToken); $email = $oauth2->getUserEmail($accessToken); - $user = $dbForInternal->findOne('users', [new Query('email', Query::TYPE_EQUAL, [$email])]); // Get user by email address + $user = $dbForInternal->findOne('users', [new Query('deleted', Query::TYPE_EQUAL, [false]), new Query('email', Query::TYPE_EQUAL, [$email])]); // Get user by email address if ($user === false || $user->isEmpty()) { // Last option -> create the user, generate random password $limit = $project->getAttribute('auths', [])['limit'] ?? 0; if ($limit !== 0) { - $sum = $dbForInternal->count('users', [], APP_LIMIT_COUNT); + $sum = $dbForInternal->count('users', [ new Query('deleted', Query::TYPE_EQUAL, [false]),], APP_LIMIT_COUNT); if ($sum >= $limit) { throw new Exception('Project registration is restricted. Contact your administrator for more information.', 501); @@ -495,6 +498,7 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect') 'sessions' => [], 'tokens' => [], 'memberships' => [], + 'deleted' => false ])); } catch (Duplicate $th) { throw new Exception('Account already exists', 409); @@ -639,7 +643,9 @@ App::post('/v1/account/sessions/anonymous') $limit = $project->getAttribute('auths', [])['limit'] ?? 0; if ($limit !== 0) { - $sum = $dbForInternal->count('users', [], APP_LIMIT_COUNT); + $sum = $dbForInternal->count('users', [ + new Query('deleted', Query::TYPE_EQUAL, [false]), + ], APP_LIMIT_COUNT); if ($sum >= $limit) { throw new Exception('Project registration is restricted. Contact your administrator for more information.', 501); @@ -665,6 +671,7 @@ App::post('/v1/account/sessions/anonymous') 'sessions' => [], 'tokens' => [], 'memberships' => [], + 'deleted' => false ])); Authorization::reset(); @@ -1221,6 +1228,8 @@ App::delete('/v1/account') $protocol = $request->getProtocol(); $user = $dbForInternal->updateDocument('users', $user->getId(), $user->setAttribute('status', false)); + // TODO Seems to be related to users.php/App::delete('/v1/users/:userId'). Can we share code between these two? Do todos below apply to users.php? + // TODO delete all tokens or only current session? // TODO delete all user data according to GDPR. Make sure everything is backed up and backups are deleted later /* @@ -1463,7 +1472,7 @@ App::post('/v1/account/recovery') $isAppUser = Auth::isAppUser(Authorization::$roles); $email = \strtolower($email); - $profile = $dbForInternal->findOne('users', [new Query('email', Query::TYPE_EQUAL, [$email])]); // Get user by email address + $profile = $dbForInternal->findOne('users', [new Query('deleted', Query::TYPE_EQUAL, [false]), new Query('email', Query::TYPE_EQUAL, [$email])]); // Get user by email address if (!$profile) { throw new Exception('User not found', 404); @@ -1566,7 +1575,7 @@ App::put('/v1/account/recovery') $profile = $dbForInternal->getDocument('users', $userId); - if ($profile->isEmpty()) { + if ($profile->isEmpty() || $profile->getAttribute('deleted')) { throw new Exception('User not found', 404); } diff --git a/app/controllers/api/users.php b/app/controllers/api/users.php index c6c8207e21..20266d1fda 100644 --- a/app/controllers/api/users.php +++ b/app/controllers/api/users.php @@ -66,6 +66,7 @@ App::post('/v1/users') 'sessions' => [], 'tokens' => [], 'memberships' => [], + 'deleted' => false ])); } catch (Duplicate $th) { throw new Exception('Account already exists', 409); @@ -106,13 +107,17 @@ App::get('/v1/users') if (!empty($after)) { $afterUser = $dbForInternal->getDocument('users', $after); - if ($afterUser->isEmpty()) { + if ($afterUser->isEmpty() || $afterUser->getAttribute('deleted')) { throw new Exception('User for after not found', 400); } } - $results = $dbForInternal->find('users', [], $limit, $offset, [], [$orderType], $afterUser ?? null); - $sum = $dbForInternal->count('users', [], APP_LIMIT_COUNT); + $results = $dbForInternal->find('users', [ + new Query('deleted', Query::TYPE_EQUAL, [false]), + ], $limit, $offset, [], [$orderType], $afterUser ?? null); + $sum = $dbForInternal->count('users', [ + new Query('deleted', Query::TYPE_EQUAL, [false]), + ], APP_LIMIT_COUNT); $usage ->setParam('users.read', 1) @@ -146,7 +151,7 @@ App::get('/v1/users/:userId') $user = $dbForInternal->getDocument('users', $userId); - if ($user->isEmpty()) { + if ($user->isEmpty() || $user->getAttribute('deleted')) { throw new Exception('User not found', 404); } @@ -178,7 +183,7 @@ App::get('/v1/users/:userId/prefs') $user = $dbForInternal->getDocument('users', $userId); - if ($user->isEmpty()) { + if ($user->isEmpty() || $user->getAttribute('deleted')) { throw new Exception('User not found', 404); } @@ -214,7 +219,7 @@ App::get('/v1/users/:userId/sessions') $user = $dbForInternal->getDocument('users', $userId); - if ($user->isEmpty()) { + if ($user->isEmpty() || $user->getAttribute('deleted')) { throw new Exception('User not found', 404); } @@ -266,7 +271,7 @@ App::get('/v1/users/:userId/logs') $user = $dbForInternal->getDocument('users', $userId); - if ($user->isEmpty()) { + if ($user->isEmpty() || $user->getAttribute('deleted')) { throw new Exception('User not found', 404); } @@ -374,7 +379,7 @@ App::patch('/v1/users/:userId/status') $user = $dbForInternal->getDocument('users', $userId); - if ($user->isEmpty()) { + if ($user->isEmpty() || $user->getAttribute('deleted')) { throw new Exception('User not found', 404); } @@ -410,7 +415,7 @@ App::patch('/v1/users/:userId/verification') $user = $dbForInternal->getDocument('users', $userId); - if ($user->isEmpty()) { + if ($user->isEmpty() || $user->getAttribute('deleted')) { throw new Exception('User not found', 404); } @@ -446,7 +451,7 @@ App::patch('/v1/users/:userId/name') $user = $dbForInternal->getDocument('users', $userId); - if ($user->isEmpty()) { + if ($user->isEmpty() || $user->getAttribute('deleted')) { throw new Exception('User not found', 404); } @@ -485,7 +490,7 @@ App::patch('/v1/users/:userId/password') $user = $dbForInternal->getDocument('users', $userId); - if ($user->isEmpty()) { + if ($user->isEmpty() || $user->getAttribute('deleted')) { throw new Exception('User not found', 404); } @@ -525,7 +530,7 @@ App::patch('/v1/users/:userId/email') $user = $dbForInternal->getDocument('users', $userId); - if ($user->isEmpty()) { + if ($user->isEmpty() || $user->getAttribute('deleted')) { throw new Exception('User not found', 404); } @@ -569,7 +574,7 @@ App::patch('/v1/users/:userId/prefs') $user = $dbForInternal->getDocument('users', $userId); - if ($user->isEmpty()) { + if ($user->isEmpty() || $user->getAttribute('deleted')) { throw new Exception('User not found', 404); } @@ -606,7 +611,7 @@ App::delete('/v1/users/:userId/sessions/:sessionId') $user = $dbForInternal->getDocument('users', $userId); - if ($user->isEmpty()) { + if ($user->isEmpty() || $user->getAttribute('deleted')) { throw new Exception('User not found', 404); } @@ -661,7 +666,7 @@ App::delete('/v1/users/:userId/sessions') $user = $dbForInternal->getDocument('users', $userId); - if ($user->isEmpty()) { + if ($user->isEmpty() || $user->getAttribute('deleted')) { throw new Exception('User not found', 404); } @@ -710,13 +715,17 @@ App::delete('/v1/users/:userId') $user = $dbForInternal->getDocument('users', $userId); - if ($user->isEmpty()) { + if ($user->isEmpty() || $user->getAttribute('deleted')) { throw new Exception('User not found', 404); } - if (!$dbForInternal->deleteDocument('users', $userId)) { - throw new Exception('Failed to remove user from DB', 500); - } + $emptyUser = clone $user; + $emptyUser->setAttribute("name", null); + $emptyUser->setAttribute("email", null); + $emptyUser->setAttribute("password", null); + $emptyUser->setAttribute("deleted", true); + + $dbForInternal->updateDocument('users', $userId, $emptyUser); $deletes ->setParam('type', DELETE_TYPE_DOCUMENT) diff --git a/composer.lock b/composer.lock index 8dac7bcc6d..c319daa5a3 100644 --- a/composer.lock +++ b/composer.lock @@ -248,16 +248,16 @@ }, { "name": "chillerlan/php-settings-container", - "version": "2.1.1", + "version": "2.1.2", "source": { "type": "git", "url": "https://github.com/chillerlan/php-settings-container.git", - "reference": "98ccc1b31b31a53bcb563465c4961879b2b93096" + "reference": "ec834493a88682dd69652a1eeaf462789ed0c5f5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/chillerlan/php-settings-container/zipball/98ccc1b31b31a53bcb563465c4961879b2b93096", - "reference": "98ccc1b31b31a53bcb563465c4961879b2b93096", + "url": "https://api.github.com/repos/chillerlan/php-settings-container/zipball/ec834493a88682dd69652a1eeaf462789ed0c5f5", + "reference": "ec834493a88682dd69652a1eeaf462789ed0c5f5", "shasum": "" }, "require": { @@ -307,7 +307,7 @@ "type": "ko_fi" } ], - "time": "2021-01-06T15:57:03+00:00" + "time": "2021-09-06T15:17:01+00:00" }, { "name": "colinmollenhour/credis", @@ -355,16 +355,16 @@ }, { "name": "composer/package-versions-deprecated", - "version": "1.11.99.3", + "version": "1.11.99.4", "source": { "type": "git", "url": "https://github.com/composer/package-versions-deprecated.git", - "reference": "fff576ac850c045158a250e7e27666e146e78d18" + "reference": "b174585d1fe49ceed21928a945138948cb394600" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/package-versions-deprecated/zipball/fff576ac850c045158a250e7e27666e146e78d18", - "reference": "fff576ac850c045158a250e7e27666e146e78d18", + "url": "https://api.github.com/repos/composer/package-versions-deprecated/zipball/b174585d1fe49ceed21928a945138948cb394600", + "reference": "b174585d1fe49ceed21928a945138948cb394600", "shasum": "" }, "require": { @@ -408,7 +408,7 @@ "description": "Composer plugin that provides efficient querying for installed package versions (no runtime IO)", "support": { "issues": "https://github.com/composer/package-versions-deprecated/issues", - "source": "https://github.com/composer/package-versions-deprecated/tree/1.11.99.3" + "source": "https://github.com/composer/package-versions-deprecated/tree/1.11.99.4" }, "funding": [ { @@ -424,7 +424,7 @@ "type": "tidelift" } ], - "time": "2021-08-17T13:49:14+00:00" + "time": "2021-09-13T08:41:34+00:00" }, { "name": "dragonmantank/cron-expression", @@ -3383,16 +3383,16 @@ }, { "name": "nikic/php-parser", - "version": "v4.12.0", + "version": "v4.13.0", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "6608f01670c3cc5079e18c1dab1104e002579143" + "reference": "50953a2691a922aa1769461637869a0a2faa3f53" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/6608f01670c3cc5079e18c1dab1104e002579143", - "reference": "6608f01670c3cc5079e18c1dab1104e002579143", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/50953a2691a922aa1769461637869a0a2faa3f53", + "reference": "50953a2691a922aa1769461637869a0a2faa3f53", "shasum": "" }, "require": { @@ -3433,9 +3433,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v4.12.0" + "source": "https://github.com/nikic/PHP-Parser/tree/v4.13.0" }, - "time": "2021-07-21T10:44:31+00:00" + "time": "2021-09-20T12:20:58+00:00" }, { "name": "openlss/lib-array2xml", @@ -3712,16 +3712,16 @@ }, { "name": "phpdocumentor/type-resolver", - "version": "1.4.0", + "version": "1.5.0", "source": { "type": "git", "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0" + "reference": "30f38bffc6f24293dadd1823936372dfa9e86e2f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0", - "reference": "6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/30f38bffc6f24293dadd1823936372dfa9e86e2f", + "reference": "30f38bffc6f24293dadd1823936372dfa9e86e2f", "shasum": "" }, "require": { @@ -3729,7 +3729,8 @@ "phpdocumentor/reflection-common": "^2.0" }, "require-dev": { - "ext-tokenizer": "*" + "ext-tokenizer": "*", + "psalm/phar": "^4.8" }, "type": "library", "extra": { @@ -3755,39 +3756,39 @@ "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", "support": { "issues": "https://github.com/phpDocumentor/TypeResolver/issues", - "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.4.0" + "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.5.0" }, - "time": "2020-09-17T18:55:26+00:00" + "time": "2021-09-17T15:28:14+00:00" }, { "name": "phpspec/prophecy", - "version": "1.13.0", + "version": "1.14.0", "source": { "type": "git", "url": "https://github.com/phpspec/prophecy.git", - "reference": "be1996ed8adc35c3fd795488a653f4b518be70ea" + "reference": "d86dfc2e2a3cd366cee475e52c6bb3bbc371aa0e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/be1996ed8adc35c3fd795488a653f4b518be70ea", - "reference": "be1996ed8adc35c3fd795488a653f4b518be70ea", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/d86dfc2e2a3cd366cee475e52c6bb3bbc371aa0e", + "reference": "d86dfc2e2a3cd366cee475e52c6bb3bbc371aa0e", "shasum": "" }, "require": { "doctrine/instantiator": "^1.2", - "php": "^7.2 || ~8.0, <8.1", + "php": "^7.2 || ~8.0, <8.2", "phpdocumentor/reflection-docblock": "^5.2", "sebastian/comparator": "^3.0 || ^4.0", "sebastian/recursion-context": "^3.0 || ^4.0" }, "require-dev": { - "phpspec/phpspec": "^6.0", + "phpspec/phpspec": "^6.0 || ^7.0", "phpunit/phpunit": "^8.0 || ^9.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.11.x-dev" + "dev-master": "1.x-dev" } }, "autoload": { @@ -3822,29 +3823,29 @@ ], "support": { "issues": "https://github.com/phpspec/prophecy/issues", - "source": "https://github.com/phpspec/prophecy/tree/1.13.0" + "source": "https://github.com/phpspec/prophecy/tree/1.14.0" }, - "time": "2021-03-17T13:42:18+00:00" + "time": "2021-09-10T09:02:12+00:00" }, { "name": "phpunit/php-code-coverage", - "version": "9.2.6", + "version": "9.2.7", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "f6293e1b30a2354e8428e004689671b83871edde" + "reference": "d4c798ed8d51506800b441f7a13ecb0f76f12218" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/f6293e1b30a2354e8428e004689671b83871edde", - "reference": "f6293e1b30a2354e8428e004689671b83871edde", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/d4c798ed8d51506800b441f7a13ecb0f76f12218", + "reference": "d4c798ed8d51506800b441f7a13ecb0f76f12218", "shasum": "" }, "require": { "ext-dom": "*", "ext-libxml": "*", "ext-xmlwriter": "*", - "nikic/php-parser": "^4.10.2", + "nikic/php-parser": "^4.12.0", "php": ">=7.3", "phpunit/php-file-iterator": "^3.0.3", "phpunit/php-text-template": "^2.0.2", @@ -3893,7 +3894,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.6" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.7" }, "funding": [ { @@ -3901,7 +3902,7 @@ "type": "github" } ], - "time": "2021-03-28T07:26:59+00:00" + "time": "2021-09-17T05:39:03+00:00" }, { "name": "phpunit/php-file-iterator", @@ -5313,16 +5314,16 @@ }, { "name": "symfony/console", - "version": "v5.3.6", + "version": "v5.3.7", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "51b71afd6d2dc8f5063199357b9880cea8d8bfe2" + "reference": "8b1008344647462ae6ec57559da166c2bfa5e16a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/51b71afd6d2dc8f5063199357b9880cea8d8bfe2", - "reference": "51b71afd6d2dc8f5063199357b9880cea8d8bfe2", + "url": "https://api.github.com/repos/symfony/console/zipball/8b1008344647462ae6ec57559da166c2bfa5e16a", + "reference": "8b1008344647462ae6ec57559da166c2bfa5e16a", "shasum": "" }, "require": { @@ -5392,7 +5393,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v5.3.6" + "source": "https://github.com/symfony/console/tree/v5.3.7" }, "funding": [ { @@ -5408,7 +5409,7 @@ "type": "tidelift" } ], - "time": "2021-07-27T19:10:22+00:00" + "time": "2021-08-25T20:02:16+00:00" }, { "name": "symfony/deprecation-contracts", @@ -5882,16 +5883,16 @@ }, { "name": "symfony/string", - "version": "v5.3.3", + "version": "v5.3.7", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "bd53358e3eccec6a670b5f33ab680d8dbe1d4ae1" + "reference": "8d224396e28d30f81969f083a58763b8b9ceb0a5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/bd53358e3eccec6a670b5f33ab680d8dbe1d4ae1", - "reference": "bd53358e3eccec6a670b5f33ab680d8dbe1d4ae1", + "url": "https://api.github.com/repos/symfony/string/zipball/8d224396e28d30f81969f083a58763b8b9ceb0a5", + "reference": "8d224396e28d30f81969f083a58763b8b9ceb0a5", "shasum": "" }, "require": { @@ -5945,7 +5946,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v5.3.3" + "source": "https://github.com/symfony/string/tree/v5.3.7" }, "funding": [ { @@ -5961,7 +5962,7 @@ "type": "tidelift" } ], - "time": "2021-06-27T11:44:38+00:00" + "time": "2021-08-26T08:00:08+00:00" }, { "name": "theseer/tokenizer", @@ -6015,16 +6016,16 @@ }, { "name": "twig/twig", - "version": "v2.14.6", + "version": "v2.14.7", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "27e5cf2b05e3744accf39d4c68a3235d9966d260" + "reference": "8e202327ee1ed863629de9b18a5ec70ac614d88f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/27e5cf2b05e3744accf39d4c68a3235d9966d260", - "reference": "27e5cf2b05e3744accf39d4c68a3235d9966d260", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/8e202327ee1ed863629de9b18a5ec70ac614d88f", + "reference": "8e202327ee1ed863629de9b18a5ec70ac614d88f", "shasum": "" }, "require": { @@ -6034,7 +6035,7 @@ }, "require-dev": { "psr/container": "^1.0", - "symfony/phpunit-bridge": "^4.4.9|^5.0.9" + "symfony/phpunit-bridge": "^4.4.9|^5.0.9|^6.0" }, "type": "library", "extra": { @@ -6078,7 +6079,7 @@ ], "support": { "issues": "https://github.com/twigphp/Twig/issues", - "source": "https://github.com/twigphp/Twig/tree/v2.14.6" + "source": "https://github.com/twigphp/Twig/tree/v2.14.7" }, "funding": [ { @@ -6090,7 +6091,7 @@ "type": "tidelift" } ], - "time": "2021-05-16T12:12:47+00:00" + "time": "2021-09-17T08:39:54+00:00" }, { "name": "vimeo/psalm", From add7a01fac568ab7e78220ef0659a1f6cbc6b44e Mon Sep 17 00:00:00 2001 From: Matej Baco Date: Thu, 23 Sep 2021 15:40:05 +0200 Subject: [PATCH 2/8] Added database key for performence --- app/config/collections2.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/config/collections2.php b/app/config/collections2.php index 866d1cb1b6..71dc7e9f69 100644 --- a/app/config/collections2.php +++ b/app/config/collections2.php @@ -715,6 +715,13 @@ $collections = [ 'lengths' => [1024], 'orders' => [Database::ORDER_ASC], ], + [ + '$id' => '_key_deleted_email', + 'type' => Database::INDEX_KEY, + 'attributes' => ['deleted', 'email'], + 'lengths' => [0, 1024], + 'orders' => [Database::ORDER_ASC, Database::ORDER_ASC], + ], ], ], From 429da848c6ccb1ee41f15dbe82c2b023f42b6989 Mon Sep 17 00:00:00 2001 From: Matej Baco Date: Mon, 27 Sep 2021 14:11:06 +0200 Subject: [PATCH 3/8] Added missing tests for user deprecation feature --- composer.lock | 12 ++--- docker-compose.yml | 2 +- .../Services/Users/UsersCustomServerTest.php | 48 +++++++++++++++++++ 3 files changed, 55 insertions(+), 7 deletions(-) diff --git a/composer.lock b/composer.lock index c319daa5a3..6e2046e5e8 100644 --- a/composer.lock +++ b/composer.lock @@ -2576,16 +2576,16 @@ "packages-dev": [ { "name": "amphp/amp", - "version": "v2.6.0", + "version": "v2.6.1", "source": { "type": "git", "url": "https://github.com/amphp/amp.git", - "reference": "caa95edeb1ca1bf7532e9118ede4a3c3126408cc" + "reference": "c5fc66a78ee38d7ac9195a37bacaf940eb3f65ae" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/amphp/amp/zipball/caa95edeb1ca1bf7532e9118ede4a3c3126408cc", - "reference": "caa95edeb1ca1bf7532e9118ede4a3c3126408cc", + "url": "https://api.github.com/repos/amphp/amp/zipball/c5fc66a78ee38d7ac9195a37bacaf940eb3f65ae", + "reference": "c5fc66a78ee38d7ac9195a37bacaf940eb3f65ae", "shasum": "" }, "require": { @@ -2653,7 +2653,7 @@ "support": { "irc": "irc://irc.freenode.org/amphp", "issues": "https://github.com/amphp/amp/issues", - "source": "https://github.com/amphp/amp/tree/v2.6.0" + "source": "https://github.com/amphp/amp/tree/v2.6.1" }, "funding": [ { @@ -2661,7 +2661,7 @@ "type": "github" } ], - "time": "2021-07-16T20:06:06+00:00" + "time": "2021-09-23T18:43:08+00:00" }, { "name": "amphp/byte-stream", diff --git a/docker-compose.yml b/docker-compose.yml index 539799aa9a..27c2a125d9 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -63,7 +63,7 @@ services: - ./psalm.xml:/usr/src/code/psalm.xml - ./tests:/usr/src/code/tests - ./app:/usr/src/code/app - # - ./vendor/utopia-php/database:/usr/src/code/vendor/utopia-php/database + - ./vendor:/usr/src/code/vendor - ./docs:/usr/src/code/docs - ./public:/usr/src/code/public - ./src:/usr/src/code/src diff --git a/tests/e2e/Services/Users/UsersCustomServerTest.php b/tests/e2e/Services/Users/UsersCustomServerTest.php index c5e4ff8c1a..3acd4330af 100644 --- a/tests/e2e/Services/Users/UsersCustomServerTest.php +++ b/tests/e2e/Services/Users/UsersCustomServerTest.php @@ -2,6 +2,7 @@ namespace Tests\E2E\Services\Users; +use Tests\E2E\Client; use Tests\E2E\Scopes\ProjectCustom; use Tests\E2E\Scopes\Scope; use Tests\E2E\Scopes\SideServer; @@ -11,4 +12,51 @@ class UsersCustomServerTest extends Scope use UsersBase; use ProjectCustom; use SideServer; + + public function testDeprecatedUsers():array + { + /** + * Test for FAILURE (don't allow recreating account with same custom ID) + */ + + // Create user with custom ID 'meldiron' + $response = $this->client->call(Client::METHOD_POST, '/users', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'userId' => 'meldiron', + 'email' => 'matej@appwrite.io', + 'password' => 'my-superstr0ng-password', + 'name' => 'Matej Bačo' + ]); + + $this->assertEquals(201, $response['headers']['status-code']); + + // Delete user with custom ID 'meldiron' + $response = $this->client->call(Client::METHOD_DELETE, '/users/meldiron', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + + ]); + + $this->assertEquals(204, $response['headers']['status-code']); + + // Try to create user with custom ID 'meldiron' again, but now it should fail + $response1 = $this->client->call(Client::METHOD_POST, '/users', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'userId' => 'meldiron', + 'email' => 'matej@appwrite.io', + 'password' => 'my-superstr0ng-password', + 'name' => 'Matej Bačo' + ]); + + $this->assertEquals(409, $response1['headers']['status-code']); + $this->assertEquals('Account already exists', $response1['body']['message']); + + return []; + } + } \ No newline at end of file From 8fb83d9605dcced707ef7af1df835c8d96616da1 Mon Sep 17 00:00:00 2001 From: Matej Baco Date: Tue, 28 Sep 2021 08:51:53 +0200 Subject: [PATCH 4/8] Fixed column width --- app/config/collections2.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/config/collections2.php b/app/config/collections2.php index 71dc7e9f69..72b8e00671 100644 --- a/app/config/collections2.php +++ b/app/config/collections2.php @@ -578,7 +578,7 @@ $collections = [ '$id' => 'email', 'type' => Database::VAR_STRING, 'format' => '', - 'size' => 1024, + 'size' => 320, 'signed' => true, 'required' => false, 'default' => null, @@ -712,14 +712,14 @@ $collections = [ '$id' => '_key_email', 'type' => Database::INDEX_UNIQUE, 'attributes' => ['email'], - 'lengths' => [1024], + 'lengths' => [320], 'orders' => [Database::ORDER_ASC], ], [ '$id' => '_key_deleted_email', 'type' => Database::INDEX_KEY, 'attributes' => ['deleted', 'email'], - 'lengths' => [0, 1024], + 'lengths' => [0, 320], 'orders' => [Database::ORDER_ASC, Database::ORDER_ASC], ], ], From 6ada84cb53f91eb733cc729ed669c551075d95d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Mon, 4 Oct 2021 12:58:33 +0200 Subject: [PATCH 5/8] Update tests/e2e/Services/Users/UsersCustomServerTest.php Co-authored-by: kodumbeats --- tests/e2e/Services/Users/UsersCustomServerTest.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/e2e/Services/Users/UsersCustomServerTest.php b/tests/e2e/Services/Users/UsersCustomServerTest.php index 3acd4330af..9d7e60a730 100644 --- a/tests/e2e/Services/Users/UsersCustomServerTest.php +++ b/tests/e2e/Services/Users/UsersCustomServerTest.php @@ -36,9 +36,7 @@ class UsersCustomServerTest extends Scope $response = $this->client->call(Client::METHOD_DELETE, '/users/meldiron', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ - - ]); + ], $this->getHeaders())); $this->assertEquals(204, $response['headers']['status-code']); From b068f4969cde06c8e5a7a095238f4642626bbc1d Mon Sep 17 00:00:00 2001 From: Matej Baco Date: Mon, 4 Oct 2021 13:01:08 +0200 Subject: [PATCH 6/8] Review changes --- docker-compose.yml | 2 +- tests/e2e/Services/Users/UsersCustomServerTest.php | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 27c2a125d9..ade61dc1f8 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -63,7 +63,7 @@ services: - ./psalm.xml:/usr/src/code/psalm.xml - ./tests:/usr/src/code/tests - ./app:/usr/src/code/app - - ./vendor:/usr/src/code/vendor + # - ./vendor:/usr/src/code/vendor - ./docs:/usr/src/code/docs - ./public:/usr/src/code/public - ./src:/usr/src/code/src diff --git a/tests/e2e/Services/Users/UsersCustomServerTest.php b/tests/e2e/Services/Users/UsersCustomServerTest.php index 9d7e60a730..cee654e6c3 100644 --- a/tests/e2e/Services/Users/UsersCustomServerTest.php +++ b/tests/e2e/Services/Users/UsersCustomServerTest.php @@ -46,9 +46,9 @@ class UsersCustomServerTest extends Scope 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ 'userId' => 'meldiron', - 'email' => 'matej@appwrite.io', - 'password' => 'my-superstr0ng-password', - 'name' => 'Matej Bačo' + 'email' => 'matej2@appwrite.io', + 'password' => 'someones-superstr0ng-password', + 'name' => 'Matej Bačo Second' ]); $this->assertEquals(409, $response1['headers']['status-code']); From 88ef9dfd3c8ebe6f2a70bf3885f5a256a01d9203 Mon Sep 17 00:00:00 2001 From: kodumbeats Date: Tue, 5 Oct 2021 10:29:43 -0400 Subject: [PATCH 7/8] style - pass clone of user object to workers --- app/controllers/api/users.php | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/app/controllers/api/users.php b/app/controllers/api/users.php index 20266d1fda..5023ccd040 100644 --- a/app/controllers/api/users.php +++ b/app/controllers/api/users.php @@ -719,26 +719,31 @@ App::delete('/v1/users/:userId') throw new Exception('User not found', 404); } - $emptyUser = clone $user; - $emptyUser->setAttribute("name", null); - $emptyUser->setAttribute("email", null); - $emptyUser->setAttribute("password", null); - $emptyUser->setAttribute("deleted", true); + // clone user object to send to workers + $clone = clone $user; - $dbForInternal->updateDocument('users', $userId, $emptyUser); + $user + ->setAttribute("name", null) + ->setAttribute("email", null); + ->setAttribute("password", null); + ->setAttribute("deleted", true) + ; + + $dbForInternal->updateDocument('users', $userId, $user); $deletes ->setParam('type', DELETE_TYPE_DOCUMENT) - ->setParam('document', $user) + ->setParam('document', $clone) ; $events - ->setParam('eventData', $response->output($user, Response::MODEL_USER)) + ->setParam('eventData', $response->output($clone, Response::MODEL_USER)) ; $usage ->setParam('users.delete', 1) ; + $response->noContent(); }); From 895da9dbef9c65a244b1b899145f6d65beadae80 Mon Sep 17 00:00:00 2001 From: Torsten Dittmann Date: Tue, 5 Oct 2021 22:37:17 +0200 Subject: [PATCH 8/8] fix semi-colons --- app/controllers/api/users.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/controllers/api/users.php b/app/controllers/api/users.php index 5023ccd040..86319ea5ec 100644 --- a/app/controllers/api/users.php +++ b/app/controllers/api/users.php @@ -724,8 +724,8 @@ App::delete('/v1/users/:userId') $user ->setAttribute("name", null) - ->setAttribute("email", null); - ->setAttribute("password", null); + ->setAttribute("email", null) + ->setAttribute("password", null) ->setAttribute("deleted", true) ;