From 0f0af0c7994a2e705c1960c1f11a531ceb72e835 Mon Sep 17 00:00:00 2001 From: Eldad Fux Date: Fri, 16 Jul 2021 07:38:18 +0300 Subject: [PATCH 01/11] Updated libs --- composer.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.lock b/composer.lock index c0fbb00ce8..0ce07f2453 100644 --- a/composer.lock +++ b/composer.lock @@ -6258,5 +6258,5 @@ "platform-overrides": { "php": "8.0" }, - "plugin-api-version": "2.1.0" + "plugin-api-version": "2.0.0" } From 04d6d33f6053c200362947a5ec76b0d654013e7f Mon Sep 17 00:00:00 2001 From: Eldad Fux Date: Fri, 16 Jul 2021 07:38:29 +0300 Subject: [PATCH 02/11] Fixed structure --- app/config/collections2.php | 166 +++++++++++++++++++++++++++++++++++- 1 file changed, 165 insertions(+), 1 deletion(-) diff --git a/app/config/collections2.php b/app/config/collections2.php index 0a69b81c32..4c6659317c 100644 --- a/app/config/collections2.php +++ b/app/config/collections2.php @@ -360,6 +360,169 @@ $collections = [ ], ], + // $session = new Document(array_merge( + // [ + // '$id' => $dbForInternal->getId(), + // 'userId' => $profile->getId(), + // 'provider' => Auth::SESSION_PROVIDER_EMAIL, + // 'providerUid' => $email, + // 'secret' => Auth::hash($secret), // One way hash encryption to protect DB leak + // 'expire' => $expiry, + // 'userAgent' => $request->getUserAgent('UNKNOWN'), + // 'ip' => $request->getIP(), + // 'countryCode' => ($record) ? \strtolower($record['country']['iso_code']) : '--', + // ], $detector->getOS(), $detector->getClient(), $detector->getDevice() + // )); + + 'sessions' => [ + '$collection' => Database::COLLECTIONS, + '$id' => 'sessions', + 'name' => 'Sessions', + 'attributes' => [ + [ + '$id' => 'userId', + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => Database::LENGTH_KEY, + 'signed' => true, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => [], + ], + [ + '$id' => 'email', + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => 1024, + 'signed' => true, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => [], + ], + [ + '$id' => 'status', + 'type' => Database::VAR_INTEGER, + 'format' => '', + 'size' => 0, + 'signed' => true, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => [], + ], + [ + '$id' => 'password', + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => 16384, + 'signed' => true, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => [], + ], + [ + '$id' => 'passwordUpdate', + 'type' => Database::VAR_INTEGER, + 'format' => '', + 'size' => 0, + 'signed' => true, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => [], + ], + [ + '$id' => 'prefs', + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => 16384, + 'signed' => true, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => ['json'] + ], + [ + '$id' => 'registration', + 'type' => Database::VAR_INTEGER, + 'format' => '', + 'size' => 0, + 'signed' => true, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => [], + ], + [ + '$id' => 'emailVerification', + 'type' => Database::VAR_BOOLEAN, + 'format' => '', + 'size' => 0, + 'signed' => true, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => [], + ], + [ + '$id' => 'reset', + 'type' => Database::VAR_BOOLEAN, + 'format' => '', + 'size' => 0, + 'signed' => true, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => [], + ], + [ + '$id' => 'sessions', + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => 16384, + 'signed' => true, + 'required' => false, + 'default' => null, + 'array' => true, + 'filters' => ['json'], + ], + [ + '$id' => 'tokens', + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => 16384, + 'signed' => true, + 'required' => false, + 'default' => null, + 'array' => true, + 'filters' => ['json'], + ], + [ + '$id' => 'memberships', + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => 16384, + 'signed' => true, + 'required' => false, + 'default' => null, + 'array' => true, + 'filters' => ['json'], + ], + ], + 'indexes' => [ + [ + '$id' => '_key_email', + 'type' => Database::INDEX_UNIQUE, + 'attributes' => ['email'], + 'lengths' => [1024], + 'orders' => [Database::ORDER_ASC], + ] + ], + ], + 'teams' => [ '$collection' => Database::COLLECTIONS, '$id' => 'teams', @@ -1047,11 +1210,12 @@ $collections = [ ] ], ], + 'certificates' => [ '$collection' => Database::COLLECTIONS, '$id' => 'certificates', 'name' => 'Certificates', - 'attributes' => [, + 'attributes' => [ [ '$id' => 'domain', 'type' => Database::VAR_STRING, From b4a65c2c1a10c09a418dd48bb60672c7e772c9ae Mon Sep 17 00:00:00 2001 From: Eldad Fux Date: Fri, 16 Jul 2021 07:39:31 +0300 Subject: [PATCH 03/11] Removed TODOs, fixed comments --- app/controllers/api/account.php | 6 +++--- app/controllers/api/functions.php | 1 - app/controllers/general.php | 2 +- app/workers/functions.php | 2 +- src/Appwrite/Utopia/Response/Model/Task.php | 2 +- src/Appwrite/Utopia/Response/Model/Team.php | 2 +- 6 files changed, 7 insertions(+), 8 deletions(-) diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php index 72d46ca177..f14282e2b4 100644 --- a/app/controllers/api/account.php +++ b/app/controllers/api/account.php @@ -1371,7 +1371,7 @@ App::post('/v1/account/recovery') $profile = $dbForInternal->findFirst('users', [new Query('email', Query::TYPE_EQUAL, [$email])], 1); // Get user by email address if (!$profile) { - throw new Exception('User not found', 404); // TODO maybe hide this + throw new Exception('User not found', 404); } if (Auth::USER_STATUS_BLOCKED == $profile->getAttribute('status')) { // Account is blocked @@ -1482,7 +1482,7 @@ App::put('/v1/account/recovery') $profile = $dbForInternal->getDocument('users', $userId); if ($profile->isEmpty()) { - throw new Exception('User not found', 404); // TODO maybe hide this + throw new Exception('User not found', 404); } $tokens = $profile->getAttribute('tokens', []); @@ -1662,7 +1662,7 @@ App::put('/v1/account/verification') $profile = $dbForInternal->getDocument('users', $userId); if ($profile->isEmpty()) { - throw new Exception('User not found', 404); // TODO maybe hide this + throw new Exception('User not found', 404); } $tokens = $profile->getAttribute('tokens', []); diff --git a/app/controllers/api/functions.php b/app/controllers/api/functions.php index 01bfd8c69a..fe2fc39127 100644 --- a/app/controllers/api/functions.php +++ b/app/controllers/api/functions.php @@ -143,7 +143,6 @@ App::get('/v1/functions/:functionId/usage') ->action(function ($functionId, $range, $response, $project, $dbForInternal, $register) { /** @var Appwrite\Utopia\Response $response */ /** @var Appwrite\Database\Document $project */ - /** @var Utopia\Database\Database $consoleDB */ /** @var Utopia\Database\Database $dbForInternal */ /** @var Utopia\Registry\Registry $register */ diff --git a/app/controllers/general.php b/app/controllers/general.php index 8b599a44c7..14f8a54eed 100644 --- a/app/controllers/general.php +++ b/app/controllers/general.php @@ -57,7 +57,7 @@ App::init(function ($utopia, $request, $response, $console, $project, $dbForCons $certificate = $dbForConsole->createDocument('certificates', $certificate); Authorization2::enable(); - Console::info('Issuing a TLS certificate for the master domain (' . $domain->get() . ') in a few seconds...'); // TODO move this to installation script + Console::info('Issuing a TLS certificate for the master domain (' . $domain->get() . ') in a few seconds...'); Resque::enqueue('v1-certificates', 'CertificatesV1', [ 'document' => $certificate, diff --git a/app/workers/functions.php b/app/workers/functions.php index 8cb6fafbb6..6b8910cece 100644 --- a/app/workers/functions.php +++ b/app/workers/functions.php @@ -123,7 +123,7 @@ Console::info(count($list)." functions listed in " . ($executionEnd - $execution * 7. Trigger usage log - DONE */ -//TODO aviod scheduled execution if delay is bigger than X offest +//TODO avoid scheduled execution if delay is bigger than X offest class FunctionsV1 extends Worker { diff --git a/src/Appwrite/Utopia/Response/Model/Task.php b/src/Appwrite/Utopia/Response/Model/Task.php index 974bd4bafb..69a673ea49 100644 --- a/src/Appwrite/Utopia/Response/Model/Task.php +++ b/src/Appwrite/Utopia/Response/Model/Task.php @@ -96,7 +96,7 @@ class Task extends Model ]) ->addRule('status', [ 'type' => self::TYPE_STRING, - 'description' => 'Task status. Possible values: play, pause', // TODO - change to enabled disabled + 'description' => 'Task status. Possible values: play, pause', 'default' => '', 'example' => 'enabled', ]) diff --git a/src/Appwrite/Utopia/Response/Model/Team.php b/src/Appwrite/Utopia/Response/Model/Team.php index b5f7482a19..48660324f5 100644 --- a/src/Appwrite/Utopia/Response/Model/Team.php +++ b/src/Appwrite/Utopia/Response/Model/Team.php @@ -28,7 +28,7 @@ class Team extends Model 'default' => 0, 'example' => 1592981250, ]) - ->addRule('sum', [ // TODO change key name? + ->addRule('sum', [ 'type' => self::TYPE_INTEGER, 'description' => 'Total sum of team members.', 'default' => 0, From 6471acb1e19b82830b4476f4191ed233af715ac5 Mon Sep 17 00:00:00 2001 From: Eldad Fux Date: Fri, 16 Jul 2021 07:40:01 +0300 Subject: [PATCH 04/11] Fixed injection name --- app/controllers/general.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/general.php b/app/controllers/general.php index 14f8a54eed..0706f7e30b 100644 --- a/app/controllers/general.php +++ b/app/controllers/general.php @@ -281,7 +281,7 @@ App::init(function ($utopia, $request, $response, $console, $project, $dbForCons throw new Exception('Password reset is required', 412); } -}, ['utopia', 'request', 'response', 'console', 'project', 'consoleDB', 'user', 'locale', 'clients']); +}, ['utopia', 'request', 'response', 'console', 'project', 'dbForConsole', 'user', 'locale', 'clients']); App::options(function ($request, $response) { /** @var Utopia\Swoole\Request $request */ From 0608103d6f82e78ba06b73867c7a78725e14d0be Mon Sep 17 00:00:00 2001 From: Eldad Fux Date: Fri, 16 Jul 2021 18:11:14 +0300 Subject: [PATCH 05/11] Updated sessions collection structure --- app/config/collections2.php | 181 ++++++++++++++++++++++++++---------- 1 file changed, 133 insertions(+), 48 deletions(-) diff --git a/app/config/collections2.php b/app/config/collections2.php index 4c6659317c..57362ec9d8 100644 --- a/app/config/collections2.php +++ b/app/config/collections2.php @@ -360,20 +360,6 @@ $collections = [ ], ], - // $session = new Document(array_merge( - // [ - // '$id' => $dbForInternal->getId(), - // 'userId' => $profile->getId(), - // 'provider' => Auth::SESSION_PROVIDER_EMAIL, - // 'providerUid' => $email, - // 'secret' => Auth::hash($secret), // One way hash encryption to protect DB leak - // 'expire' => $expiry, - // 'userAgent' => $request->getUserAgent('UNKNOWN'), - // 'ip' => $request->getIP(), - // 'countryCode' => ($record) ? \strtolower($record['country']['iso_code']) : '--', - // ], $detector->getOS(), $detector->getClient(), $detector->getDevice() - // )); - 'sessions' => [ '$collection' => Database::COLLECTIONS, '$id' => 'sessions', @@ -391,7 +377,7 @@ $collections = [ 'filters' => [], ], [ - '$id' => 'email', + '$id' => 'provider', 'type' => Database::VAR_STRING, 'format' => '', 'size' => 1024, @@ -402,7 +388,40 @@ $collections = [ 'filters' => [], ], [ - '$id' => 'status', + '$id' => 'providerUid', + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => 2048, + 'signed' => true, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => [], + ], + [ + '$id' => 'providerToken', + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => 2048, + 'signed' => true, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => [], + ], + [ + '$id' => 'secret', + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => 64, // https://www.tutorialspoint.com/how-long-is-the-sha256-hash-in-mysql + 'signed' => true, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => [], + ], + [ + '$id' => 'expire', 'type' => Database::VAR_INTEGER, 'format' => '', 'size' => 0, @@ -413,10 +432,10 @@ $collections = [ 'filters' => [], ], [ - '$id' => 'password', + '$id' => 'userAgent', 'type' => Database::VAR_STRING, 'format' => '', - 'size' => 16384, + 'size' => 2048, 'signed' => true, 'required' => false, 'default' => null, @@ -424,10 +443,10 @@ $collections = [ 'filters' => [], ], [ - '$id' => 'passwordUpdate', - 'type' => Database::VAR_INTEGER, + '$id' => 'ip', + 'type' => Database::VAR_STRING, 'format' => '', - 'size' => 0, + 'size' => 15, 'signed' => true, 'required' => false, 'default' => null, @@ -435,81 +454,147 @@ $collections = [ 'filters' => [], ], [ - '$id' => 'prefs', + '$id' => 'countryCode', 'type' => Database::VAR_STRING, 'format' => '', - 'size' => 16384, + 'size' => 2, 'signed' => true, 'required' => false, 'default' => null, 'array' => false, - 'filters' => ['json'] + 'filters' => [] ], [ - '$id' => 'registration', - 'type' => Database::VAR_INTEGER, + '$id' => 'osCode', + 'type' => Database::VAR_STRING, 'format' => '', - 'size' => 0, + 'size' => 256, 'signed' => true, 'required' => false, 'default' => null, 'array' => false, - 'filters' => [], + 'filters' => [] ], [ - '$id' => 'emailVerification', - 'type' => Database::VAR_BOOLEAN, + '$id' => 'osName', + 'type' => Database::VAR_STRING, 'format' => '', - 'size' => 0, + 'size' => 256, 'signed' => true, 'required' => false, 'default' => null, 'array' => false, - 'filters' => [], + 'filters' => [] ], [ - '$id' => 'reset', - 'type' => Database::VAR_BOOLEAN, + '$id' => 'osVersion', + 'type' => Database::VAR_STRING, 'format' => '', - 'size' => 0, + 'size' => 256, 'signed' => true, 'required' => false, 'default' => null, 'array' => false, - 'filters' => [], + 'filters' => [] ], [ - '$id' => 'sessions', + '$id' => 'clientType', 'type' => Database::VAR_STRING, 'format' => '', - 'size' => 16384, + 'size' => 256, 'signed' => true, 'required' => false, 'default' => null, - 'array' => true, - 'filters' => ['json'], + 'array' => false, + 'filters' => [] ], [ - '$id' => 'tokens', + '$id' => 'clientCode', 'type' => Database::VAR_STRING, 'format' => '', - 'size' => 16384, + 'size' => 256, 'signed' => true, 'required' => false, 'default' => null, - 'array' => true, - 'filters' => ['json'], + 'array' => false, + 'filters' => [] ], [ - '$id' => 'memberships', + '$id' => 'clientName', 'type' => Database::VAR_STRING, 'format' => '', - 'size' => 16384, + 'size' => 256, 'signed' => true, 'required' => false, 'default' => null, - 'array' => true, - 'filters' => ['json'], + 'array' => false, + 'filters' => [] + ], + [ + '$id' => 'clientVersion', + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => 256, + 'signed' => true, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => [] + ], + [ + '$id' => 'clientEngine', + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => 256, + 'signed' => true, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => [] + ], + [ + '$id' => 'clientEngineVersion', + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => 256, + 'signed' => true, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => [] + ], + [ + '$id' => 'deviceName', + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => 256, + 'signed' => true, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => [] + ], + [ + '$id' => 'deviceBrand', + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => 256, + 'signed' => true, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => [] + ], + [ + '$id' => 'deviceModel', + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => 256, + 'signed' => true, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => [] ], ], 'indexes' => [ From 2bf69d59f15dd9e073caaf6baacf704c42be2bdb Mon Sep 17 00:00:00 2001 From: Eldad Fux Date: Sat, 17 Jul 2021 13:04:43 +0300 Subject: [PATCH 06/11] Update session document --- app/config/collections2.php | 24 +++++++++++------------ app/controllers/api/account.php | 34 +++++++++++++++++++++++---------- app/controllers/api/teams.php | 7 +++++++ app/controllers/api/users.php | 12 +++++++++--- 4 files changed, 52 insertions(+), 25 deletions(-) diff --git a/app/config/collections2.php b/app/config/collections2.php index 57362ec9d8..5ce2d3e546 100644 --- a/app/config/collections2.php +++ b/app/config/collections2.php @@ -380,7 +380,7 @@ $collections = [ '$id' => 'provider', 'type' => Database::VAR_STRING, 'format' => '', - 'size' => 1024, + 'size' => 1000, 'signed' => true, 'required' => false, 'default' => null, @@ -402,7 +402,7 @@ $collections = [ '$id' => 'providerToken', 'type' => Database::VAR_STRING, 'format' => '', - 'size' => 2048, + 'size' => 16384, 'signed' => true, 'required' => false, 'default' => null, @@ -435,7 +435,7 @@ $collections = [ '$id' => 'userAgent', 'type' => Database::VAR_STRING, 'format' => '', - 'size' => 2048, + 'size' => 16384, 'signed' => true, 'required' => false, 'default' => null, @@ -597,15 +597,15 @@ $collections = [ 'filters' => [] ], ], - 'indexes' => [ - [ - '$id' => '_key_email', - 'type' => Database::INDEX_UNIQUE, - 'attributes' => ['email'], - 'lengths' => [1024], - 'orders' => [Database::ORDER_ASC], - ] - ], + // 'indexes' => [ + // [ + // '$id' => '_key_provider_providerUid', + // 'type' => Database::INDEX_KEY, + // 'attributes' => ['provider', 'providerUid'], + // 'lengths' => [100, 100], + // 'orders' => [Database::ORDER_ASC, Database::ORDER_ASC], + // ] + // ], ], 'teams' => [ diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php index f14282e2b4..67a789a872 100644 --- a/app/controllers/api/account.php +++ b/app/controllers/api/account.php @@ -192,8 +192,12 @@ App::post('/v1/account/sessions') Authorization::setRole('user:'.$profile->getId()); - $profile->setAttribute('sessions', $session, Document::SET_TYPE_APPEND); + $session = $dbForInternal->createDocument('sessions', $session + ->setAttribute('$read', ['user:'.$profile->getId()]) + ->setAttribute('$write', ['user:'.$profile->getId()]) + ); + $profile->setAttribute('sessions', $session, Document::SET_TYPE_APPEND); $profile = $dbForInternal->updateDocument('users', $profile->getId(), $profile); $audits @@ -428,9 +432,11 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect') $current = Auth::sessionVerify($sessions, Auth::$secret); if($current) { // Delete current session of new one. - foreach ($sessions as $key => $session) { + foreach ($sessions as $key => $session) { /** @var Document $session */ if ($current === $session['$id']) { unset($sessions[$key]); + + $dbForInternal->deleteDocument('sessions', $session->getId()); $dbForInternal->updateDocument('users', $user->getId(), $user->setAttribute('sessions', $sessions)); } } @@ -523,6 +529,11 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect') ; } + $session = $dbForInternal->createDocument('sessions', $session + ->setAttribute('$read', ['user:'.$user->getId()]) + ->setAttribute('$write', ['user:'.$user->getId()]) + ); + $user ->setAttribute('status', Auth::USER_STATUS_ACTIVATED) ->setAttribute('sessions', $session, Document::SET_TYPE_APPEND) @@ -668,6 +679,11 @@ App::post('/v1/account/sessions/anonymous') Authorization::setRole('user:'.$user->getId()); + $session = $dbForInternal->createDocument('sessions', $session + ->setAttribute('$read', ['user:'.$user->getId()]) + ->setAttribute('$write', ['user:'.$user->getId()]) + ); + $user = $dbForInternal->updateDocument('users', $user->getId(), $user->setAttribute('sessions', $session, Document::SET_TYPE_APPEND)); @@ -814,9 +830,7 @@ App::get('/v1/account/sessions') $countries = $locale->getText('countries'); $current = Auth::sessionVerify($sessions, Auth::$secret); - foreach ($sessions as $key => $session) { - /** @var Document $session */ - + foreach ($sessions as $key => $session) { /** @var Document $session */ $countryName = (isset($countries[strtoupper($session->getAttribute('countryCode'))])) ? $countries[strtoupper($session->getAttribute('countryCode'))] : $locale->getText('locale.country.unknown'); @@ -1213,12 +1227,12 @@ App::delete('/v1/account/sessions/:sessionId') $sessions = $user->getAttribute('sessions', []); - foreach ($sessions as $key => $session) { - /** @var Document $session */ - + foreach ($sessions as $key => $session) { /** @var Document $session */ if ($sessionId == $session->getId()) { unset($sessions[$key]); + $dbForInternal->deleteDocument('sessions', $session->getId()); + $audits ->setParam('userId', $user->getId()) ->setParam('event', 'account.sessions.delete') @@ -1289,8 +1303,8 @@ App::delete('/v1/account/sessions') $protocol = $request->getProtocol(); $sessions = $user->getAttribute('sessions', []); - foreach ($sessions as $session) { - /** @var Document $session */ + foreach ($sessions as $session) { /** @var Document $session */ + $dbForInternal->deleteDocument('sessions', $session->getId()); $audits ->setParam('userId', $user->getId()) diff --git a/app/controllers/api/teams.php b/app/controllers/api/teams.php index 39ced4b747..a8022cafcd 100644 --- a/app/controllers/api/teams.php +++ b/app/controllers/api/teams.php @@ -608,6 +608,8 @@ App::patch('/v1/teams/:teamId/memberships/:membershipId/status') // Log user in + Authorization::setRole('user:'.$user->getId()); + $detector = new Detector($request->getUserAgent('UNKNOWN')); $record = $geodb->get($request->getIP()); $expiry = \time() + Auth::TOKEN_EXPIRATION_LOGIN_LONG; @@ -624,6 +626,11 @@ App::patch('/v1/teams/:teamId/memberships/:membershipId/status') 'countryCode' => ($record) ? \strtolower($record['country']['iso_code']) : '--', ], $detector->getOS(), $detector->getClient(), $detector->getDevice())); + $session = $dbForInternal->createDocument('sessions', $session + ->setAttribute('$read', ['user:'.$user->getId()]) + ->setAttribute('$write', ['user:'.$user->getId()]) + ); + $user->setAttribute('sessions', $session, Document::SET_TYPE_APPEND); Authorization::setRole('user:'.$userId); diff --git a/app/controllers/api/users.php b/app/controllers/api/users.php index 9777e5b250..96e9af7872 100644 --- a/app/controllers/api/users.php +++ b/app/controllers/api/users.php @@ -430,12 +430,13 @@ App::delete('/v1/users/:userId/sessions/:sessionId') $sessions = $user->getAttribute('sessions', []); - foreach ($sessions as $key => $session) { - /** @var Document $session */ + foreach ($sessions as $key => $session) { /** @var Document $session */ if ($sessionId == $session->getId()) { unset($sessions[$key]); + $dbForInternal->deleteDocument('sessions', $session->getId()); + $user->setAttribute('sessions', $sessions); $events @@ -476,13 +477,18 @@ App::delete('/v1/users/:userId/sessions') throw new Exception('User not found', 404); } + $sessions = $user->getAttribute('sessions', []); + + foreach ($sessions as $key => $session) { /** @var Document $session */ + $dbForInternal->deleteDocument('sessions', $session->getId()); + } + $dbForInternal->updateDocument('users', $user->getId(), $user->getAttribute('sessions', [])); $events ->setParam('eventData', $response->output2($user, Response::MODEL_USER)) ; - // TODO : Response filter implementation $response->noContent(); }); From 46960d67319135f8b45526c5caeceda2f213b7b5 Mon Sep 17 00:00:00 2001 From: Eldad Fux Date: Sat, 17 Jul 2021 21:59:34 +0300 Subject: [PATCH 07/11] Hide index --- app/config/collections2.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/config/collections2.php b/app/config/collections2.php index 5ce2d3e546..6ded2ab626 100644 --- a/app/config/collections2.php +++ b/app/config/collections2.php @@ -597,7 +597,7 @@ $collections = [ 'filters' => [] ], ], - // 'indexes' => [ + 'indexes' => [ // [ // '$id' => '_key_provider_providerUid', // 'type' => Database::INDEX_KEY, @@ -605,7 +605,7 @@ $collections = [ // 'lengths' => [100, 100], // 'orders' => [Database::ORDER_ASC, Database::ORDER_ASC], // ] - // ], + ], ], 'teams' => [ From 318c4843cacc206fce41cac1fa6aef13ff6d3041 Mon Sep 17 00:00:00 2001 From: Eldad Fux Date: Sat, 17 Jul 2021 21:59:54 +0300 Subject: [PATCH 08/11] Updated error template --- app/controllers/general.php | 2 ++ app/views/general/error.phtml | 28 ++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/app/controllers/general.php b/app/controllers/general.php index 0706f7e30b..88dcb5d152 100644 --- a/app/controllers/general.php +++ b/app/controllers/general.php @@ -370,10 +370,12 @@ App::error(function ($error, $utopia, $request, $response, $layout, $project) { $comp = new View($template); $comp + ->setParam('development', App::isDevelopment()) ->setParam('projectName', $project->getAttribute('name')) ->setParam('projectURL', $project->getAttribute('url')) ->setParam('message', $error->getMessage()) ->setParam('code', $code) + ->setParam('trace', $error->getTrace()) ; $layout diff --git a/app/views/general/error.phtml b/app/views/general/error.phtml index be7e3dc9c5..66f6cf77d7 100644 --- a/app/views/general/error.phtml +++ b/app/views/general/error.phtml @@ -1,7 +1,9 @@ getParam('development', false); $code = $this->getParam('code', 500); $errorID = $this->getParam('errorID', 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'); $message = $this->getParam('message', ''); +$trace = $this->getParam('trace', []); $projectName = $this->getParam('projectName', ''); $projectURL = $this->getParam('projectURL', ''); ?> @@ -18,4 +20,30 @@ $projectURL = $this->getParam('projectURL', '');

Back to

+ + +
+ +

Error Trace

+ + + + $value): ?> + + + + + + +
+ + + + + +
+ +
+ + From 6fe19370f3dc7ef34bc59caec96904dbca08a290 Mon Sep 17 00:00:00 2001 From: Eldad Fux Date: Sun, 18 Jul 2021 00:21:33 +0300 Subject: [PATCH 09/11] Fixed OAuth2 tests --- app/controllers/api/account.php | 28 ++++++++----------- .../Account/AccountCustomClientTest.php | 17 +++++++++++ 2 files changed, 29 insertions(+), 16 deletions(-) diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php index 67a789a872..4a44d4fc4d 100644 --- a/app/controllers/api/account.php +++ b/app/controllers/api/account.php @@ -442,27 +442,23 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect') } } - $user = (empty($user->getId())) ? $dbForInternal->getCollectionFirst([ // Get user by provider id - 'limit' => 1, - 'filters' => [ - '$collection='.Database::SYSTEM_COLLECTION_USERS, - 'sessions.provider='.$provider, - 'sessions.providerUid='.$oauth2ID - ], - ]) : $user; + $user = ($user->isEmpty()) ? $dbForInternal->findFirst('sessions', [ // Get user by provider id + new Query('provider', QUERY::TYPE_EQUAL, [$provider]), + new Query('providerUid', QUERY::TYPE_EQUAL, [$oauth2ID]), + ], 1) : $user; - if (empty($user)) { // No user logged in or with OAuth2 provider ID, create new one or connect with account with same email + if ($user === false || $user->isEmpty()) { // No user logged in or with OAuth2 provider ID, create new one or connect with account with same email $name = $oauth2->getUserName($accessToken); $email = $oauth2->getUserEmail($accessToken); $user = $dbForInternal->findFirst('users', [new Query('email', Query::TYPE_EQUAL, [$email])], 1); // Get user by email address - if (!$user || empty($user->getId())) { // Last option -> create the user, generate random password + if ($user === false || $user->isEmpty()) { // Last option -> create the user, generate random password $limit = $project->getAttribute('usersAuthLimit', 0); if ($limit !== 0) { $sum = $dbForInternal->count('users', [], APP_LIMIT_COUNT); - + if($sum >= $limit) { throw new Exception('Project registration is restricted. Contact your administrator for more information.', 501); } @@ -529,11 +525,6 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect') ; } - $session = $dbForInternal->createDocument('sessions', $session - ->setAttribute('$read', ['user:'.$user->getId()]) - ->setAttribute('$write', ['user:'.$user->getId()]) - ); - $user ->setAttribute('status', Auth::USER_STATUS_ACTIVATED) ->setAttribute('sessions', $session, Document::SET_TYPE_APPEND) @@ -541,6 +532,11 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect') Authorization::setRole('user:'.$user->getId()); + $session = $dbForInternal->createDocument('sessions', $session + ->setAttribute('$read', ['user:'.$user->getId()]) + ->setAttribute('$write', ['user:'.$user->getId()]) + ); + $user = $dbForInternal->updateDocument('users', $user->getId(), $user); $audits diff --git a/tests/e2e/Services/Account/AccountCustomClientTest.php b/tests/e2e/Services/Account/AccountCustomClientTest.php index 7c04b59f63..5ff9d46d7c 100644 --- a/tests/e2e/Services/Account/AccountCustomClientTest.php +++ b/tests/e2e/Services/Account/AccountCustomClientTest.php @@ -14,6 +14,9 @@ class AccountCustomClientTest extends Scope use ProjectCustom; use SideClient; + /** + * @depends testCreateAccountSession + */ public function testCreateOAuth2AccountSession():array { $provider = 'mock'; @@ -384,6 +387,17 @@ class AccountCustomClientTest extends Scope /** * Test for SUCCESS */ + $response = $this->client->call(Client::METHOD_GET, '/account', array_merge([ + 'origin' => 'http://localhost', + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'cookie' => 'a_session_'.$this->getProject()['$id'].'=' . $session, + ])); + + $this->assertEquals($response['headers']['status-code'], 200); + + $userId = $response['body']['$id'] ?? ''; + $response = $this->client->call(Client::METHOD_PATCH, '/projects/'.$this->getProject()['$id'].'/oauth2', array_merge([ 'origin' => 'http://localhost', 'content-type' => 'application/json', @@ -406,6 +420,8 @@ class AccountCustomClientTest extends Scope 'success' => 'http://localhost/v1/mock/tests/general/oauth2/success', 'failure' => 'http://localhost/v1/mock/tests/general/oauth2/failure', ]); + + $session = $this->client->parseCookie((string)$response['headers']['set-cookie'])['a_session_'.$this->getProject()['$id']]; $this->assertEquals(200, $response['headers']['status-code']); $this->assertEquals('success', $response['body']['result']); @@ -418,6 +434,7 @@ class AccountCustomClientTest extends Scope ])); $this->assertEquals($response['headers']['status-code'], 200); + $this->assertEquals($response['body']['$id'], $userId); $this->assertEquals($response['body']['name'], 'User Name'); $this->assertEquals($response['body']['email'], 'user@localhost.test'); From 09a1f609be3df4fc41e6392b5075e68e2f648c30 Mon Sep 17 00:00:00 2001 From: Eldad Fux Date: Mon, 19 Jul 2021 18:02:05 +0300 Subject: [PATCH 10/11] Changed IP length --- app/config/collections2.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/config/collections2.php b/app/config/collections2.php index 6ded2ab626..ce59a1d1b0 100644 --- a/app/config/collections2.php +++ b/app/config/collections2.php @@ -446,7 +446,7 @@ $collections = [ '$id' => 'ip', 'type' => Database::VAR_STRING, 'format' => '', - 'size' => 15, + 'size' => 45, // https://stackoverflow.com/a/166157/2299554 'signed' => true, 'required' => false, 'default' => null, From f0657d6ff3e2b72683563ba8ac176acff278f5de Mon Sep 17 00:00:00 2001 From: Eldad Fux Date: Mon, 19 Jul 2021 18:03:15 +0300 Subject: [PATCH 11/11] Changed provider length --- app/config/collections2.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/config/collections2.php b/app/config/collections2.php index ce59a1d1b0..365fac2c55 100644 --- a/app/config/collections2.php +++ b/app/config/collections2.php @@ -380,7 +380,7 @@ $collections = [ '$id' => 'provider', 'type' => Database::VAR_STRING, 'format' => '', - 'size' => 1000, + 'size' => 128, 'signed' => true, 'required' => false, 'default' => null,