From 0dec176bb8de9200111aecb06a35160cd1ab46b2 Mon Sep 17 00:00:00 2001 From: Eldad Fux Date: Sun, 21 Jun 2020 10:40:50 +0300 Subject: [PATCH 01/10] Updated first and last description --- app/controllers/api/database.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/controllers/api/database.php b/app/controllers/api/database.php index d8ecedab84..c87622a15e 100644 --- a/app/controllers/api/database.php +++ b/app/controllers/api/database.php @@ -477,8 +477,8 @@ $utopia->get('/v1/database/collections/:collectionId/documents') ->param('orderType', 'ASC', function () { return new WhiteList(array('DESC', 'ASC')); }, 'Order direction. Possible values are DESC for descending order, or ASC for ascending order.', true) ->param('orderCast', 'string', function () { return new WhiteList(array('int', 'string', 'date', 'time', 'datetime')); }, 'Order field type casting. Possible values are int, string, date, time or datetime. The database will attempt to cast the order field to the value you pass here. The default value is a string.', true) ->param('search', '', function () { return new Text(256); }, 'Search query. Enter any free text search. The database will try to find a match against all document attributes and children.', true) - ->param('first', 0, function () { return new Range(0, 1); }, 'Return only the first document. Pass 1 for true or 0 for false. The default value is 0.', true) - ->param('last', 0, function () { return new Range(0, 1); }, 'Return only the last document. Pass 1 for true or 0 for false. The default value is 0.', true) + ->param('first', 0, function () { return new Range(0, 1); }, 'Return only the first document. Pass 1 for true or 0 for false. The default value is 0. This option refers to the first element in your current documents range (limit/offset), and not the entire collection.', true) + ->param('last', 0, function () { return new Range(0, 1); }, 'Return only the last document. Pass 1 for true or 0 for false. The default value is 0. This option refers to the last element in your current documents range (limit/offset), and not the entire collection.', true) ->action( function ($collectionId, $filters, $offset, $limit, $orderField, $orderType, $orderCast, $search, $first, $last) use ($response, $projectDB, $isDev) { $collection = $projectDB->getDocument($collectionId, $isDev); From 569560d4566f1300bb7c698f7b5987e193eb9308 Mon Sep 17 00:00:00 2001 From: Eldad Fux Date: Sun, 21 Jun 2020 10:41:44 +0300 Subject: [PATCH 02/10] Unused imports --- app/controllers/api/database.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/controllers/api/database.php b/app/controllers/api/database.php index c87622a15e..96d0b4db93 100644 --- a/app/controllers/api/database.php +++ b/app/controllers/api/database.php @@ -10,9 +10,9 @@ use Utopia\Validator\WhiteList; use Utopia\Validator\Text; use Utopia\Validator\ArrayList; use Utopia\Validator\JSON; -use Utopia\Locale\Locale; -use Utopia\Audit\Audit; -use Utopia\Audit\Adapters\MySQL as AuditAdapter; +// use Utopia\Locale\Locale; +// use Utopia\Audit\Audit; +// use Utopia\Audit\Adapters\MySQL as AuditAdapter; use Appwrite\Database\Database; use Appwrite\Database\Document; use Appwrite\Database\Validator\UID; From 1b549092c4056742146ba3347a885bb6c040b5bc Mon Sep 17 00:00:00 2001 From: Eldad Fux Date: Sun, 21 Jun 2020 14:56:42 +0300 Subject: [PATCH 03/10] Added support for "loose" boolean in query strings --- app/controllers/api/avatars.php | 5 ++++- app/controllers/api/database.php | 12 ++++++++---- app/controllers/api/projects.php | 15 +++++++++------ app/controllers/web/home.php | 4 ++++ composer.json | 2 +- composer.lock | 22 +++++++++++----------- 6 files changed, 37 insertions(+), 23 deletions(-) diff --git a/app/controllers/api/avatars.php b/app/controllers/api/avatars.php index 4bff678c5d..86c85700e9 100644 --- a/app/controllers/api/avatars.php +++ b/app/controllers/api/avatars.php @@ -11,6 +11,7 @@ use Utopia\Cache\Cache; use Utopia\Cache\Adapter\Filesystem; use Appwrite\Resize\Resize; use Appwrite\URL\URL as URLParse; +use Appwrite\Utopia\Validator\Boolean; use BaconQrCode\Renderer\ImageRenderer; use BaconQrCode\Renderer\Image\ImagickImageBackEnd; use BaconQrCode\Renderer\RendererStyle\RendererStyle; @@ -363,7 +364,7 @@ $utopia->get('/v1/avatars/qr') ->param('text', '', function () { return new Text(512); }, 'Plain text to be converted to QR code image.') ->param('size', 400, function () { return new Range(0, 1000); }, 'QR code size. Pass an integer between 0 to 1000. Defaults to 400.', true) ->param('margin', 1, function () { return new Range(0, 10); }, 'Margin from edge. Pass an integer between 0 to 10. Defaults to 1.', true) - ->param('download', 0, function () { return new Range(0, 1); }, 'Return resulting image with \'Content-Disposition: attachment \' headers for the browser to start downloading it. Pass 0 for no header, or 1 for otherwise. Default value is set to 0.', true) + ->param('download', false, function () { return new Boolean(true); }, 'Return resulting image with \'Content-Disposition: attachment \' headers for the browser to start downloading it. Pass 0 for no header, or 1 for otherwise. Default value is set to 0.', true) ->label('scope', 'avatars.read') ->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER]) ->label('sdk.namespace', 'avatars') @@ -372,6 +373,8 @@ $utopia->get('/v1/avatars/qr') ->label('sdk.description', '/docs/references/avatars/get-qr.md') ->action( function ($text, $size, $margin, $download) use ($response) { + $download = ($download === '1' || $download === 'true' || $download === 1 || $download === true); + $renderer = new ImageRenderer( new RendererStyle($size, $margin), new ImagickImageBackEnd('png', 100) diff --git a/app/controllers/api/database.php b/app/controllers/api/database.php index 96d0b4db93..5e5a521461 100644 --- a/app/controllers/api/database.php +++ b/app/controllers/api/database.php @@ -5,6 +5,7 @@ global $utopia, $register, $request, $response, $webhook, $audit, $projectDB; use Utopia\App; use Utopia\Exception; use Utopia\Response; +use Utopia\Validator\Boolean; use Utopia\Validator\Range; use Utopia\Validator\WhiteList; use Utopia\Validator\Text; @@ -22,8 +23,9 @@ use Appwrite\Database\Validator\Collection; use Appwrite\Database\Validator\Authorization; use Appwrite\Database\Exception\Authorization as AuthorizationException; use Appwrite\Database\Exception\Structure as StructureException; -use DeviceDetector\DeviceDetector; -use GeoIp2\Database\Reader; + +// use DeviceDetector\DeviceDetector; +// use GeoIp2\Database\Reader; include_once __DIR__ . '/../shared/api.php'; @@ -477,11 +479,13 @@ $utopia->get('/v1/database/collections/:collectionId/documents') ->param('orderType', 'ASC', function () { return new WhiteList(array('DESC', 'ASC')); }, 'Order direction. Possible values are DESC for descending order, or ASC for ascending order.', true) ->param('orderCast', 'string', function () { return new WhiteList(array('int', 'string', 'date', 'time', 'datetime')); }, 'Order field type casting. Possible values are int, string, date, time or datetime. The database will attempt to cast the order field to the value you pass here. The default value is a string.', true) ->param('search', '', function () { return new Text(256); }, 'Search query. Enter any free text search. The database will try to find a match against all document attributes and children.', true) - ->param('first', 0, function () { return new Range(0, 1); }, 'Return only the first document. Pass 1 for true or 0 for false. The default value is 0. This option refers to the first element in your current documents range (limit/offset), and not the entire collection.', true) - ->param('last', 0, function () { return new Range(0, 1); }, 'Return only the last document. Pass 1 for true or 0 for false. The default value is 0. This option refers to the last element in your current documents range (limit/offset), and not the entire collection.', true) + ->param('first', false, function () { return new Boolean(true); }, 'Return only the first document. Pass 1 for true or 0 for false. The default value is 0. This option refers to the first element in your current documents range (limit/offset), and not the entire collection.', true) + ->param('last', false, function () { return new Boolean(true); }, 'Return only the last document. Pass 1 for true or 0 for false. The default value is 0. This option refers to the last element in your current documents range (limit/offset), and not the entire collection.', true) ->action( function ($collectionId, $filters, $offset, $limit, $orderField, $orderType, $orderCast, $search, $first, $last) use ($response, $projectDB, $isDev) { $collection = $projectDB->getDocument($collectionId, $isDev); + $first = ($first === '1' || $first === 'true' || $first === 1 || $first === true); + $last = ($last === '1' || $last === 'true' || $last === 1 || $last === true); if (\is_null($collection->getId()) || Database::SYSTEM_COLLECTION_COLLECTIONS != $collection->getCollection()) { throw new Exception('Collection not found', 404); diff --git a/app/controllers/api/projects.php b/app/controllers/api/projects.php index 4511c34807..10145074c2 100644 --- a/app/controllers/api/projects.php +++ b/app/controllers/api/projects.php @@ -19,6 +19,7 @@ use Appwrite\Database\Document; use Appwrite\Database\Validator\UID; use Appwrite\OpenSSL\OpenSSL; use Appwrite\Network\Validator\CNAME; +use Appwrite\Utopia\Validator\Boolean; use Cron\CronExpression; include_once __DIR__ . '/../shared/api.php'; @@ -448,7 +449,7 @@ $utopia->post('/v1/projects/:projectId/webhooks') ->param('name', null, function () { return new Text(256); }, 'Webhook name.') ->param('events', null, function () { return new ArrayList(new Text(256)); }, 'Webhook events list.') ->param('url', null, function () { return new Text(2000); }, 'Webhook URL.') - ->param('security', null, function () { return new Range(0, 1); }, 'Certificate verification, 0 for disabled or 1 for enabled.') + ->param('security', false, function () { return new Boolean(true); }, 'Certificate verification, false for disabled or true for enabled.') ->param('httpUser', '', function () { return new Text(256); }, 'Webhook HTTP user.', true) ->param('httpPass', '', function () { return new Text(256); }, 'Webhook HTTP password.', true) ->action( @@ -459,6 +460,7 @@ $utopia->post('/v1/projects/:projectId/webhooks') throw new Exception('Project not found', 404); } + $security = ($security === '1' || $security === 'true' || $security === 1 || $security === true); $key = $request->getServer('_APP_OPENSSL_KEY_V1'); $iv = OpenSSL::randomPseudoBytes(OpenSSL::cipherIVLength(OpenSSL::CIPHER_AES_128_GCM)); $tag = null; @@ -578,8 +580,7 @@ $utopia->put('/v1/projects/:projectId/webhooks/:webhookId') ->param('name', null, function () { return new Text(256); }, 'Webhook name.') ->param('events', null, function () { return new ArrayList(new Text(256)); }, 'Webhook events list.') ->param('url', null, function () { return new Text(2000); }, 'Webhook URL.') - ->param('security', null, function () { return new Range(0, 1); }, 'Certificate verification, 0 for disabled or 1 for enabled.') - ->param('httpUser', '', function () { return new Text(256); }, 'Webhook HTTP user.', true) + ->param('security', false, function () { return new Boolean(true); }, 'Certificate verification, false for disabled or true for enabled.') ->param('httpUser', '', function () { return new Text(256); }, 'Webhook HTTP user.', true) ->param('httpPass', '', function () { return new Text(256); }, 'Webhook HTTP password.', true) ->action( function ($projectId, $webhookId, $name, $events, $url, $security, $httpUser, $httpPass) use ($request, $response, $consoleDB) { @@ -589,6 +590,7 @@ $utopia->put('/v1/projects/:projectId/webhooks/:webhookId') throw new Exception('Project not found', 404); } + $security = ($security === '1' || $security === 'true' || $security === 1 || $security === true); $key = $request->getServer('_APP_OPENSSL_KEY_V1'); $iv = OpenSSL::randomPseudoBytes(OpenSSL::cipherIVLength(OpenSSL::CIPHER_AES_128_GCM)); $tag = null; @@ -819,8 +821,7 @@ $utopia->post('/v1/projects/:projectId/tasks') ->param('name', null, function () { return new Text(256); }, 'Task name.') ->param('status', null, function () { return new WhiteList(['play', 'pause']); }, 'Task status.') ->param('schedule', null, function () { return new Cron(); }, 'Task schedule CRON syntax.') - ->param('security', null, function () { return new Range(0, 1); }, 'Certificate verification, 0 for disabled or 1 for enabled.') - ->param('httpMethod', '', function () { return new WhiteList(['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS', 'TRACE', 'CONNECT']); }, 'Task HTTP method.') + ->param('security', false, function () { return new Boolean(true); }, 'Certificate verification, false for disabled or true for enabled.') ->param('httpMethod', '', function () { return new WhiteList(['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS', 'TRACE', 'CONNECT']); }, 'Task HTTP method.') ->param('httpUrl', '', function () { return new URL(); }, 'Task HTTP URL') ->param('httpHeaders', null, function () { return new ArrayList(new Text(256)); }, 'Task HTTP headers list.', true) ->param('httpUser', '', function () { return new Text(256); }, 'Task HTTP user.', true) @@ -836,6 +837,7 @@ $utopia->post('/v1/projects/:projectId/tasks') $cron = CronExpression::factory($schedule); $next = ($status == 'play') ? $cron->getNextRunDate()->format('U') : null; + $security = ($security === '1' || $security === 'true' || $security === 1 || $security === true); $key = $request->getServer('_APP_OPENSSL_KEY_V1'); $iv = OpenSSL::randomPseudoBytes(OpenSSL::cipherIVLength(OpenSSL::CIPHER_AES_128_GCM)); $tag = null; @@ -966,7 +968,7 @@ $utopia->put('/v1/projects/:projectId/tasks/:taskId') ->param('name', null, function () { return new Text(256); }, 'Task name.') ->param('status', null, function () { return new WhiteList(['play', 'pause']); }, 'Task status.') ->param('schedule', null, function () { return new Cron(); }, 'Task schedule CRON syntax.') - ->param('security', null, function () { return new Range(0, 1); }, 'Certificate verification, 0 for disabled or 1 for enabled.') + ->param('security', false, function () { return new Boolean(true); }, 'Certificate verification, false for disabled or true for enabled.') ->param('httpMethod', '', function () { return new WhiteList(['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS', 'TRACE', 'CONNECT']); }, 'Task HTTP method.') ->param('httpUrl', '', function () { return new URL(); }, 'Task HTTP URL.') ->param('httpHeaders', null, function () { return new ArrayList(new Text(256)); }, 'Task HTTP headers list.', true) @@ -989,6 +991,7 @@ $utopia->put('/v1/projects/:projectId/tasks/:taskId') $cron = CronExpression::factory($schedule); $next = ($status == 'play') ? $cron->getNextRunDate()->format('U') : null; + $security = ($security === '1' || $security === 'true' || $security === 1 || $security === true); $key = $request->getServer('_APP_OPENSSL_KEY_V1'); $iv = OpenSSL::randomPseudoBytes(OpenSSL::cipherIVLength(OpenSSL::CIPHER_AES_128_GCM)); $tag = null; diff --git a/app/controllers/web/home.php b/app/controllers/web/home.php index cfec346b91..8dda07111c 100644 --- a/app/controllers/web/home.php +++ b/app/controllers/web/home.php @@ -453,6 +453,10 @@ $utopia->get('/open-api-2.json') $node['type'] = 'string'; $node['x-example'] = '['.\strtoupper(fromCamelCase($node['name'])).']'; break; + case 'Utopia\Validator\Boolean': + $node['type'] = 'boolean'; + $node['x-example'] = false; + break; case 'Appwrite\Database\Validator\UID': $node['type'] = 'string'; $node['x-example'] = '['.\strtoupper(fromCamelCase($node['name'])).']'; diff --git a/composer.json b/composer.json index 8af76121cd..51bf3762da 100644 --- a/composer.json +++ b/composer.json @@ -32,7 +32,7 @@ "appwrite/php-clamav": "1.0.*", - "utopia-php/framework": "0.3.5", + "utopia-php/framework": "0.3.7", "utopia-php/abuse": "0.2.*", "utopia-php/audit": "0.3.*", "utopia-php/cache": "0.2.*", diff --git a/composer.lock b/composer.lock index 459a9bd325..7c452fe458 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": "9deec50e5a99197511b5efbcaa9593bd", + "content-hash": "1df9fdb337c6030db4bb5f0e9868f9c3", "packages": [ { "name": "appwrite/php-clamav", @@ -1546,16 +1546,16 @@ }, { "name": "utopia-php/domains", - "version": "0.2.0", + "version": "0.2.1", "source": { "type": "git", "url": "https://github.com/utopia-php/domains.git", - "reference": "1665e1d9932afa3be63b5c1e0dcfe01fe77d8e73" + "reference": "98e85296867a59c9d712d6ed768a5c5b2b297b43" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/domains/zipball/1665e1d9932afa3be63b5c1e0dcfe01fe77d8e73", - "reference": "1665e1d9932afa3be63b5c1e0dcfe01fe77d8e73", + "url": "https://api.github.com/repos/utopia-php/domains/zipball/98e85296867a59c9d712d6ed768a5c5b2b297b43", + "reference": "98e85296867a59c9d712d6ed768a5c5b2b297b43", "shasum": "" }, "require": { @@ -1592,20 +1592,20 @@ "upf", "utopia" ], - "time": "2020-02-23T07:40:02+00:00" + "time": "2020-06-20T11:47:04+00:00" }, { "name": "utopia-php/framework", - "version": "0.3.5", + "version": "0.3.7", "source": { "type": "git", "url": "https://github.com/utopia-php/framework.git", - "reference": "ca2ebe37936983d786f57bae8ee6e006299f4942" + "reference": "23156b3d604fd9586f2e8c6c449b2fc6a82c10bc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/framework/zipball/ca2ebe37936983d786f57bae8ee6e006299f4942", - "reference": "ca2ebe37936983d786f57bae8ee6e006299f4942", + "url": "https://api.github.com/repos/utopia-php/framework/zipball/23156b3d604fd9586f2e8c6c449b2fc6a82c10bc", + "reference": "23156b3d604fd9586f2e8c6c449b2fc6a82c10bc", "shasum": "" }, "require": { @@ -1636,7 +1636,7 @@ "php", "upf" ], - "time": "2020-06-20T11:33:46+00:00" + "time": "2020-06-21T11:29:58+00:00" }, { "name": "utopia-php/locale", From a3aeecfd0db1ee8b2efdd719aebda7b828044c00 Mon Sep 17 00:00:00 2001 From: Eldad Fux Date: Sun, 21 Jun 2020 15:12:13 +0300 Subject: [PATCH 04/10] Removed first and last params --- CHANGES.md | 3 +++ app/controllers/api/database.php | 46 +++++++++++++------------------- 2 files changed, 22 insertions(+), 27 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 233301df9e..9833893b5d 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -32,6 +32,9 @@ - Fixed missing custom scopes param for OAuth2 session create API route - Fixed wrong JSON validation when creating and updating database documnets +## Breaking Changes +- **Deprecated** `first` and `last` query params for documents list route in the database API + ## Security - Access to Health API now requires authentication with an API Key with access to `health.read` scope allowed diff --git a/app/controllers/api/database.php b/app/controllers/api/database.php index d8ecedab84..957d90d7b5 100644 --- a/app/controllers/api/database.php +++ b/app/controllers/api/database.php @@ -477,10 +477,8 @@ $utopia->get('/v1/database/collections/:collectionId/documents') ->param('orderType', 'ASC', function () { return new WhiteList(array('DESC', 'ASC')); }, 'Order direction. Possible values are DESC for descending order, or ASC for ascending order.', true) ->param('orderCast', 'string', function () { return new WhiteList(array('int', 'string', 'date', 'time', 'datetime')); }, 'Order field type casting. Possible values are int, string, date, time or datetime. The database will attempt to cast the order field to the value you pass here. The default value is a string.', true) ->param('search', '', function () { return new Text(256); }, 'Search query. Enter any free text search. The database will try to find a match against all document attributes and children.', true) - ->param('first', 0, function () { return new Range(0, 1); }, 'Return only the first document. Pass 1 for true or 0 for false. The default value is 0.', true) - ->param('last', 0, function () { return new Range(0, 1); }, 'Return only the last document. Pass 1 for true or 0 for false. The default value is 0.', true) ->action( - function ($collectionId, $filters, $offset, $limit, $orderField, $orderType, $orderCast, $search, $first, $last) use ($response, $projectDB, $isDev) { + function ($collectionId, $filters, $offset, $limit, $orderField, $orderType, $orderCast, $search) use ($response, $projectDB, $isDev) { $collection = $projectDB->getDocument($collectionId, $isDev); if (\is_null($collection->getId()) || Database::SYSTEM_COLLECTION_COLLECTIONS != $collection->getCollection()) { @@ -494,38 +492,32 @@ $utopia->get('/v1/database/collections/:collectionId/documents') 'orderType' => $orderType, 'orderCast' => $orderCast, 'search' => $search, - 'first' => (bool) $first, - 'last' => (bool) $last, 'filters' => \array_merge($filters, [ '$collection='.$collectionId, ]), ]); - if ($first || $last) { - $response->json((!empty($list) ? $list->getArrayCopy() : [])); - } else { - if ($isDev) { - $collection - ->setAttribute('debug', $projectDB->getDebug()) - ->setAttribute('limit', $limit) - ->setAttribute('offset', $offset) - ->setAttribute('orderField', $orderField) - ->setAttribute('orderType', $orderType) - ->setAttribute('orderCast', $orderCast) - ->setAttribute('filters', $filters) - ; - } - + if ($isDev) { $collection - ->setAttribute('sum', $projectDB->getSum()) - ->setAttribute('documents', $list) + ->setAttribute('debug', $projectDB->getDebug()) + ->setAttribute('limit', $limit) + ->setAttribute('offset', $offset) + ->setAttribute('orderField', $orderField) + ->setAttribute('orderType', $orderType) + ->setAttribute('orderCast', $orderCast) + ->setAttribute('filters', $filters) ; - - /* - * View - */ - $response->json($collection->getArrayCopy(/*['$id', '$collection', 'name', 'documents']*/[], ['rules'])); } + + $collection + ->setAttribute('sum', $projectDB->getSum()) + ->setAttribute('documents', $list) + ; + + /* + * View + */ + $response->json($collection->getArrayCopy(/*['$id', '$collection', 'name', 'documents']*/[], ['rules'])); } ); From 2bc181a057da8ea94d0faaf87680fb234590e108 Mon Sep 17 00:00:00 2001 From: Eldad Fux Date: Sun, 21 Jun 2020 15:18:00 +0300 Subject: [PATCH 05/10] Fixed tests --- app/controllers/api/avatars.php | 2 +- app/controllers/api/projects.php | 3 +-- public/index.php | 6 +++--- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/app/controllers/api/avatars.php b/app/controllers/api/avatars.php index 86c85700e9..b3486f3583 100644 --- a/app/controllers/api/avatars.php +++ b/app/controllers/api/avatars.php @@ -3,6 +3,7 @@ global $utopia, $request, $response; use Utopia\Exception; +use Utopia\Validator\Boolean; use Utopia\Validator\Text; use Utopia\Validator\WhiteList; use Utopia\Validator\Range; @@ -11,7 +12,6 @@ use Utopia\Cache\Cache; use Utopia\Cache\Adapter\Filesystem; use Appwrite\Resize\Resize; use Appwrite\URL\URL as URLParse; -use Appwrite\Utopia\Validator\Boolean; use BaconQrCode\Renderer\ImageRenderer; use BaconQrCode\Renderer\Image\ImagickImageBackEnd; use BaconQrCode\Renderer\RendererStyle\RendererStyle; diff --git a/app/controllers/api/projects.php b/app/controllers/api/projects.php index 10145074c2..799987114b 100644 --- a/app/controllers/api/projects.php +++ b/app/controllers/api/projects.php @@ -5,10 +5,10 @@ global $utopia, $request, $response, $register, $user, $consoleDB, $projectDB, $ use Utopia\Exception; use Utopia\Response; use Utopia\Validator\ArrayList; +use Utopia\Validator\Boolean; use Utopia\Validator\Domain as DomainValidator; use Utopia\Validator\Text; use Utopia\Validator\WhiteList; -use Utopia\Validator\Range; use Utopia\Validator\URL; use Utopia\Config\Config; use Utopia\Domains\Domain; @@ -19,7 +19,6 @@ use Appwrite\Database\Document; use Appwrite\Database\Validator\UID; use Appwrite\OpenSSL\OpenSSL; use Appwrite\Network\Validator\CNAME; -use Appwrite\Utopia\Validator\Boolean; use Cron\CronExpression; include_once __DIR__ . '/../shared/api.php'; diff --git a/public/index.php b/public/index.php index f6cd63710c..a3f608a7a5 100644 --- a/public/index.php +++ b/public/index.php @@ -11,9 +11,9 @@ error_reporting(0); ini_set('display_errors', 0); -// ini_set('display_errors', 1); -// ini_set('display_startup_errors', 1); -// error_reporting(E_ALL); +ini_set('display_errors', 1); +ini_set('display_startup_errors', 1); +error_reporting(E_ALL); $path = (isset($_GET['q'])) ? explode('/', $_GET['q']) : []; $domain = (isset($_SERVER['HTTP_HOST'])) ? $_SERVER['HTTP_HOST'] : ''; From 1eb6f43ec90eef1ac7719e522477bb6fb454a48d Mon Sep 17 00:00:00 2001 From: Eldad Fux Date: Sun, 21 Jun 2020 15:18:53 +0300 Subject: [PATCH 06/10] Fixed debugging --- public/index.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/public/index.php b/public/index.php index a3f608a7a5..f6cd63710c 100644 --- a/public/index.php +++ b/public/index.php @@ -11,9 +11,9 @@ error_reporting(0); ini_set('display_errors', 0); -ini_set('display_errors', 1); -ini_set('display_startup_errors', 1); -error_reporting(E_ALL); +// ini_set('display_errors', 1); +// ini_set('display_startup_errors', 1); +// error_reporting(E_ALL); $path = (isset($_GET['q'])) ? explode('/', $_GET['q']) : []; $domain = (isset($_SERVER['HTTP_HOST'])) ? $_SERVER['HTTP_HOST'] : ''; From bd073da05e816a18adfaece67f2f7566a3bf14c0 Mon Sep 17 00:00:00 2001 From: Eldad Fux Date: Sun, 21 Jun 2020 15:23:50 +0300 Subject: [PATCH 07/10] Fixed tests --- tests/e2e/Services/Database/DatabaseBase.php | 35 -------------------- 1 file changed, 35 deletions(-) diff --git a/tests/e2e/Services/Database/DatabaseBase.php b/tests/e2e/Services/Database/DatabaseBase.php index 60dc1f81cc..7e68940104 100644 --- a/tests/e2e/Services/Database/DatabaseBase.php +++ b/tests/e2e/Services/Database/DatabaseBase.php @@ -317,41 +317,6 @@ trait DatabaseBase return []; } - /** - * @depends testCreateDocument - */ - public function testListDocumentsFirstAndLast(array $data):array - { - $documents = $this->client->call(Client::METHOD_GET, '/database/collections/' . $data['moviesId'] . '/documents', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ - 'limit' => 1, - 'orderField' => 'releaseYear', - 'orderType' => 'ASC', - 'orderCast' => 'int', - 'first' => true, - ]); - - $this->assertEquals(1944, $documents['body']['releaseYear']); - - $documents = $this->client->call(Client::METHOD_GET, '/database/collections/' . $data['moviesId'] . '/documents', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ - 'limit' => 2, - 'offset' => 1, - 'orderField' => 'releaseYear', - 'orderType' => 'ASC', - 'orderCast' => 'int', - 'last' => true, - ]); - - $this->assertEquals(2019, $documents['body']['releaseYear']); - - return []; - } - /** * @depends testCreateDocument */ From 7c2969b967c6f107a3970e56baf7d33eed0236d2 Mon Sep 17 00:00:00 2001 From: Eldad Fux Date: Fri, 26 Jun 2020 17:41:13 +0300 Subject: [PATCH 08/10] Removed first and last from internal functions --- app/controllers/api/account.php | 24 ++++++++-------------- app/controllers/api/teams.php | 6 ++---- app/controllers/api/users.php | 3 +-- app/workers/certificates.php | 3 +-- src/Appwrite/Database/Database.php | 32 ++++++++++++++++++++---------- 5 files changed, 34 insertions(+), 34 deletions(-) diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php index a7c1c2c534..10665bf740 100644 --- a/app/controllers/api/account.php +++ b/app/controllers/api/account.php @@ -80,9 +80,8 @@ $utopia->post('/v1/account') } } - $profile = $projectDB->getCollection([ // Get user by email address + $profile = $projectDB->getCollectionFirst([ // Get user by email address 'limit' => 1, - 'first' => true, 'filters' => [ '$collection='.Database::SYSTEM_COLLECTION_USERS, 'email='.$email, @@ -163,9 +162,8 @@ $utopia->post('/v1/account/sessions') ->action( function ($email, $password) use ($response, $request, $projectDB, $audit, $webhook) { $protocol = Config::getParam('protocol'); - $profile = $projectDB->getCollection([ // Get user by email address + $profile = $projectDB->getCollectionFirst([ // Get user by email address 'limit' => 1, - 'first' => true, 'filters' => [ '$collection='.Database::SYSTEM_COLLECTION_USERS, 'email='.$email, @@ -414,9 +412,8 @@ $utopia->get('/v1/account/sessions/oauth2/:provider/redirect') $projectDB->deleteDocument($current); //throw new Exception('User already logged in', 401); } - $user = (empty($user->getId())) ? $projectDB->getCollection([ // Get user by provider id + $user = (empty($user->getId())) ? $projectDB->getCollectionFirst([ // Get user by provider id 'limit' => 1, - 'first' => true, 'filters' => [ '$collection='.Database::SYSTEM_COLLECTION_USERS, 'oauth2'.\ucfirst($provider).'='.$oauth2ID, @@ -427,9 +424,8 @@ $utopia->get('/v1/account/sessions/oauth2/:provider/redirect') $name = $oauth2->getUserName($accessToken); $email = $oauth2->getUserEmail($accessToken); - $user = $projectDB->getCollection([ // Get user by provider email address + $user = $projectDB->getCollectionFirst([ // Get user by provider email address 'limit' => 1, - 'first' => true, 'filters' => [ '$collection='.Database::SYSTEM_COLLECTION_USERS, 'email='.$email, @@ -797,9 +793,8 @@ $utopia->patch('/v1/account/email') throw new Exception('Invalid credentials', 401); } - $profile = $projectDB->getCollection([ // Get user by email address + $profile = $projectDB->getCollectionFirst([ // Get user by email address 'limit' => 1, - 'first' => true, 'filters' => [ '$collection='.Database::SYSTEM_COLLECTION_USERS, 'email='.$email, @@ -1056,9 +1051,8 @@ $utopia->post('/v1/account/recovery') ->param('url', '', function () use ($clients) { return new Host($clients); }, 'URL to redirect the user back to your app from the recovery email. Only URLs from hostnames in your project platform list are allowed. This requirement helps to prevent an [open redirect](https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html) attack against your project API.') ->action( function ($email, $url) use ($request, $response, $projectDB, $mail, $audit, $project) { - $profile = $projectDB->getCollection([ // Get user by email address + $profile = $projectDB->getCollectionFirst([ // Get user by email address 'limit' => 1, - 'first' => true, 'filters' => [ '$collection='.Database::SYSTEM_COLLECTION_USERS, 'email='.$email, @@ -1161,9 +1155,8 @@ $utopia->put('/v1/account/recovery') throw new Exception('Passwords must match', 400); } - $profile = $projectDB->getCollection([ // Get user by email address + $profile = $projectDB->getCollectionFirst([ // Get user by email address 'limit' => 1, - 'first' => true, 'filters' => [ '$collection='.Database::SYSTEM_COLLECTION_USERS, '$id='.$userId, @@ -1311,9 +1304,8 @@ $utopia->put('/v1/account/verification') ->param('secret', '', function () { return new Text(256); }, 'Valid verification token.') ->action( function ($userId, $secret) use ($response, $user, $projectDB, $audit) { - $profile = $projectDB->getCollection([ // Get user by email address + $profile = $projectDB->getCollectionFirst([ // Get user by email address 'limit' => 1, - 'first' => true, 'filters' => [ '$collection='.Database::SYSTEM_COLLECTION_USERS, '$id='.$userId, diff --git a/app/controllers/api/teams.php b/app/controllers/api/teams.php index b8e0bf1194..95dad48562 100644 --- a/app/controllers/api/teams.php +++ b/app/controllers/api/teams.php @@ -232,9 +232,8 @@ $utopia->post('/v1/teams/:teamId/memberships') ], ]); - $invitee = $projectDB->getCollection([ // Get user by email address + $invitee = $projectDB->getCollectionFirst([ // Get user by email address 'limit' => 1, - 'first' => true, 'filters' => [ '$collection='.Database::SYSTEM_COLLECTION_USERS, 'email='.$email, @@ -480,9 +479,8 @@ $utopia->patch('/v1/teams/:teamId/memberships/:inviteId/status') } if (empty($user->getId())) { - $user = $projectDB->getCollection([ // Get user + $user = $projectDB->getCollectionFirst([ // Get user 'limit' => 1, - 'first' => true, 'filters' => [ '$collection='.Database::SYSTEM_COLLECTION_USERS, '$id='.$userId, diff --git a/app/controllers/api/users.php b/app/controllers/api/users.php index d032cef947..1324c559ac 100644 --- a/app/controllers/api/users.php +++ b/app/controllers/api/users.php @@ -35,9 +35,8 @@ $utopia->post('/v1/users') ->param('name', '', function () { return new Text(100); }, 'User name.', true) ->action( function ($email, $password, $name) use ($response, $projectDB) { - $profile = $projectDB->getCollection([ // Get user by email address + $profile = $projectDB->getCollectionFirst([ // Get user by email address 'limit' => 1, - 'first' => true, 'filters' => [ '$collection='.Database::SYSTEM_COLLECTION_USERS, 'email='.$email, diff --git a/app/workers/certificates.php b/app/workers/certificates.php index b04c7409c0..22c3a14e63 100644 --- a/app/workers/certificates.php +++ b/app/workers/certificates.php @@ -77,7 +77,7 @@ class CertificatesV1 } } - $certificate = $consoleDB->getCollection([ + $certificate = $consoleDB->getCollectionFirst([ 'limit' => 1, 'offset' => 0, 'orderField' => 'id', @@ -87,7 +87,6 @@ class CertificatesV1 '$collection='.Database::SYSTEM_COLLECTION_CERTIFICATES, 'domain='.$domain->get(), ], - 'first' => true, ]); // $condition = ($certificate diff --git a/src/Appwrite/Database/Database.php b/src/Appwrite/Database/Database.php index e75eb01b51..45b61cd089 100644 --- a/src/Appwrite/Database/Database.php +++ b/src/Appwrite/Database/Database.php @@ -130,8 +130,6 @@ class Database 'orderField' => '$id', 'orderType' => 'ASC', 'orderCast' => 'int', - 'first' => false, - 'last' => false, 'filters' => [], ], $options); @@ -141,17 +139,31 @@ class Database $node = new Document($node); } - if ($options['first']) { - $results = \reset($results); - } - - if ($options['last']) { - $results = \end($results); - } - return $results; } + /** + * @param array $options + * + * @return Document + */ + public function getCollectionFirst(array $options) + { + $results = $this->getCollection($options); + return \reset($results); + } + + /** + * @param array $options + * + * @return Document + */ + public function getCollectionLast(array $options) + { + $results = $this->getCollection($options); + return \end($results); + } + /** * @param int $id * @param bool $mock is mocked data allowed? From b2b716048ec72a8dd5ce06124c170fcc1e6a09db Mon Sep 17 00:00:00 2001 From: Eldad Fux Date: Sun, 28 Jun 2020 21:35:12 +0300 Subject: [PATCH 09/10] Updated deps --- composer.json | 4 ---- composer.lock | 21 --------------------- 2 files changed, 25 deletions(-) diff --git a/composer.json b/composer.json index dbb78bfb17..78b0fd76cc 100644 --- a/composer.json +++ b/composer.json @@ -32,11 +32,7 @@ "appwrite/php-clamav": "1.0.*", -<<<<<<< HEAD - "utopia-php/framework": "0.3.7", -======= "utopia-php/framework": "0.4.0", ->>>>>>> 17b9dc76a60403ef4e680ee92f3c845a5762effd "utopia-php/abuse": "0.2.*", "utopia-php/audit": "0.3.*", "utopia-php/cache": "0.2.*", diff --git a/composer.lock b/composer.lock index 957ddf5d19..a7d030f06a 100644 --- a/composer.lock +++ b/composer.lock @@ -4,11 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], -<<<<<<< HEAD - "content-hash": "1df9fdb337c6030db4bb5f0e9868f9c3", -======= "content-hash": "7f6cbe77fe2e0f8bdff33c37a4d9ca11", ->>>>>>> 17b9dc76a60403ef4e680ee92f3c845a5762effd "packages": [ { "name": "appwrite/php-clamav", @@ -1600,18 +1596,6 @@ }, { "name": "utopia-php/framework", -<<<<<<< HEAD - "version": "0.3.7", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/framework.git", - "reference": "23156b3d604fd9586f2e8c6c449b2fc6a82c10bc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/framework/zipball/23156b3d604fd9586f2e8c6c449b2fc6a82c10bc", - "reference": "23156b3d604fd9586f2e8c6c449b2fc6a82c10bc", -======= "version": "0.4.0", "source": { "type": "git", @@ -1622,7 +1606,6 @@ "type": "zip", "url": "https://api.github.com/repos/utopia-php/framework/zipball/30aeb2aeecf8ea2ab83242efad0f5f9fab8d4be5", "reference": "30aeb2aeecf8ea2ab83242efad0f5f9fab8d4be5", ->>>>>>> 17b9dc76a60403ef4e680ee92f3c845a5762effd "shasum": "" }, "require": { @@ -1653,11 +1636,7 @@ "php", "upf" ], -<<<<<<< HEAD - "time": "2020-06-21T11:29:58+00:00" -======= "time": "2020-06-25T18:21:48+00:00" ->>>>>>> 17b9dc76a60403ef4e680ee92f3c845a5762effd }, { "name": "utopia-php/locale", From 8ee9943468c93b2030e4c89d9ddd83b696d52735 Mon Sep 17 00:00:00 2001 From: Eldad Fux Date: Sun, 28 Jun 2020 21:38:16 +0300 Subject: [PATCH 10/10] Updated changelog --- CHANGES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.md b/CHANGES.md index ce47a26783..49b0f5d1fc 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -19,6 +19,7 @@ - Added container names to docker-compose.yml (@drandell) - Upgraded ClamAV container image to version 1.0.9 - Optimised function execution by using fully-qualified function calls +- Added support for boolean 'true' and 'false' in query strings alongside 1 and 0 ## Bug Fixes