Merge branch 'response-refactor' of github.com:appwrite/appwrite into graphql

This commit is contained in:
Eldad Fux
2020-06-25 23:12:11 +03:00
57 changed files with 768 additions and 395 deletions
+10
View File
@@ -171,6 +171,16 @@ Improve PHP exeution time by using [fully-qualified function calls](https://veew
php-cs-fixer fix src/ --rules=native_function_invocation --allow-risky=yes
```
Coding Standards:
```bash
php-cs-fixer fix app/controllers --rules='{"braces": {"allow_single_line_closure": true}}'
```
```bash
php-cs-fixer fix src --rules='{"braces": {"allow_single_line_closure": true}}'
```
## Tutorials
From time to time, our team will add tutorials that will help contributors find their way in the Appwrite source code. Below is a list of currently available tutorials:
+5 -8
View File
@@ -3,7 +3,7 @@
// Init
require_once __DIR__.'/init.php';
global $utopia, $request, $response, $register, $consoleDB, $project, $service;
global $utopia, $request, $response, $register, $consoleDB, $project;
use Utopia\App;
use Utopia\Request;
@@ -425,14 +425,11 @@ $utopia->get('/.well-known/acme-challenge')
}
);
$name = APP_NAME;
include_once __DIR__ . '/controllers/shared/api.php';
include_once __DIR__ . '/controllers/shared/web.php';
if (\array_key_exists($service, $services)) { /** @noinspection PhpIncludeInspection */
include_once $services[$service]['controller'];
$name = APP_NAME.' '.\ucfirst($services[$service]['name']);
} else {
/** @noinspection PhpIncludeInspection */
include_once $services['/']['controller'];
foreach($services as $key => $service) {
include_once $services[$key]['controller'];
}
$utopia->run($request, $response);
+28 -9
View File
@@ -29,8 +29,6 @@ use DeviceDetector\DeviceDetector;
use GeoIp2\Database\Reader;
use Utopia\Validator\ArrayList;
include_once __DIR__ . '/../shared/api.php';
$oauthDefaultSuccess = $request->getServer('_APP_HOME').'/auth/oauth2/success';
$oauthDefaultFailure = $request->getServer('_APP_HOME').'/auth/oauth2/failure';
@@ -45,10 +43,11 @@ $utopia->init(function() use (&$oauth2Keys) {
$oauth2Keys[] = 'oauth2'.\ucfirst($key);
$oauth2Keys[] = 'oauth2'.\ucfirst($key).'AccessToken';
}
});
}, 'account');
$utopia->post('/v1/account')
->desc('Create Account')
->groups(['api', 'account'])
->label('webhook', 'account.create')
->label('scope', 'public')
->label('sdk.platform', [APP_PLATFORM_CLIENT])
@@ -140,6 +139,7 @@ $utopia->post('/v1/account')
$utopia->post('/v1/account/sessions')
->desc('Create Account Session')
->groups(['api', 'account'])
->label('webhook', 'account.sessions.create')
->label('scope', 'public')
->label('sdk.platform', [APP_PLATFORM_CLIENT])
@@ -213,7 +213,7 @@ $utopia->post('/v1/account/sessions')
->setParam('resource', 'users/'.$profile->getId())
;
if(!Config::getParam('domainVerification')) {
if (!Config::getParam('domainVerification')) {
$response
->addHeader('X-Fallback-Cookies', \json_encode([Auth::$cookieName => Auth::encodeSession($profile->getId(), $secret)]))
;
@@ -231,6 +231,7 @@ $utopia->post('/v1/account/sessions')
$utopia->get('/v1/account/sessions/oauth2/:provider')
->desc('Create Account Session with OAuth2')
->groups(['api', 'account'])
->label('error', __DIR__.'/../../views/general/error.phtml')
->label('scope', 'public')
->label('sdk.platform', [APP_PLATFORM_CLIENT])
@@ -281,6 +282,7 @@ $utopia->get('/v1/account/sessions/oauth2/:provider')
$utopia->get('/v1/account/sessions/oauth2/callback/:provider/:projectId')
->desc('OAuth2 Callback')
->groups(['api', 'account'])
->label('error', __DIR__.'/../../views/general/error.phtml')
->label('scope', 'public')
->label('docs', false)
@@ -303,6 +305,7 @@ $utopia->get('/v1/account/sessions/oauth2/callback/:provider/:projectId')
$utopia->post('/v1/account/sessions/oauth2/callback/:provider/:projectId')
->desc('OAuth2 Callback')
->groups(['api', 'account'])
->label('error', __DIR__.'/../../views/general/error.phtml')
->label('scope', 'public')
->label('origin', '*')
@@ -326,6 +329,7 @@ $utopia->post('/v1/account/sessions/oauth2/callback/:provider/:projectId')
$utopia->get('/v1/account/sessions/oauth2/:provider/redirect')
->desc('OAuth2 Redirect')
->groups(['api', 'account'])
->label('error', __DIR__.'/../../views/general/error.phtml')
->label('webhook', 'account.sessions.create')
->label('scope', 'public')
@@ -491,13 +495,13 @@ $utopia->get('/v1/account/sessions/oauth2/:provider/redirect')
->setParam('data', ['provider' => $provider])
;
if(!Config::getParam('domainVerification')) {
if (!Config::getParam('domainVerification')) {
$response
->addHeader('X-Fallback-Cookies', \json_encode([Auth::$cookieName => Auth::encodeSession($user->getId(), $secret)]))
;
}
if($state['success'] === $oauthDefaultSuccess) { // Add keys for non-web platforms
if ($state['success'] === $oauthDefaultSuccess) { // Add keys for non-web platforms
$state['success'] = URLParser::parse($state['success']);
$query = URLParser::parseQuery($state['success']['query']);
$query['project'] = $project->getId();
@@ -520,6 +524,7 @@ $utopia->get('/v1/account/sessions/oauth2/:provider/redirect')
$utopia->get('/v1/account')
->desc('Get Account')
->groups(['api', 'account'])
->label('scope', 'account')
->label('sdk.platform', [APP_PLATFORM_CLIENT])
->label('sdk.namespace', 'account')
@@ -534,6 +539,7 @@ $utopia->get('/v1/account')
$utopia->get('/v1/account/prefs')
->desc('Get Account Preferences')
->groups(['api', 'account'])
->label('scope', 'account')
->label('sdk.platform', [APP_PLATFORM_CLIENT])
->label('sdk.namespace', 'account')
@@ -556,6 +562,7 @@ $utopia->get('/v1/account/prefs')
$utopia->get('/v1/account/sessions')
->desc('Get Account Sessions')
->groups(['api', 'account'])
->label('scope', 'account')
->label('sdk.platform', [APP_PLATFORM_CLIENT])
->label('sdk.namespace', 'account')
@@ -614,6 +621,7 @@ $utopia->get('/v1/account/sessions')
$utopia->get('/v1/account/logs')
->desc('Get Account Logs')
->groups(['api', 'account'])
->label('scope', 'account')
->label('sdk.platform', [APP_PLATFORM_CLIENT])
->label('sdk.namespace', 'account')
@@ -686,6 +694,7 @@ $utopia->get('/v1/account/logs')
$utopia->patch('/v1/account/name')
->desc('Update Account Name')
->groups(['api', 'account'])
->label('webhook', 'account.update.name')
->label('scope', 'account')
->label('sdk.platform', [APP_PLATFORM_CLIENT])
@@ -715,6 +724,7 @@ $utopia->patch('/v1/account/name')
$utopia->patch('/v1/account/password')
->desc('Update Account Password')
->groups(['api', 'account'])
->label('webhook', 'account.update.password')
->label('scope', 'account')
->label('sdk.platform', [APP_PLATFORM_CLIENT])
@@ -749,6 +759,7 @@ $utopia->patch('/v1/account/password')
$utopia->patch('/v1/account/email')
->desc('Update Account Email')
->groups(['api', 'account'])
->label('webhook', 'account.update.email')
->label('scope', 'account')
->label('sdk.platform', [APP_PLATFORM_CLIENT])
@@ -799,6 +810,7 @@ $utopia->patch('/v1/account/email')
$utopia->patch('/v1/account/prefs')
->desc('Update Account Preferences')
->groups(['api', 'account'])
->label('webhook', 'account.update.prefs')
->label('scope', 'account')
->label('sdk.platform', [APP_PLATFORM_CLIENT])
@@ -839,6 +851,7 @@ $utopia->patch('/v1/account/prefs')
$utopia->delete('/v1/account')
->desc('Delete Account')
->groups(['api', 'account'])
->label('webhook', 'account.delete')
->label('scope', 'account')
->label('sdk.platform', [APP_PLATFORM_CLIENT])
@@ -878,7 +891,7 @@ $utopia->delete('/v1/account')
])
;
if(!Config::getParam('domainVerification')) {
if (!Config::getParam('domainVerification')) {
$response
->addHeader('X-Fallback-Cookies', \json_encode([]))
;
@@ -894,6 +907,7 @@ $utopia->delete('/v1/account')
$utopia->delete('/v1/account/sessions/:sessionId')
->desc('Delete Account Session')
->groups(['api', 'account'])
->label('scope', 'account')
->label('webhook', 'account.sessions.delete')
->label('sdk.platform', [APP_PLATFORM_CLIENT])
@@ -930,7 +944,7 @@ $utopia->delete('/v1/account/sessions/:sessionId')
])
;
if(!Config::getParam('domainVerification')) {
if (!Config::getParam('domainVerification')) {
$response
->addHeader('X-Fallback-Cookies', \json_encode([]))
;
@@ -953,6 +967,7 @@ $utopia->delete('/v1/account/sessions/:sessionId')
$utopia->delete('/v1/account/sessions')
->desc('Delete All Account Sessions')
->groups(['api', 'account'])
->label('scope', 'account')
->label('webhook', 'account.sessions.delete')
->label('sdk.platform', [APP_PLATFORM_CLIENT])
@@ -983,7 +998,7 @@ $utopia->delete('/v1/account/sessions')
])
;
if(!Config::getParam('domainVerification')) {
if (!Config::getParam('domainVerification')) {
$response
->addHeader('X-Fallback-Cookies', \json_encode([]))
;
@@ -1003,6 +1018,7 @@ $utopia->delete('/v1/account/sessions')
$utopia->post('/v1/account/recovery')
->desc('Create Password Recovery')
->groups(['api', 'account'])
->label('scope', 'public')
->label('sdk.platform', [APP_PLATFORM_CLIENT])
->label('sdk.namespace', 'account')
@@ -1102,6 +1118,7 @@ $utopia->post('/v1/account/recovery')
$utopia->put('/v1/account/recovery')
->desc('Complete Password Recovery')
->groups(['api', 'account'])
->label('scope', 'public')
->label('sdk.platform', [APP_PLATFORM_CLIENT])
->label('sdk.namespace', 'account')
@@ -1172,6 +1189,7 @@ $utopia->put('/v1/account/recovery')
$utopia->post('/v1/account/verification')
->desc('Create Email Verification')
->groups(['api', 'account'])
->label('scope', 'account')
->label('sdk.platform', [APP_PLATFORM_CLIENT])
->label('sdk.namespace', 'account')
@@ -1258,6 +1276,7 @@ $utopia->post('/v1/account/verification')
$utopia->put('/v1/account/verification')
->desc('Complete Email Verification')
->groups(['api', 'account'])
->label('scope', 'public')
->label('sdk.platform', [APP_PLATFORM_CLIENT])
->label('sdk.namespace', 'account')
+15 -13
View File
@@ -18,15 +18,13 @@ use BaconQrCode\Writer;
use Utopia\Config\Config;
use Utopia\Validator\HexColor;
include_once __DIR__ . '/../shared/api.php';
$types = [
'browsers' => include __DIR__.'/../../config/avatars/browsers.php',
'credit-cards' => include __DIR__.'/../../config/avatars/credit-cards.php',
'flags' => include __DIR__.'/../../config/avatars/flags.php',
];
$avatarCallback = function ($type, $code, $width, $height, $quality) use ($types, $response, $request) {
$avatarCallback = function ($type, $code, $width, $height, $quality) use ($types, $response) {
$code = \strtolower($code);
$type = \strtolower($type);
@@ -86,12 +84,11 @@ $avatarCallback = function ($type, $code, $width, $height, $quality) use ($types
echo $data;
unset($resize);
exit(0);
};
$utopia->get('/v1/avatars/credit-cards/:code')
->desc('Get Credit Card Icon')
->groups(['api', 'avatars'])
->param('code', '', function () use ($types) { return new WhiteList(\array_keys($types['credit-cards'])); }, 'Credit Card Code. Possible values: '.\implode(', ', \array_keys($types['credit-cards'])).'.')
->param('width', 100, function () { return new Range(0, 2000); }, 'Image width. Pass an integer between 0 to 2000. Defaults to 100.', true)
->param('height', 100, function () { return new Range(0, 2000); }, 'Image height. Pass an integer between 0 to 2000. Defaults to 100.', true)
@@ -102,11 +99,13 @@ $utopia->get('/v1/avatars/credit-cards/:code')
->label('sdk.method', 'getCreditCard')
->label('sdk.methodType', 'location')
->label('sdk.description', '/docs/references/avatars/get-credit-card.md')
->action(function ($code, $width, $height, $quality) use ($avatarCallback) { return $avatarCallback('credit-cards', $code, $width, $height, $quality);
->action(function ($code, $width, $height, $quality) use ($avatarCallback) {
return $avatarCallback('credit-cards', $code, $width, $height, $quality);
});
$utopia->get('/v1/avatars/browsers/:code')
->desc('Get Browser Icon')
->groups(['api', 'avatars'])
->param('code', '', function () use ($types) { return new WhiteList(\array_keys($types['browsers'])); }, 'Browser Code.')
->param('width', 100, function () { return new Range(0, 2000); }, 'Image width. Pass an integer between 0 to 2000. Defaults to 100.', true)
->param('height', 100, function () { return new Range(0, 2000); }, 'Image height. Pass an integer between 0 to 2000. Defaults to 100.', true)
@@ -117,11 +116,13 @@ $utopia->get('/v1/avatars/browsers/:code')
->label('sdk.method', 'getBrowser')
->label('sdk.methodType', 'location')
->label('sdk.description', '/docs/references/avatars/get-browser.md')
->action(function ($code, $width, $height, $quality) use ($avatarCallback) { return $avatarCallback('browsers', $code, $width, $height, $quality);
->action(function ($code, $width, $height, $quality) use ($avatarCallback) {
return $avatarCallback('browsers', $code, $width, $height, $quality);
});
$utopia->get('/v1/avatars/flags/:code')
->desc('Get Country Flag')
->groups(['api', 'avatars'])
->param('code', '', function () use ($types) { return new WhiteList(\array_keys($types['flags'])); }, 'Country Code. ISO Alpha-2 country code format.')
->param('width', 100, function () { return new Range(0, 2000); }, 'Image width. Pass an integer between 0 to 2000. Defaults to 100.', true)
->param('height', 100, function () { return new Range(0, 2000); }, 'Image height. Pass an integer between 0 to 2000. Defaults to 100.', true)
@@ -132,11 +133,13 @@ $utopia->get('/v1/avatars/flags/:code')
->label('sdk.method', 'getFlag')
->label('sdk.methodType', 'location')
->label('sdk.description', '/docs/references/avatars/get-flag.md')
->action(function ($code, $width, $height, $quality) use ($avatarCallback) { return $avatarCallback('flags', $code, $width, $height, $quality);
->action(function ($code, $width, $height, $quality) use ($avatarCallback) {
return $avatarCallback('flags', $code, $width, $height, $quality);
});
$utopia->get('/v1/avatars/image')
->desc('Get Image from URL')
->groups(['api', 'avatars'])
->param('url', '', function () { return new URL(); }, 'Image URL which you want to crop.')
->param('width', 400, function () { return new Range(0, 2000); }, 'Resize preview image width, Pass an integer between 0 to 2000.', true)
->param('height', 400, function () { return new Range(0, 2000); }, 'Resize preview image height, Pass an integer between 0 to 2000.', true)
@@ -199,13 +202,12 @@ $utopia->get('/v1/avatars/image')
echo $data;
unset($resize);
exit(0);
}
);
$utopia->get('/v1/avatars/favicon')
->desc('Get Favicon')
->groups(['api', 'avatars'])
->param('url', '', function () { return new URL(); }, 'Website URL which you want to fetch the favicon from.')
->label('scope', 'avatars.read')
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
@@ -353,13 +355,12 @@ $utopia->get('/v1/avatars/favicon')
echo $data;
unset($resize);
exit(0);
}
);
$utopia->get('/v1/avatars/qr')
->desc('Get QR Code')
->groups(['api', 'avatars'])
->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)
@@ -393,6 +394,7 @@ $utopia->get('/v1/avatars/qr')
$utopia->get('/v1/avatars/initials')
->desc('Get User Initials')
->groups(['api', 'avatars'])
->param('name', '', function () { return new Text(512); }, 'Full Name. When empty, current user name or email will be used.', true)
->param('width', 500, function () { return new Range(0, 2000); }, 'Image width. Pass an integer between 0 to 2000. Defaults to 100.', true)
->param('height', 500, function () { return new Range(0, 2000); }, 'Image height. Pass an integer between 0 to 2000. Defaults to 100.', true)
@@ -430,7 +432,7 @@ $utopia->get('/v1/avatars/initials')
$initials .= (isset($w[0])) ? $w[0] : '';
$code += (isset($w[0])) ? \ord($w[0]) : 0;
if($key == 1) {
if ($key == 1) {
break;
}
}
+27 -20
View File
@@ -25,12 +25,9 @@ use Appwrite\Database\Exception\Structure as StructureException;
use DeviceDetector\DeviceDetector;
use GeoIp2\Database\Reader;
include_once __DIR__ . '/../shared/api.php';
$isDev = (App::MODE_TYPE_PRODUCTION !== $utopia->getMode());
$utopia->post('/v1/database/collections')
->desc('Create Collection')
->groups(['api', 'database'])
->label('webhook', 'database.collections.create')
->label('scope', 'collections.write')
->label('sdk.namespace', 'database')
@@ -104,6 +101,7 @@ $utopia->post('/v1/database/collections')
$utopia->get('/v1/database/collections')
->desc('List Collections')
->groups(['api', 'database'])
->label('scope', 'collections.read')
->label('sdk.namespace', 'database')
->label('sdk.platform', [APP_PLATFORM_SERVER])
@@ -133,6 +131,7 @@ $utopia->get('/v1/database/collections')
$utopia->get('/v1/database/collections/:collectionId')
->desc('Get Collection')
->groups(['api', 'database'])
->label('scope', 'collections.read')
->label('sdk.namespace', 'database')
->label('sdk.platform', [APP_PLATFORM_SERVER])
@@ -153,6 +152,7 @@ $utopia->get('/v1/database/collections/:collectionId')
// $utopia->get('/v1/database/collections/:collectionId/logs')
// ->desc('Get Collection Logs')
// ->groups(['api', 'database'])
// ->label('scope', 'collections.read')
// ->label('sdk.platform', [APP_PLATFORM_SERVER])
// ->label('sdk.namespace', 'database')
@@ -161,7 +161,7 @@ $utopia->get('/v1/database/collections/:collectionId')
// ->param('collectionId', '', function () { return new UID(); }, 'Collection unique ID.')
// ->action(
// function ($collectionId) use ($response, $register, $projectDB, $project) {
// $collection = $projectDB->getDocument($collectionId);
// $collection = $projectDB->getDocument($collectionId, false);
// if (empty($collection->getId()) || Database::SYSTEM_COLLECTION_COLLECTIONS != $collection->getCollection()) {
// throw new Exception('Collection not found', 404);
@@ -217,6 +217,7 @@ $utopia->get('/v1/database/collections/:collectionId')
$utopia->put('/v1/database/collections/:collectionId')
->desc('Update Collection')
->groups(['api', 'database'])
->label('scope', 'collections.write')
->label('webhook', 'database.collections.update')
->label('sdk.namespace', 'database')
@@ -289,6 +290,7 @@ $utopia->put('/v1/database/collections/:collectionId')
$utopia->delete('/v1/database/collections/:collectionId')
->desc('Delete Collection')
->groups(['api', 'database'])
->label('scope', 'collections.write')
->label('webhook', 'database.collections.delete')
->label('sdk.namespace', 'database')
@@ -326,6 +328,7 @@ $utopia->delete('/v1/database/collections/:collectionId')
$utopia->post('/v1/database/collections/:collectionId/documents')
->desc('Create Document')
->groups(['api', 'database'])
->label('webhook', 'database.documents.create')
->label('scope', 'documents.write')
->label('sdk.namespace', 'database')
@@ -351,7 +354,7 @@ $utopia->post('/v1/database/collections/:collectionId/documents')
throw new Exception('$id is not allowed for creating new documents, try update instead', 400);
}
$collection = $projectDB->getDocument($collectionId/*, $isDev*/);
$collection = $projectDB->getDocument($collectionId, false);
if (\is_null($collection->getId()) || Database::SYSTEM_COLLECTION_COLLECTIONS != $collection->getCollection()) {
throw new Exception('Collection not found', 404);
@@ -366,7 +369,7 @@ $utopia->post('/v1/database/collections/:collectionId/documents')
// Read parent document + validate not 404 + validate read / write permission like patch method
// Add payload to parent document property
if ((!empty($parentDocument)) && (!empty($parentProperty))) {
$parentDocument = $projectDB->getDocument($parentDocument);
$parentDocument = $projectDB->getDocument($parentDocument, false);
if (empty($parentDocument->getArrayCopy())) { // Check empty
throw new Exception('No parent document found', 404);
@@ -406,7 +409,7 @@ $utopia->post('/v1/database/collections/:collectionId/documents')
$key = (isset($rule['key'])) ? $rule['key'] : '';
$default = (isset($rule['default'])) ? $rule['default'] : null;
if(!isset($data[$key])) {
if (!isset($data[$key])) {
$data[$key] = $default;
}
}
@@ -445,6 +448,7 @@ $utopia->post('/v1/database/collections/:collectionId/documents')
$utopia->get('/v1/database/collections/:collectionId/documents')
->desc('List Documents')
->groups(['api', 'database'])
->label('scope', 'documents.read')
->label('sdk.namespace', 'database')
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
@@ -461,8 +465,8 @@ $utopia->get('/v1/database/collections/:collectionId/documents')
->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) {
$collection = $projectDB->getDocument($collectionId, $isDev);
function ($collectionId, $filters, $offset, $limit, $orderField, $orderType, $orderCast, $search, $first, $last) use ($response, $projectDB, $utopia) {
$collection = $projectDB->getDocument($collectionId, false);
if (\is_null($collection->getId()) || Database::SYSTEM_COLLECTION_COLLECTIONS != $collection->getCollection()) {
throw new Exception('Collection not found', 404);
@@ -485,7 +489,7 @@ $utopia->get('/v1/database/collections/:collectionId/documents')
if ($first || $last) {
$response->json((!empty($list) ? $list->getArrayCopy() : []));
} else {
if ($isDev) {
if ($utopia->isDevelopment()) {
$collection
->setAttribute('debug', $projectDB->getDebug())
->setAttribute('limit', $limit)
@@ -512,6 +516,7 @@ $utopia->get('/v1/database/collections/:collectionId/documents')
$utopia->get('/v1/database/collections/:collectionId/documents/:documentId')
->desc('Get Document')
->groups(['api', 'database'])
->label('scope', 'documents.read')
->label('sdk.namespace', 'database')
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
@@ -520,9 +525,9 @@ $utopia->get('/v1/database/collections/:collectionId/documents/:documentId')
->param('collectionId', null, function () { return new UID(); }, 'Collection unique ID. You can create a new collection with validation rules using the Database service [server integration](/docs/server/database#createCollection).')
->param('documentId', null, function () { return new UID(); }, 'Document unique ID.')
->action(
function ($collectionId, $documentId) use ($response, $request, $projectDB, $isDev) {
$document = $projectDB->getDocument($documentId, $isDev);
$collection = $projectDB->getDocument($collectionId, $isDev);
function ($collectionId, $documentId) use ($response, $request, $projectDB) {
$document = $projectDB->getDocument($documentId, false);
$collection = $projectDB->getDocument($collectionId, false);
if (empty($document->getArrayCopy()) || $document->getCollection() != $collection->getId()) { // Check empty
throw new Exception('No document found', 404);
@@ -557,6 +562,7 @@ $utopia->get('/v1/database/collections/:collectionId/documents/:documentId')
$utopia->patch('/v1/database/collections/:collectionId/documents/:documentId')
->desc('Update Document')
->groups(['api', 'database'])
->label('webhook', 'database.documents.update')
->label('scope', 'documents.write')
->label('sdk.namespace', 'database')
@@ -569,9 +575,9 @@ $utopia->patch('/v1/database/collections/:collectionId/documents/:documentId')
->param('read', [], function () { return new ArrayList(new Text(64)); }, 'An array of strings with read permissions. By default no user is granted with any read permissions. [learn more about permissions](/docs/permissions) and get a full list of available permissions.')
->param('write', [], function () { return new ArrayList(new Text(64)); }, 'An array of strings with write permissions. By default no user is granted with any write permissions. [learn more about permissions](/docs/permissions) and get a full list of available permissions.')
->action(
function ($collectionId, $documentId, $data, $read, $write) use ($response, $projectDB, &$output, $webhook, $audit, $isDev) {
$collection = $projectDB->getDocument($collectionId/*, $isDev*/);
$document = $projectDB->getDocument($documentId, $isDev);
function ($collectionId, $documentId, $data, $read, $write) use ($response, $projectDB, $webhook, $audit) {
$collection = $projectDB->getDocument($collectionId, false);
$document = $projectDB->getDocument($documentId, false);
$data = (\is_string($data)) ? \json_decode($data, true) : $data; // Cast to JSON array
@@ -636,6 +642,7 @@ $utopia->patch('/v1/database/collections/:collectionId/documents/:documentId')
$utopia->delete('/v1/database/collections/:collectionId/documents/:documentId')
->desc('Delete Document')
->groups(['api', 'database'])
->label('scope', 'documents.write')
->label('webhook', 'database.documents.delete')
->label('sdk.namespace', 'database')
@@ -645,9 +652,9 @@ $utopia->delete('/v1/database/collections/:collectionId/documents/:documentId')
->param('collectionId', null, function () { return new UID(); }, 'Collection unique ID. You can create a new collection with validation rules using the Database service [server integration](/docs/server/database#createCollection).')
->param('documentId', null, function () { return new UID(); }, 'Document unique ID.')
->action(
function ($collectionId, $documentId) use ($response, $projectDB, $audit, $webhook, $isDev) {
$collection = $projectDB->getDocument($collectionId, $isDev);
$document = $projectDB->getDocument($documentId, $isDev);
function ($collectionId, $documentId) use ($response, $projectDB, $audit, $webhook) {
$collection = $projectDB->getDocument($collectionId, false);
$document = $projectDB->getDocument($documentId, false);
if (empty($document->getArrayCopy()) || $document->getCollection() != $collectionId) { // Check empty
throw new Exception('No document found', 404);
+1
View File
@@ -39,6 +39,7 @@ global $utopia, $request, $response;
$utopia->post('/v1/graphql')
->desc('GraphQL Endpoint')
->groups(['api', 'graphql'])
->label('scope', 'public')
->action(
function () use ($request, $response, $utopia) {
+15 -2
View File
@@ -9,6 +9,7 @@ use Appwrite\ClamAV\Network;
$utopia->get('/v1/health')
->desc('Get HTTP')
->groups(['api', 'health'])
->label('scope', 'health.read')
->label('sdk.platform', [APP_PLATFORM_SERVER])
->label('sdk.namespace', 'health')
@@ -22,6 +23,7 @@ $utopia->get('/v1/health')
$utopia->get('/v1/health/version')
->desc('Get Version')
->groups(['api', 'health'])
->label('scope', 'public')
->action(
function () use ($response) {
@@ -31,6 +33,7 @@ $utopia->get('/v1/health/version')
$utopia->get('/v1/health/db')
->desc('Get DB')
->groups(['api', 'health'])
->label('scope', 'health.read')
->label('sdk.platform', [APP_PLATFORM_SERVER])
->label('sdk.namespace', 'health')
@@ -46,6 +49,7 @@ $utopia->get('/v1/health/db')
$utopia->get('/v1/health/cache')
->desc('Get Cache')
->groups(['api', 'health'])
->label('scope', 'health.read')
->label('sdk.platform', [APP_PLATFORM_SERVER])
->label('sdk.namespace', 'health')
@@ -61,6 +65,7 @@ $utopia->get('/v1/health/cache')
$utopia->get('/v1/health/time')
->desc('Get Time')
->groups(['api', 'health'])
->label('scope', 'health.read')
->label('sdk.platform', [APP_PLATFORM_SERVER])
->label('sdk.namespace', 'health')
@@ -108,6 +113,7 @@ $utopia->get('/v1/health/time')
$utopia->get('/v1/health/queue/webhooks')
->desc('Get Webhooks Queue')
->groups(['api', 'health'])
->label('scope', 'health.read')
->label('sdk.platform', [APP_PLATFORM_SERVER])
->label('sdk.namespace', 'health')
@@ -121,6 +127,7 @@ $utopia->get('/v1/health/queue/webhooks')
$utopia->get('/v1/health/queue/tasks')
->desc('Get Tasks Queue')
->groups(['api', 'health'])
->label('scope', 'health.read')
->label('sdk.platform', [APP_PLATFORM_SERVER])
->label('sdk.namespace', 'health')
@@ -134,6 +141,7 @@ $utopia->get('/v1/health/queue/tasks')
$utopia->get('/v1/health/queue/logs')
->desc('Get Logs Queue')
->groups(['api', 'health'])
->label('scope', 'health.read')
->label('sdk.platform', [APP_PLATFORM_SERVER])
->label('sdk.namespace', 'health')
@@ -147,6 +155,7 @@ $utopia->get('/v1/health/queue/logs')
$utopia->get('/v1/health/queue/usage')
->desc('Get Usage Queue')
->groups(['api', 'health'])
->label('scope', 'health.read')
->label('sdk.platform', [APP_PLATFORM_SERVER])
->label('sdk.namespace', 'health')
@@ -160,6 +169,7 @@ $utopia->get('/v1/health/queue/usage')
$utopia->get('/v1/health/queue/certificates')
->desc('Get Certificate Queue')
->groups(['api', 'health'])
->label('scope', 'health.read')
->label('sdk.platform', [APP_PLATFORM_SERVER])
->label('sdk.namespace', 'health')
@@ -173,6 +183,7 @@ $utopia->get('/v1/health/queue/certificates')
$utopia->get('/v1/health/queue/functions')
->desc('Get Functions Queue')
->groups(['api', 'health'])
->label('scope', 'health.read')
->label('sdk.platform', [APP_PLATFORM_SERVER])
->label('sdk.namespace', 'health')
@@ -186,6 +197,7 @@ $utopia->get('/v1/health/queue/functions')
$utopia->get('/v1/health/storage/local')
->desc('Get Local Storage')
->groups(['api', 'health'])
->label('scope', 'health.read')
->label('sdk.platform', [APP_PLATFORM_SERVER])
->label('sdk.namespace', 'health')
@@ -193,7 +205,6 @@ $utopia->get('/v1/health/storage/local')
->label('sdk.description', '/docs/references/health/get-storage-local.md')
->action(
function () use ($response) {
foreach ([
'Uploads' => APP_STORAGE_UPLOADS,
'Cache' => APP_STORAGE_CACHE,
@@ -217,6 +228,7 @@ $utopia->get('/v1/health/storage/local')
$utopia->get('/v1/health/anti-virus')
->desc('Get Anti virus')
->groups(['api', 'health'])
->label('scope', 'health.read')
->label('sdk.platform', [APP_PLATFORM_SERVER])
->label('sdk.namespace', 'health')
@@ -224,7 +236,7 @@ $utopia->get('/v1/health/anti-virus')
->label('sdk.description', '/docs/references/health/get-storage-anti-virus.md')
->action(
function () use ($request, $response) {
if($request->getServer('_APP_STORAGE_ANTIVIRUS') === 'disabled') { // Check if scans are enabled
if ($request->getServer('_APP_STORAGE_ANTIVIRUS') === 'disabled') { // Check if scans are enabled
throw new Exception('Anitvirus is disabled');
}
@@ -239,6 +251,7 @@ $utopia->get('/v1/health/anti-virus')
$utopia->get('/v1/health/stats') // Currently only used internally
->desc('Get System Stats')
->groups(['api', 'health'])
->label('scope', 'god')
// ->label('sdk.platform', [APP_PLATFORM_SERVER])
// ->label('sdk.namespace', 'health')
+7 -2
View File
@@ -8,10 +8,9 @@ use Utopia\App;
use Utopia\Locale\Locale;
use GeoIp2\Database\Reader;
include_once __DIR__ . '/../shared/api.php';
$utopia->get('/v1/locale')
->desc('Get User Locale')
->groups(['api', 'locale'])
->label('scope', 'locale.read')
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
->label('sdk.namespace', 'locale')
@@ -72,6 +71,7 @@ $utopia->get('/v1/locale')
$utopia->get('/v1/locale/countries')
->desc('List Countries')
->groups(['api', 'locale'])
->label('scope', 'locale.read')
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
->label('sdk.namespace', 'locale')
@@ -89,6 +89,7 @@ $utopia->get('/v1/locale/countries')
$utopia->get('/v1/locale/countries/eu')
->desc('List EU Countries')
->groups(['api', 'locale'])
->label('scope', 'locale.read')
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
->label('sdk.namespace', 'locale')
@@ -114,6 +115,7 @@ $utopia->get('/v1/locale/countries/eu')
$utopia->get('/v1/locale/countries/phones')
->desc('List Countries Phone Codes')
->groups(['api', 'locale'])
->label('scope', 'locale.read')
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
->label('sdk.namespace', 'locale')
@@ -139,6 +141,7 @@ $utopia->get('/v1/locale/countries/phones')
$utopia->get('/v1/locale/continents')
->desc('List Continents')
->groups(['api', 'locale'])
->label('scope', 'locale.read')
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
->label('sdk.namespace', 'locale')
@@ -157,6 +160,7 @@ $utopia->get('/v1/locale/continents')
$utopia->get('/v1/locale/currencies')
->desc('List Currencies')
->groups(['api', 'locale'])
->label('scope', 'locale.read')
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
->label('sdk.namespace', 'locale')
@@ -173,6 +177,7 @@ $utopia->get('/v1/locale/currencies')
$utopia->get('/v1/locale/languages')
->desc('List Languages')
->groups(['api', 'locale'])
->label('scope', 'locale.read')
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
->label('sdk.namespace', 'locale')
+37 -7
View File
@@ -21,12 +21,11 @@ use Appwrite\OpenSSL\OpenSSL;
use Appwrite\Network\Validator\CNAME;
use Cron\CronExpression;
include_once __DIR__ . '/../shared/api.php';
$scopes = include __DIR__.'/../../../app/config/scopes.php';
$utopia->post('/v1/projects')
->desc('Create Project')
->groups(['api', 'projects'])
->label('scope', 'projects.write')
->label('sdk.namespace', 'projects')
->label('sdk.method', 'create')
@@ -89,6 +88,7 @@ $utopia->post('/v1/projects')
$utopia->get('/v1/projects')
->desc('List Projects')
->groups(['api', 'projects'])
->label('scope', 'projects.read')
->label('sdk.namespace', 'projects')
->label('sdk.method', 'list')
@@ -122,6 +122,7 @@ $utopia->get('/v1/projects')
$utopia->get('/v1/projects/:projectId')
->desc('Get Project')
->groups(['api', 'projects'])
->label('scope', 'projects.read')
->label('sdk.namespace', 'projects')
->label('sdk.method', 'get')
@@ -149,6 +150,7 @@ $utopia->get('/v1/projects/:projectId')
$utopia->get('/v1/projects/:projectId/usage')
->desc('Get Project')
->groups(['api', 'projects'])
->label('scope', 'projects.read')
->label('sdk.namespace', 'projects')
->label('sdk.method', 'getUsage')
@@ -310,6 +312,7 @@ $utopia->get('/v1/projects/:projectId/usage')
$utopia->patch('/v1/projects/:projectId')
->desc('Update Project')
->groups(['api', 'projects'])
->label('scope', 'projects.write')
->label('sdk.namespace', 'projects')
->label('sdk.method', 'update')
@@ -355,6 +358,7 @@ $utopia->patch('/v1/projects/:projectId')
$utopia->patch('/v1/projects/:projectId/oauth2')
->desc('Update Project OAuth2')
->groups(['api', 'projects'])
->label('scope', 'projects.write')
->label('sdk.namespace', 'projects')
->label('sdk.method', 'updateOAuth2')
@@ -396,6 +400,7 @@ $utopia->patch('/v1/projects/:projectId/oauth2')
$utopia->delete('/v1/projects/:projectId')
->desc('Delete Project')
->groups(['api', 'projects'])
->label('scope', 'projects.write')
->label('sdk.namespace', 'projects')
->label('sdk.method', 'delete')
@@ -415,7 +420,7 @@ $utopia->delete('/v1/projects/:projectId')
$deletes->setParam('document', $project->getArrayCopy());
foreach(['keys', 'webhooks', 'tasks', 'platforms', 'domains'] as $key) { // Delete all children (keys, webhooks, tasks [stop tasks?], platforms)
foreach (['keys', 'webhooks', 'tasks', 'platforms', 'domains'] as $key) { // Delete all children (keys, webhooks, tasks [stop tasks?], platforms)
$list = $project->getAttribute('webhooks', []);
foreach ($list as $document) { /* @var $document Document */
@@ -441,6 +446,7 @@ $utopia->delete('/v1/projects/:projectId')
$utopia->post('/v1/projects/:projectId/webhooks')
->desc('Create Webhook')
->groups(['api', 'projects'])
->label('scope', 'projects.write')
->label('sdk.namespace', 'projects')
->label('sdk.method', 'createWebhook')
@@ -505,6 +511,7 @@ $utopia->post('/v1/projects/:projectId/webhooks')
$utopia->get('/v1/projects/:projectId/webhooks')
->desc('List Webhooks')
->groups(['api', 'projects'])
->label('scope', 'projects.read')
->label('sdk.namespace', 'projects')
->label('sdk.method', 'listWebhooks')
@@ -537,6 +544,7 @@ $utopia->get('/v1/projects/:projectId/webhooks')
$utopia->get('/v1/projects/:projectId/webhooks/:webhookId')
->desc('Get Webhook')
->groups(['api', 'projects'])
->label('scope', 'projects.read')
->label('sdk.namespace', 'projects')
->label('sdk.method', 'getWebhook')
@@ -570,6 +578,7 @@ $utopia->get('/v1/projects/:projectId/webhooks/:webhookId')
$utopia->put('/v1/projects/:projectId/webhooks/:webhookId')
->desc('Update Webhook')
->groups(['api', 'projects'])
->label('scope', 'projects.write')
->label('sdk.namespace', 'projects')
->label('sdk.method', 'updateWebhook')
@@ -625,6 +634,7 @@ $utopia->put('/v1/projects/:projectId/webhooks/:webhookId')
$utopia->delete('/v1/projects/:projectId/webhooks/:webhookId')
->desc('Delete Webhook')
->groups(['api', 'projects'])
->label('scope', 'projects.write')
->label('sdk.namespace', 'projects')
->label('sdk.method', 'deleteWebhook')
@@ -656,6 +666,7 @@ $utopia->delete('/v1/projects/:projectId/webhooks/:webhookId')
$utopia->post('/v1/projects/:projectId/keys')
->desc('Create Key')
->groups(['api', 'projects'])
->label('scope', 'projects.write')
->label('sdk.namespace', 'projects')
->label('sdk.method', 'createKey')
@@ -702,6 +713,7 @@ $utopia->post('/v1/projects/:projectId/keys')
$utopia->get('/v1/projects/:projectId/keys')
->desc('List Keys')
->groups(['api', 'projects'])
->label('scope', 'projects.read')
->label('sdk.namespace', 'projects')
->label('sdk.method', 'listKeys')
@@ -720,6 +732,7 @@ $utopia->get('/v1/projects/:projectId/keys')
$utopia->get('/v1/projects/:projectId/keys/:keyId')
->desc('Get Key')
->groups(['api', 'projects'])
->label('scope', 'projects.read')
->label('sdk.namespace', 'projects')
->label('sdk.method', 'getKey')
@@ -745,6 +758,7 @@ $utopia->get('/v1/projects/:projectId/keys/:keyId')
$utopia->put('/v1/projects/:projectId/keys/:keyId')
->desc('Update Key')
->groups(['api', 'projects'])
->label('scope', 'projects.write')
->label('sdk.namespace', 'projects')
->label('sdk.method', 'updateKey')
@@ -781,6 +795,7 @@ $utopia->put('/v1/projects/:projectId/keys/:keyId')
$utopia->delete('/v1/projects/:projectId/keys/:keyId')
->desc('Delete Key')
->groups(['api', 'projects'])
->label('scope', 'projects.write')
->label('sdk.namespace', 'projects')
->label('sdk.method', 'deleteKey')
@@ -812,6 +827,7 @@ $utopia->delete('/v1/projects/:projectId/keys/:keyId')
$utopia->post('/v1/projects/:projectId/tasks')
->desc('Create Task')
->groups(['api', 'projects'])
->label('scope', 'projects.write')
->label('sdk.namespace', 'projects')
->label('sdk.method', 'createTask')
@@ -894,6 +910,7 @@ $utopia->post('/v1/projects/:projectId/tasks')
$utopia->get('/v1/projects/:projectId/tasks')
->desc('List Tasks')
->groups(['api', 'projects'])
->label('scope', 'projects.read')
->label('sdk.namespace', 'projects')
->label('sdk.method', 'listTasks')
@@ -926,6 +943,7 @@ $utopia->get('/v1/projects/:projectId/tasks')
$utopia->get('/v1/projects/:projectId/tasks/:taskId')
->desc('Get Task')
->groups(['api', 'projects'])
->label('scope', 'projects.read')
->label('sdk.namespace', 'projects')
->label('sdk.method', 'getTask')
@@ -958,6 +976,7 @@ $utopia->get('/v1/projects/:projectId/tasks/:taskId')
$utopia->put('/v1/projects/:projectId/tasks/:taskId')
->desc('Update Task')
->groups(['api', 'projects'])
->label('scope', 'projects.write')
->label('sdk.namespace', 'projects')
->label('sdk.method', 'updateTask')
@@ -1028,6 +1047,7 @@ $utopia->put('/v1/projects/:projectId/tasks/:taskId')
$utopia->delete('/v1/projects/:projectId/tasks/:taskId')
->desc('Delete Task')
->groups(['api', 'projects'])
->label('scope', 'projects.write')
->label('sdk.namespace', 'projects')
->label('sdk.method', 'deleteTask')
@@ -1059,6 +1079,7 @@ $utopia->delete('/v1/projects/:projectId/tasks/:taskId')
$utopia->post('/v1/projects/:projectId/platforms')
->desc('Create Platform')
->groups(['api', 'projects'])
->label('scope', 'projects.write')
->label('sdk.namespace', 'projects')
->label('sdk.method', 'createPlatform')
@@ -1112,6 +1133,7 @@ $utopia->post('/v1/projects/:projectId/platforms')
$utopia->get('/v1/projects/:projectId/platforms')
->desc('List Platforms')
->groups(['api', 'projects'])
->label('scope', 'projects.read')
->label('sdk.namespace', 'projects')
->label('sdk.method', 'listPlatforms')
@@ -1132,6 +1154,7 @@ $utopia->get('/v1/projects/:projectId/platforms')
$utopia->get('/v1/projects/:projectId/platforms/:platformId')
->desc('Get Platform')
->groups(['api', 'projects'])
->label('scope', 'projects.read')
->label('sdk.namespace', 'projects')
->label('sdk.method', 'getPlatform')
@@ -1157,6 +1180,7 @@ $utopia->get('/v1/projects/:projectId/platforms/:platformId')
$utopia->put('/v1/projects/:projectId/platforms/:platformId')
->desc('Update Platform')
->groups(['api', 'projects'])
->label('scope', 'projects.write')
->label('sdk.namespace', 'projects')
->label('sdk.method', 'updatePlatform')
@@ -1198,6 +1222,7 @@ $utopia->put('/v1/projects/:projectId/platforms/:platformId')
$utopia->delete('/v1/projects/:projectId/platforms/:platformId')
->desc('Delete Platform')
->groups(['api', 'projects'])
->label('scope', 'projects.write')
->label('sdk.namespace', 'projects')
->label('sdk.method', 'deletePlatform')
@@ -1229,6 +1254,7 @@ $utopia->delete('/v1/projects/:projectId/platforms/:platformId')
$utopia->post('/v1/projects/:projectId/domains')
->desc('Create Domain')
->groups(['api', 'projects'])
->label('scope', 'projects.write')
->label('sdk.namespace', 'projects')
->label('sdk.method', 'createDomain')
@@ -1250,7 +1276,7 @@ $utopia->post('/v1/projects/:projectId/domains')
$target = new Domain($request->getServer('_APP_DOMAIN_TARGET', ''));
if(!$target->isKnown() || $target->isTest()) {
if (!$target->isKnown() || $target->isTest()) {
throw new Exception('Unreachable CNAME target ('.$target->get().'), plesse use a domain with a public suffix.', 500);
}
@@ -1291,6 +1317,7 @@ $utopia->post('/v1/projects/:projectId/domains')
$utopia->get('/v1/projects/:projectId/domains')
->desc('List Domains')
->groups(['api', 'projects'])
->label('scope', 'projects.read')
->label('sdk.namespace', 'projects')
->label('sdk.method', 'listDomains')
@@ -1311,6 +1338,7 @@ $utopia->get('/v1/projects/:projectId/domains')
$utopia->get('/v1/projects/:projectId/domains/:domainId')
->desc('Get Domain')
->groups(['api', 'projects'])
->label('scope', 'projects.read')
->label('sdk.namespace', 'projects')
->label('sdk.method', 'getDomain')
@@ -1336,6 +1364,7 @@ $utopia->get('/v1/projects/:projectId/domains/:domainId')
$utopia->patch('/v1/projects/:projectId/domains/:domainId/verification')
->desc('Update Domain Verification Status')
->groups(['api', 'projects'])
->label('scope', 'projects.write')
->label('sdk.namespace', 'projects')
->label('sdk.method', 'updateDomainVerification')
@@ -1357,18 +1386,18 @@ $utopia->patch('/v1/projects/:projectId/domains/:domainId/verification')
$target = new Domain($request->getServer('_APP_DOMAIN_TARGET', ''));
if(!$target->isKnown() || $target->isTest()) {
if (!$target->isKnown() || $target->isTest()) {
throw new Exception('Unreachable CNAME target ('.$target->get().'), plesse use a domain with a public suffix.', 500);
}
if($domain->getAttribute('verification') === true) {
if ($domain->getAttribute('verification') === true) {
return $response->json($domain->getArrayCopy());
}
// Verify Domain with DNS records
$validator = new CNAME($target->get());
if(!$validator->isValid($domain->getAttribute('domain', ''))) {
if (!$validator->isValid($domain->getAttribute('domain', ''))) {
throw new Exception('Failed to verify domain', 401);
}
@@ -1392,6 +1421,7 @@ $utopia->patch('/v1/projects/:projectId/domains/:domainId/verification')
$utopia->delete('/v1/projects/:projectId/domains/:domainId')
->desc('Delete Domain')
->groups(['api', 'projects'])
->label('scope', 'projects.write')
->label('sdk.namespace', 'projects')
->label('sdk.method', 'deleteDomain')
+12 -7
View File
@@ -23,8 +23,6 @@ use Appwrite\Storage\Compression\Algorithms\GZIP;
use Appwrite\Resize\Resize;
use Appwrite\OpenSSL\OpenSSL;
include_once __DIR__ . '/../shared/api.php';
Storage::addDevice('local', new Local(APP_STORAGE_UPLOADS.'/app-'.$project->getId()));
$fileLogos = [ // Based on this list @see http://stackoverflow.com/a/4212908/2299554
@@ -135,6 +133,7 @@ $mimes = [
$utopia->post('/v1/storage/files')
->desc('Create File')
->groups(['api', 'storage'])
->label('scope', 'files.write')
->label('webhook', 'storage.files.create')
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
@@ -198,7 +197,7 @@ $utopia->post('/v1/storage/files')
$mimeType = $device->getFileMimeType($path); // Get mime-type before compression and encryption
if($request->getServer('_APP_STORAGE_ANTIVIRUS') === 'enabled') { // Check if scans are enabled
if ($request->getServer('_APP_STORAGE_ANTIVIRUS') === 'enabled') { // Check if scans are enabled
$antiVirus = new Network('clamav', 3310);
// Check if file size is exceeding allowed limit
@@ -216,7 +215,7 @@ $utopia->post('/v1/storage/files')
$iv = OpenSSL::randomPseudoBytes(OpenSSL::cipherIVLength(OpenSSL::CIPHER_AES_128_GCM));
$data = OpenSSL::encrypt($data, OpenSSL::CIPHER_AES_128_GCM, $key, 0, $iv, $tag);
if(!$device->write($path, $data)) {
if (!$device->write($path, $data)) {
throw new Exception('Failed to save file', 500);
}
@@ -271,6 +270,7 @@ $utopia->post('/v1/storage/files')
$utopia->get('/v1/storage/files')
->desc('List Files')
->groups(['api', 'storage'])
->label('scope', 'files.read')
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
->label('sdk.namespace', 'storage')
@@ -304,6 +304,7 @@ $utopia->get('/v1/storage/files')
$utopia->get('/v1/storage/files/:fileId')
->desc('Get File')
->groups(['api', 'storage'])
->label('scope', 'files.read')
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
->label('sdk.namespace', 'storage')
@@ -324,6 +325,7 @@ $utopia->get('/v1/storage/files/:fileId')
$utopia->get('/v1/storage/files/:fileId/preview')
->desc('Get File Preview')
->groups(['api', 'storage'])
->label('scope', 'files.read')
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
->label('sdk.namespace', 'storage')
@@ -337,8 +339,6 @@ $utopia->get('/v1/storage/files/:fileId/preview')
->param('quality', 100, function () { return new Range(0, 100); }, 'Preview image quality. Pass an integer between 0 to 100. Defaults to 100.', true)
->param('background', '', function () { return new HexColor(); }, 'Preview image background color. Only works with transparent images (png). Use a valid HEX color, no # is needed for prefix.', true)
->param('output', null, function () use ($outputs) { return new WhiteList(\array_merge(\array_keys($outputs), [null])); }, 'Output format type (jpeg, jpg, png, gif and webp).', true)
//->param('storage', 'local', function () {return new WhiteList(array('local'));}, 'Selected storage device. defaults to local')
//->param('token', '', function () {return new Text(128);}, 'Preview token', true)
->action(
function ($fileId, $width, $height, $quality, $background, $output) use ($request, $response, $projectDB, $project, $inputs, $outputs, $fileLogos) {
$storage = 'local';
@@ -370,7 +370,7 @@ $utopia->get('/v1/storage/files/:fileId/preview')
$cipher = $file->getAttribute('fileOpenSSLCipher');
$mime = $file->getAttribute('mimeType');
if(!\in_array($mime, $inputs)) {
if (!\in_array($mime, $inputs)) {
$path = (\array_key_exists($mime, $fileLogos)) ? $fileLogos[$mime] : $fileLogos['default'];
$algorithm = null;
$cipher = null;
@@ -448,6 +448,7 @@ $utopia->get('/v1/storage/files/:fileId/preview')
$utopia->get('/v1/storage/files/:fileId/download')
->desc('Get File for Download')
->groups(['api', 'storage'])
->label('scope', 'files.read')
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
->label('sdk.namespace', 'storage')
@@ -501,6 +502,7 @@ $utopia->get('/v1/storage/files/:fileId/download')
$utopia->get('/v1/storage/files/:fileId/view')
->desc('Get File for View')
->groups(['api', 'storage'])
->label('scope', 'files.read')
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
->label('sdk.namespace', 'storage')
@@ -571,6 +573,7 @@ $utopia->get('/v1/storage/files/:fileId/view')
$utopia->put('/v1/storage/files/:fileId')
->desc('Update File')
->groups(['api', 'storage'])
->label('scope', 'files.write')
->label('webhook', 'storage.files.update')
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
@@ -616,6 +619,7 @@ $utopia->put('/v1/storage/files/:fileId')
$utopia->delete('/v1/storage/files/:fileId')
->desc('Delete File')
->groups(['api', 'storage'])
->label('scope', 'files.write')
->label('webhook', 'storage.files.delete')
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
@@ -658,6 +662,7 @@ $utopia->delete('/v1/storage/files/:fileId')
// $utopia->get('/v1/storage/files/:fileId/scan')
// ->desc('Scan Storage')
// ->groups(['api', 'storage'])
// ->label('scope', 'god')
// ->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
// ->label('sdk.namespace', 'storage')
+36 -54
View File
@@ -3,7 +3,6 @@
global $utopia, $register, $request, $response, $projectDB, $project, $user, $audit, $mail, $mode, $clients;
use Utopia\Exception;
use Utopia\Response;
use Utopia\Config\Config;
use Utopia\Validator\Email;
use Utopia\Validator\Text;
@@ -19,11 +18,11 @@ use Appwrite\Database\Validator\UID;
use Appwrite\Database\Validator\Authorization;
use Appwrite\Database\Exception\Duplicate;
use Appwrite\Template\Template;
include_once __DIR__ . '/../shared/api.php';
use Appwrite\Utopia\Response;
$utopia->post('/v1/teams')
->desc('Create Team')
->groups(['api', 'teams'])
->label('scope', 'teams.write')
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
->label('sdk.namespace', 'teams')
@@ -78,15 +77,14 @@ $utopia->post('/v1/teams')
}
}
$response
->setStatusCode(Response::STATUS_CODE_CREATED)
->json($team->getArrayCopy())
;
$response->setStatusCode(Response::STATUS_CODE_CREATED);
$response->dynamic($team, Response::MODEL_TEAM);
}
);
$utopia->get('/v1/teams')
->desc('List Teams')
->groups(['api', 'teams'])
->label('scope', 'teams.read')
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
->label('sdk.namespace', 'teams')
@@ -110,12 +108,16 @@ $utopia->get('/v1/teams')
],
]);
$response->json(['sum' => $projectDB->getSum(), 'teams' => $results]);
$response->dynamic(new Document([
'sum' => $projectDB->getSum(),
'teams' => $results
]), Response::MODEL_TEAM_LIST);
}
);
$utopia->get('/v1/teams/:teamId')
->desc('Get Team')
->groups(['api', 'teams'])
->label('scope', 'teams.read')
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
->label('sdk.namespace', 'teams')
@@ -130,12 +132,13 @@ $utopia->get('/v1/teams/:teamId')
throw new Exception('Team not found', 404);
}
$response->json($team->getArrayCopy([]));
$response->dynamic($team, Response::MODEL_TEAM);
}
);
$utopia->put('/v1/teams/:teamId')
->desc('Update Team')
->groups(['api', 'teams'])
->label('scope', 'teams.write')
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
->label('sdk.namespace', 'teams')
@@ -159,12 +162,13 @@ $utopia->put('/v1/teams/:teamId')
throw new Exception('Failed saving team to DB', 500);
}
$response->json($team->getArrayCopy());
$response->dynamic($team, Response::MODEL_TEAM);
}
);
$utopia->delete('/v1/teams/:teamId')
->desc('Delete Team')
->groups(['api', 'teams'])
->label('scope', 'teams.write')
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
->label('sdk.namespace', 'teams')
@@ -204,6 +208,7 @@ $utopia->delete('/v1/teams/:teamId')
$utopia->post('/v1/teams/:teamId/memberships')
->desc('Create Team Membership')
->groups(['api', 'teams'])
->label('scope', 'teams.write')
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
->label('sdk.namespace', 'teams')
@@ -306,12 +311,11 @@ $utopia->post('/v1/teams/:teamId/memberships')
'secret' => Auth::hash($secret),
]);
if(APP_MODE_ADMIN === $mode) { // Allow admin to create membership
if (APP_MODE_ADMIN === $mode) { // Allow admin to create membership
Authorization::disable();
$membership = $projectDB->createDocument($membership->getArrayCopy());
Authorization::reset();
}
else {
} else {
$membership = $projectDB->createDocument($membership->getArrayCopy());
}
@@ -344,7 +348,7 @@ $utopia->post('/v1/teams/:teamId/memberships')
->setParam('{{text-cta}}', '#ffffff')
;
if(APP_MODE_ADMIN !== $mode) { // No need in comfirmation when in admin mode
if (APP_MODE_ADMIN !== $mode) { // No need in comfirmation when in admin mode
$mail
->setParam('event', 'teams.membership.create')
->setParam('recipient', $email)
@@ -361,26 +365,18 @@ $utopia->post('/v1/teams/:teamId/memberships')
->setParam('resource', 'teams/'.$teamId)
;
$response
->setStatusCode(Response::STATUS_CODE_CREATED) // TODO change response of this endpoint
->json(\array_merge($membership->getArrayCopy([
'$id',
'userId',
'teamId',
'roles',
'invited',
'joined',
'confirm',
]), [
'email' => $email,
'name' => $name,
]))
;
$response->setStatusCode(Response::STATUS_CODE_CREATED); // TODO change response of this endpoint
$response->dynamic(new Document(\array_merge($membership->getArrayCopy(), [
'email' => $email,
'name' => $name,
])), Response::MODEL_MEMBERSHIP);
}
);
$utopia->get('/v1/teams/:teamId/memberships')
->desc('Get Team Memberships')
->groups(['api', 'teams'])
->label('scope', 'teams.read')
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
->label('sdk.namespace', 'teams')
@@ -421,24 +417,16 @@ $utopia->get('/v1/teams/:teamId/memberships')
$temp = $projectDB->getDocument($membership->getAttribute('userId', null))->getArrayCopy(['email', 'name']);
$users[] = \array_merge($temp, $membership->getArrayCopy([
'$id',
'userId',
'teamId',
'roles',
'invited',
'joined',
'confirm',
]));
$users[] = new Document(\array_merge($temp, $membership->getArrayCopy()));
}
$response->json(['sum' => $projectDB->getSum(), 'memberships' => $users]);
$response->dynamic(new Document(['sum' => $projectDB->getSum(), 'memberships' => $users]), Response::MODEL_MEMBERSHIP_LIST);
}
);
$utopia->patch('/v1/teams/:teamId/memberships/:inviteId/status')
->desc('Update Team Membership Status')
->groups(['api', 'teams'])
->label('scope', 'public')
->label('sdk.platform', [APP_PLATFORM_CLIENT])
->label('sdk.namespace', 'teams')
@@ -544,7 +532,7 @@ $utopia->patch('/v1/teams/:teamId/memberships/:inviteId/status')
->setParam('resource', 'teams/'.$teamId)
;
if(!Config::getParam('domainVerification')) {
if (!Config::getParam('domainVerification')) {
$response
->addHeader('X-Fallback-Cookies', \json_encode([Auth::$cookieName => Auth::encodeSession($user->getId(), $secret)]))
;
@@ -553,24 +541,18 @@ $utopia->patch('/v1/teams/:teamId/memberships/:inviteId/status')
$response
->addCookie(Auth::$cookieName.'_legacy', Auth::encodeSession($user->getId(), $secret), $expiry, '/', COOKIE_DOMAIN, ('https' == $protocol), true, null)
->addCookie(Auth::$cookieName, Auth::encodeSession($user->getId(), $secret), $expiry, '/', COOKIE_DOMAIN, ('https' == $protocol), true, COOKIE_SAMESITE)
->json(\array_merge($membership->getArrayCopy([
'$id',
'userId',
'teamId',
'roles',
'invited',
'joined',
'confirm',
]), [
'email' => $user->getAttribute('email'),
'name' => $user->getAttribute('name'),
]))
;
$response->dynamic(new Document(\array_merge($membership->getArrayCopy(), [
'email' => $user->getAttribute('email'),
'name' => $user->getAttribute('name'),
])), Response::MODEL_MEMBERSHIP);
}
);
$utopia->delete('/v1/teams/:teamId/memberships/:inviteId')
->desc('Delete Team Membership')
->groups(['api', 'teams'])
->label('scope', 'teams.write')
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
->label('sdk.namespace', 'teams')
@@ -618,4 +600,4 @@ $utopia->delete('/v1/teams/:teamId/memberships/:inviteId')
$response->noContent();
}
);
);
+10 -2
View File
@@ -21,10 +21,9 @@ use Appwrite\Utopia\Response;
use DeviceDetector\DeviceDetector;
use GeoIp2\Database\Reader;
include_once __DIR__ . '/../shared/api.php';
$utopia->post('/v1/users')
->desc('Create User')
->groups(['api', 'users'])
->label('scope', 'users.write')
->label('sdk.platform', [APP_PLATFORM_SERVER])
->label('sdk.namespace', 'users')
@@ -86,6 +85,7 @@ $utopia->post('/v1/users')
$utopia->get('/v1/users')
->desc('List Users')
->groups(['api', 'users'])
->label('scope', 'users.read')
->label('sdk.platform', [APP_PLATFORM_SERVER])
->label('sdk.namespace', 'users')
@@ -140,6 +140,7 @@ $utopia->get('/v1/users')
$utopia->get('/v1/users/:userId')
->desc('Get User')
->groups(['api', 'users'])
->label('scope', 'users.read')
->label('sdk.platform', [APP_PLATFORM_SERVER])
->label('sdk.namespace', 'users')
@@ -181,6 +182,7 @@ $utopia->get('/v1/users/:userId')
$utopia->get('/v1/users/:userId/prefs')
->desc('Get User Preferences')
->groups(['api', 'users'])
->label('scope', 'users.read')
->label('sdk.platform', [APP_PLATFORM_SERVER])
->label('sdk.namespace', 'users')
@@ -210,6 +212,7 @@ $utopia->get('/v1/users/:userId/prefs')
$utopia->get('/v1/users/:userId/sessions')
->desc('Get User Sessions')
->groups(['api', 'users'])
->label('scope', 'users.read')
->label('sdk.platform', [APP_PLATFORM_SERVER])
->label('sdk.namespace', 'users')
@@ -273,6 +276,7 @@ $utopia->get('/v1/users/:userId/sessions')
$utopia->get('/v1/users/:userId/logs')
->desc('Get User Logs')
->groups(['api', 'users'])
->label('scope', 'users.read')
->label('sdk.platform', [APP_PLATFORM_SERVER])
->label('sdk.namespace', 'users')
@@ -353,6 +357,7 @@ $utopia->get('/v1/users/:userId/logs')
$utopia->patch('/v1/users/:userId/status')
->desc('Update User Status')
->groups(['api', 'users'])
->label('scope', 'users.write')
->label('sdk.platform', [APP_PLATFORM_SERVER])
->label('sdk.namespace', 'users')
@@ -401,6 +406,7 @@ $utopia->patch('/v1/users/:userId/status')
$utopia->patch('/v1/users/:userId/prefs')
->desc('Update User Preferences')
->groups(['api', 'users'])
->label('scope', 'users.write')
->label('sdk.platform', [APP_PLATFORM_SERVER])
->label('sdk.namespace', 'users')
@@ -443,6 +449,7 @@ $utopia->patch('/v1/users/:userId/prefs')
$utopia->delete('/v1/users/:userId/sessions/:sessionId')
->desc('Delete User Session')
->groups(['api', 'users'])
->label('scope', 'users.write')
->label('sdk.platform', [APP_PLATFORM_SERVER])
->label('sdk.namespace', 'users')
@@ -475,6 +482,7 @@ $utopia->delete('/v1/users/:userId/sessions/:sessionId')
$utopia->delete('/v1/users/:userId/sessions')
->desc('Delete User Sessions')
->groups(['api', 'users'])
->label('scope', 'users.write')
->label('sdk.platform', [APP_PLATFORM_SERVER])
->label('sdk.namespace', 'users')
+11 -22
View File
@@ -22,7 +22,6 @@ $utopia->get('/v1/mock/tests/foo')
->param('z', null, function () { return new ArrayList(new Text(256)); }, 'Sample array param')
->action(
function ($x, $y, $z) {
}
);
@@ -37,7 +36,6 @@ $utopia->post('/v1/mock/tests/foo')
->param('z', null, function () { return new ArrayList(new Text(256)); }, 'Sample array param')
->action(
function ($x, $y, $z) {
}
);
@@ -52,7 +50,6 @@ $utopia->patch('/v1/mock/tests/foo')
->param('z', null, function () { return new ArrayList(new Text(256)); }, 'Sample array param')
->action(
function ($x, $y, $z) {
}
);
@@ -67,7 +64,6 @@ $utopia->put('/v1/mock/tests/foo')
->param('z', null, function () { return new ArrayList(new Text(256)); }, 'Sample array param')
->action(
function ($x, $y, $z) {
}
);
@@ -82,7 +78,6 @@ $utopia->delete('/v1/mock/tests/foo')
->param('z', null, function () { return new ArrayList(new Text(256)); }, 'Sample array param')
->action(
function ($x, $y, $z) {
}
);
@@ -97,7 +92,6 @@ $utopia->get('/v1/mock/tests/bar')
->param('z', null, function () { return new ArrayList(new Text(256)); }, 'Sample array param')
->action(
function ($x, $y, $z) {
}
);
@@ -112,7 +106,6 @@ $utopia->post('/v1/mock/tests/bar')
->param('z', null, function () { return new ArrayList(new Text(256)); }, 'Sample array param')
->action(
function ($x, $y, $z) {
}
);
@@ -127,7 +120,6 @@ $utopia->patch('/v1/mock/tests/bar')
->param('z', null, function () { return new ArrayList(new Text(256)); }, 'Sample array param')
->action(
function ($x, $y, $z) {
}
);
@@ -142,7 +134,6 @@ $utopia->put('/v1/mock/tests/bar')
->param('z', null, function () { return new ArrayList(new Text(256)); }, 'Sample array param')
->action(
function ($x, $y, $z) {
}
);
@@ -157,7 +148,6 @@ $utopia->delete('/v1/mock/tests/bar')
->param('z', null, function () { return new ArrayList(new Text(256)); }, 'Sample array param')
->action(
function ($x, $y, $z) {
}
);
@@ -180,19 +170,19 @@ $utopia->post('/v1/mock/tests/general/upload')
$file['size'] = (\is_array($file['size'])) ? $file['size'] : [$file['size']];
foreach ($file['name'] as $i => $name) {
if($name !== 'file.png') {
if ($name !== 'file.png') {
throw new Exception('Wrong file name', 400);
}
}
foreach ($file['size'] as $i => $size) {
if($size !== 38756) {
if ($size !== 38756) {
throw new Exception('Wrong file size', 400);
}
}
foreach ($file['tmp_name'] as $i => $tmpName) {
if(\md5(\file_get_contents($tmpName)) !== 'd80e7e6999a3eb2ae0d631a96fe135a4') {
if (\md5(\file_get_contents($tmpName)) !== 'd80e7e6999a3eb2ae0d631a96fe135a4') {
throw new Exception('Wrong file uploaded', 400);
}
}
@@ -242,7 +232,7 @@ $utopia->get('/v1/mock/tests/general/get-cookie')
->label('sdk.description', 'Mock a get cookie request for SDK tests')
->action(
function () use ($request) {
if($request->getCookie('cookieName', '') !== 'cookieValue') {
if ($request->getCookie('cookieName', '') !== 'cookieValue') {
throw new Exception('Missing cookie value', 400);
}
}
@@ -285,15 +275,15 @@ $utopia->get('/v1/mock/tests/general/oauth2/token')
->param('code', '', function () { return new Text(100); }, 'OAuth2 state.')
->action(
function ($clientId, $redirectURI, $clientSecret, $code) use ($response) {
if($clientId != '1') {
if ($clientId != '1') {
throw new Exception('Invalid client ID');
}
if($clientSecret != '123456') {
if ($clientSecret != '123456') {
throw new Exception('Invalid client secret');
}
if($code != 'abcdef') {
if ($code != 'abcdef') {
throw new Exception('Invalid token');
}
@@ -308,7 +298,7 @@ $utopia->get('/v1/mock/tests/general/oauth2/user')
->param('token', '', function () { return new Text(100); }, 'OAuth2 Access Token.')
->action(
function ($token) use ($response) {
if($token != '123456') {
if ($token != '123456') {
throw new Exception('Invalid token');
}
@@ -345,12 +335,11 @@ $utopia->get('/v1/mock/tests/general/oauth2/failure')
);
$utopia->shutdown(function() use ($response, $request, &$result, $utopia) {
$route = $utopia->match($request);
$path = APP_STORAGE_CACHE.'/tests.json';
$tests = (\file_exists($path)) ? \json_decode(\file_get_contents($path), true) : [];
if(!\is_array($tests)) {
if (!\is_array($tests)) {
throw new Exception('Failed to read results', 500);
}
@@ -358,9 +347,9 @@ $utopia->shutdown(function() use ($response, $request, &$result, $utopia) {
$tests = \array_merge($tests, $result);
if(!\file_put_contents($path, \json_encode($tests), LOCK_EX)) {
if (!\file_put_contents($path, \json_encode($tests), LOCK_EX)) {
throw new Exception('Failed to save resutls', 500);
}
$response->json(['result' => $route->getMethod() . ':' . $route->getURL() . ':passed']);
});
}, 'mock');
+2 -4
View File
@@ -7,10 +7,9 @@ use Utopia\Abuse\Adapters\TimeLimit;
global $utopia, $request, $response, $register, $user, $project;
$utopia->init(function () use ($utopia, $request, $response, $register, $user, $project) {
$route = $utopia->match($request);
if(empty($project->getId()) && $route->getLabel('abuse-limit', 0) > 0) { // Abuse limit requires an active project scope
if (empty($project->getId()) && $route->getLabel('abuse-limit', 0) > 0) { // Abuse limit requires an active project scope
throw new Exception('Missing or unknown project ID', 400);
}
@@ -37,7 +36,6 @@ $utopia->init(function () use ($utopia, $request, $response, $register, $user, $
$abuse = new Abuse($timeLimit);
if ($timeLimit->limit()) {
$response
->addHeader('X-RateLimit-Limit', $timeLimit->limit())
->addHeader('X-RateLimit-Remaining', $timeLimit->remaining())
@@ -48,4 +46,4 @@ $utopia->init(function () use ($utopia, $request, $response, $register, $user, $
if ($abuse->check() && $request->getServer('_APP_OPTIONS_ABUSE', 'enabled') !== 'disabled') {
throw new Exception('Too many requests', 429);
}
});
}, 'api');
+22 -27
View File
@@ -2,36 +2,31 @@
use Utopia\View;
use Utopia\Config\Config;
use Utopia\Locale\Locale;
Locale::$exceptions = false;
$roles = [
['type' => 'owner', 'label' => 'Owner'],
['type' => 'developer', 'label' => 'Developer'],
['type' => 'admin', 'label' => 'Admin'],
];
$layout = new View(__DIR__.'/../../views/layouts/default.phtml');
/* AJAX check */
if (!empty($request->getQuery('version', ''))) {
$layout->setPath(__DIR__.'/../../views/layouts/empty.phtml');
}
$layout
->setParam('title', APP_NAME)
->setParam('protocol', Config::getParam('protocol'))
->setParam('domain', $domain)
->setParam('home', $request->getServer('_APP_HOME'))
->setParam('setup', $request->getServer('_APP_SETUP'))
->setParam('class', 'unknown')
->setParam('icon', '/images/favicon.png')
->setParam('roles', $roles)
->setParam('env', $utopia->getMode())
;
$utopia->init(function () use ($utopia, $response, $request, $layout) {
/* AJAX check */
if (!empty($request->getQuery('version', ''))) {
$layout->setPath(__DIR__.'/../../views/layouts/empty.phtml');
}
$layout
->setParam('title', APP_NAME)
->setParam('protocol', Config::getParam('protocol'))
->setParam('domain', Config::getParam('domain'))
->setParam('home', $request->getServer('_APP_HOME'))
->setParam('setup', $request->getServer('_APP_SETUP'))
->setParam('class', 'unknown')
->setParam('icon', '/images/favicon.png')
->setParam('roles', [
['type' => 'owner', 'label' => 'Owner'],
['type' => 'developer', 'label' => 'Developer'],
['type' => 'admin', 'label' => 'Admin'],
])
->setParam('env', $utopia->getMode())
;
$time = (60 * 60 * 24 * 45); // 45 days cache
$isDev = (\Utopia\App::MODE_TYPE_DEVELOPMENT == Config::getParam('env'));
@@ -47,4 +42,4 @@ $utopia->init(function () use ($utopia, $response, $request, $layout) {
->setParam('isDev', $isDev)
->setParam('class', $scope)
;
});
}, 'web');
+18 -19
View File
@@ -1,7 +1,5 @@
<?php
include_once __DIR__ . '/../shared/web.php';
global $utopia, $response, $request, $layout, $projectDB;
use Utopia\View;
@@ -17,7 +15,7 @@ $utopia->init(function () use ($layout) {
->setParam('description', 'Appwrite Console allows you to easily manage, monitor, and control your entire backend API and tools.')
->setParam('analytics', 'UA-26264668-5')
;
});
}, 'console');
$utopia->shutdown(function () use ($response, $request, $layout) {
$header = new View(__DIR__.'/../../views/console/comps/header.phtml');
@@ -34,10 +32,10 @@ $utopia->shutdown(function () use ($response, $request, $layout) {
;
$response->send($layout->render());
});
}, 'console');
$utopia->get('/error/:code')
->desc('Error page')
->groups(['web', 'console'])
->label('permission', 'public')
->label('scope', 'home')
->param('code', null, new \Utopia\Validator\Numeric(), 'Valid status code number', false)
@@ -54,6 +52,7 @@ $utopia->get('/error/:code')
});
$utopia->get('/console')
->groups(['web', 'console'])
->label('permission', 'public')
->label('scope', 'console')
->action(function () use ($layout, $request) {
@@ -69,6 +68,7 @@ $utopia->get('/console')
});
$utopia->get('/console/account')
->groups(['web', 'console'])
->label('permission', 'public')
->label('scope', 'console')
->action(function () use ($layout) {
@@ -86,7 +86,7 @@ $utopia->get('/console/account')
});
$utopia->get('/console/notifications')
->desc('Platform console notifications')
->groups(['web', 'console'])
->label('permission', 'public')
->label('scope', 'console')
->action(function () use ($layout) {
@@ -98,7 +98,7 @@ $utopia->get('/console/notifications')
});
$utopia->get('/console/home')
->desc('Platform console project home')
->groups(['web', 'console'])
->label('permission', 'public')
->label('scope', 'console')
->action(function () use ($layout) {
@@ -110,7 +110,7 @@ $utopia->get('/console/home')
});
$utopia->get('/console/settings')
->desc('Platform console project settings')
->groups(['web', 'console'])
->label('permission', 'public')
->label('scope', 'console')
->action(function () use ($request, $layout) {
@@ -129,7 +129,7 @@ $utopia->get('/console/settings')
});
$utopia->get('/console/webhooks')
->desc('Platform console project webhooks')
->groups(['web', 'console'])
->label('permission', 'public')
->label('scope', 'console')
->action(function () use ($layout) {
@@ -145,7 +145,7 @@ $utopia->get('/console/webhooks')
});
$utopia->get('/console/keys')
->desc('Platform console project keys')
->groups(['web', 'console'])
->label('permission', 'public')
->label('scope', 'console')
->action(function () use ($layout) {
@@ -160,7 +160,7 @@ $utopia->get('/console/keys')
});
$utopia->get('/console/tasks')
->desc('Platform console project tasks')
->groups(['web', 'console'])
->label('permission', 'public')
->label('scope', 'console')
->action(function () use ($layout) {
@@ -172,7 +172,7 @@ $utopia->get('/console/tasks')
});
$utopia->get('/console/database')
->desc('Platform console project settings')
->groups(['web', 'console'])
->label('permission', 'public')
->label('scope', 'console')
->action(function () use ($layout) {
@@ -184,7 +184,7 @@ $utopia->get('/console/database')
});
$utopia->get('/console/database/collection')
->desc('Platform console project database collection')
->groups(['web', 'console'])
->label('permission', 'public')
->label('scope', 'console')
->param('id', '', function () { return new UID(); }, 'Collection unique ID.')
@@ -213,11 +213,10 @@ $utopia->get('/console/database/collection')
->addHeader('Expires', 0)
->addHeader('Pragma', 'no-cache')
;
});
$utopia->get('/console/database/document')
->desc('Platform console project database document')
->groups(['web', 'console'])
->label('permission', 'public')
->label('scope', 'console')
->param('collection', '', function () { return new UID(); }, 'Collection unique ID.')
@@ -247,7 +246,7 @@ $utopia->get('/console/database/document')
});
$utopia->get('/console/storage')
->desc('Platform console project settings')
->groups(['web', 'console'])
->label('permission', 'public')
->label('scope', 'console')
->action(function () use ($request, $layout) {
@@ -265,7 +264,7 @@ $utopia->get('/console/storage')
});
$utopia->get('/console/users')
->desc('Platform console project settings')
->groups(['web', 'console'])
->label('permission', 'public')
->label('scope', 'console')
->action(function () use ($layout) {
@@ -279,7 +278,7 @@ $utopia->get('/console/users')
});
$utopia->get('/console/users/user')
->desc('Platform console project user')
->groups(['web', 'console'])
->label('permission', 'public')
->label('scope', 'console')
->action(function () use ($layout) {
@@ -291,7 +290,7 @@ $utopia->get('/console/users/user')
});
$utopia->get('/console/users/teams/team')
->desc('Platform console project team')
->groups(['web', 'console'])
->label('permission', 'public')
->label('scope', 'console')
->action(function () use ($layout) {
+63 -65
View File
@@ -1,7 +1,5 @@
<?php
include_once __DIR__ . '/../shared/web.php';
global $utopia, $response, $request, $layout;
use Utopia\View;
@@ -9,27 +7,30 @@ use Utopia\Config\Config;
use Utopia\Validator\WhiteList;
use Utopia\Validator\Range;
$header = new View(__DIR__.'/../../views/home/comps/header.phtml');
$footer = new View(__DIR__.'/../../views/home/comps/footer.phtml');
$utopia->init(function () use ($layout) {
$header = new View(__DIR__.'/../../views/home/comps/header.phtml');
$footer = new View(__DIR__.'/../../views/home/comps/footer.phtml');
$footer
->setParam('version', Config::getParam('version'))
;
$footer
->setParam('version', Config::getParam('version'))
;
$layout
->setParam('title', APP_NAME)
->setParam('description', '')
->setParam('class', 'home')
->setParam('platforms', Config::getParam('platforms'))
->setParam('header', [$header])
->setParam('footer', [$footer])
;
$layout
->setParam('title', APP_NAME)
->setParam('description', '')
->setParam('class', 'home')
->setParam('platforms', Config::getParam('platforms'))
->setParam('header', [$header])
->setParam('footer', [$footer])
;
}, 'home');
$utopia->shutdown(function () use ($response, $layout) {
$response->send($layout->render());
});
}, 'home');
$utopia->get('/')
->groups(['web', 'home'])
->label('permission', 'public')
->label('scope', 'home')
->action(
@@ -39,7 +40,7 @@ $utopia->get('/')
);
$utopia->get('/auth/signin')
->desc('Login page')
->groups(['web', 'home'])
->label('permission', 'public')
->label('scope', 'home')
->action(function () use ($layout) {
@@ -51,7 +52,7 @@ $utopia->get('/auth/signin')
});
$utopia->get('/auth/signup')
->desc('Registration page')
->groups(['web', 'home'])
->label('permission', 'public')
->label('scope', 'home')
->action(function () use ($layout) {
@@ -63,7 +64,7 @@ $utopia->get('/auth/signup')
});
$utopia->get('/auth/recovery')
->desc('Password recovery page')
->groups(['web', 'home'])
->label('permission', 'public')
->label('scope', 'home')
->action(function () use ($request, $layout) {
@@ -75,7 +76,7 @@ $utopia->get('/auth/recovery')
});
$utopia->get('/auth/confirm')
->desc('Account confirmation page')
->groups(['web', 'home'])
->label('permission', 'public')
->label('scope', 'home')
->action(function () use ($layout) {
@@ -87,7 +88,7 @@ $utopia->get('/auth/confirm')
});
$utopia->get('/auth/join')
->desc('Account team join page')
->groups(['web', 'home'])
->label('permission', 'public')
->label('scope', 'home')
->action(function () use ($layout) {
@@ -99,7 +100,7 @@ $utopia->get('/auth/join')
});
$utopia->get('/auth/recovery/reset')
->desc('Password recovery page')
->groups(['web', 'home'])
->label('permission', 'public')
->label('scope', 'home')
->action(function () use ($layout) {
@@ -112,7 +113,7 @@ $utopia->get('/auth/recovery/reset')
$utopia->get('/auth/oauth2/success')
->desc('Registration page')
->groups(['web', 'home'])
->label('permission', 'public')
->label('scope', 'home')
->action(function () use ($layout) {
@@ -127,7 +128,7 @@ $utopia->get('/auth/oauth2/success')
});
$utopia->get('/auth/oauth2/failure')
->desc('Registration page')
->groups(['web', 'home'])
->label('permission', 'public')
->label('scope', 'home')
->action(function () use ($layout) {
@@ -142,7 +143,7 @@ $utopia->get('/auth/oauth2/failure')
});
$utopia->get('/error/:code')
->desc('Error page')
->groups(['web', 'home'])
->label('permission', 'public')
->label('scope', 'home')
->param('code', null, new \Utopia\Validator\Numeric(), 'Valid status code number', false)
@@ -159,6 +160,7 @@ $utopia->get('/error/:code')
});
$utopia->get('/open-api-2.json')
->groups(['web', 'home'])
->label('scope', 'public')
->label('docs', false)
->param('platform', APP_PLATFORM_CLIENT, function () {return new WhiteList([APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER, APP_PLATFORM_CONSOLE]);}, 'Choose target platform.', true)
@@ -183,11 +185,11 @@ $utopia->get('/open-api-2.json')
}
foreach ($services as $service) { /* @noinspection PhpIncludeInspection */
if($tests && !isset($service['tests'])) {
if ($tests && !isset($service['tests'])) {
continue;
}
if($tests && !$service['tests']) {
if ($tests && !$service['tests']) {
continue;
}
@@ -303,27 +305,27 @@ $utopia->get('/open-api-2.json')
'securityDefinitions' => $keys[$platform],
'paths' => [],
'definitions' => [
// 'Pet' => [
// 'required' => ['id', 'name'],
// 'properties' => [
// 'id' => [
// 'type' => 'integer',
// 'format' => 'int64',
// ],
// 'name' => [
// 'type' => 'string',
// ],
// 'tag' => [
// 'type' => 'string',
// ],
// ],
// ],
// 'Pets' => array(
// 'type' => 'array',
// 'items' => array(
// '$ref' => '#/definitions/Pet',
// ),
// ),
'Pet' => [
'required' => ['id', 'name'],
'properties' => [
'id' => [
'type' => 'integer',
'format' => 'int64',
],
'name' => [
'type' => 'string',
],
'tag' => [
'type' => 'string',
],
],
],
'Pets' => array(
'type' => 'array',
'items' => array(
'$ref' => '#/definitions/Pet',
),
),
'Error' => array(
'required' => array(
0 => 'code',
@@ -347,19 +349,19 @@ $utopia->get('/open-api-2.json')
];
if ($extensions) {
if(isset($output['securityDefinitions']['Project'])) {
if (isset($output['securityDefinitions']['Project'])) {
$output['securityDefinitions']['Project']['extensions'] = ['demo' => '5df5acd0d48c2'];
}
if(isset($output['securityDefinitions']['Key'])) {
if (isset($output['securityDefinitions']['Key'])) {
$output['securityDefinitions']['Key']['extensions'] = ['demo' => '919c2d18fb5d4...a2ae413da83346ad2'];
}
if(isset($output['securityDefinitions']['Locale'])) {
if (isset($output['securityDefinitions']['Locale'])) {
$output['securityDefinitions']['Locale']['extensions'] = ['demo' => 'en'];
}
if(isset($output['securityDefinitions']['Mode'])) {
if (isset($output['securityDefinitions']['Mode'])) {
$output['securityDefinitions']['Mode']['extensions'] = ['demo' => ''];
}
}
@@ -374,7 +376,7 @@ $utopia->get('/open-api-2.json')
continue;
}
if($platform !== APP_PLATFORM_CONSOLE && !\in_array($platforms[$platform], $route->getLabel('sdk.platform', []))) {
if ($platform !== APP_PLATFORM_CONSOLE && !\in_array($platforms[$platform], $route->getLabel('sdk.platform', []))) {
continue;
}
@@ -396,14 +398,14 @@ $utopia->get('/open-api-2.json')
'tags' => [$route->getLabel('sdk.namespace', 'default')],
'description' => ($desc) ? \file_get_contents($desc) : '',
// 'responses' => [
// 200 => [
// 'description' => 'An paged array of pets',
// 'schema' => [
// '$ref' => '#/definitions/Pet',
// ],
// ],
// ],
'responses' => [
200 => [
'description' => 'An paged array of pets',
'schema' => [
'$ref' => '#/definitions/Pet',
],
],
],
];
if ($extensions) {
@@ -546,10 +548,6 @@ $utopia->get('/open-api-2.json')
}
}
/*foreach ($consoleDB->getMocks() as $mock) {
var_dump($mock['name']);
}*/
\ksort($output['paths']);
$response
+1 -1
View File
@@ -33,7 +33,7 @@
"appwrite/php-clamav": "1.0.*",
"utopia-php/framework": "0.3.5",
"utopia-php/framework": "0.4.0",
"utopia-php/abuse": "0.2.*",
"utopia-php/audit": "0.3.*",
"utopia-php/cache": "0.2.*",
Generated
+17 -17
View File
@@ -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": "b2678886d7c1aa5f4edfdd1ad1558f14",
"content-hash": "7f6cbe77fe2e0f8bdff33c37a4d9ca11",
"packages": [
{
"name": "appwrite/php-clamav",
@@ -459,24 +459,24 @@
"source": {
"type": "git",
"url": "https://github.com/guzzle/promises.git",
"reference": "89b1a76b7fda5853401297dc4b2a093cba1fda23"
"reference": "bbf3b200bc83c1e9298580a9f99b9be248543467"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/guzzle/promises/zipball/89b1a76b7fda5853401297dc4b2a093cba1fda23",
"reference": "89b1a76b7fda5853401297dc4b2a093cba1fda23",
"url": "https://api.github.com/repos/guzzle/promises/zipball/bbf3b200bc83c1e9298580a9f99b9be248543467",
"reference": "bbf3b200bc83c1e9298580a9f99b9be248543467",
"shasum": ""
},
"require": {
"php": ">=5.6"
"php": ">=5.5"
},
"require-dev": {
"phpunit/phpunit": "^5.7.27 || ^7.5"
"phpunit/phpunit": "^4.8.36 || ^5.7.27 || ^7.5"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.4-dev"
"dev-master": "1.3-dev"
}
},
"autoload": {
@@ -502,7 +502,7 @@
"keywords": [
"promise"
],
"time": "2020-02-15T23:33:03+00:00"
"time": "2020-06-21T23:10:57+00:00"
},
{
"name": "guzzlehttp/psr7",
@@ -1596,16 +1596,16 @@
},
{
"name": "utopia-php/framework",
"version": "0.3.5",
"version": "0.4.0",
"source": {
"type": "git",
"url": "https://github.com/utopia-php/framework.git",
"reference": "ca2ebe37936983d786f57bae8ee6e006299f4942"
"reference": "30aeb2aeecf8ea2ab83242efad0f5f9fab8d4be5"
},
"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/30aeb2aeecf8ea2ab83242efad0f5f9fab8d4be5",
"reference": "30aeb2aeecf8ea2ab83242efad0f5f9fab8d4be5",
"shasum": ""
},
"require": {
@@ -1636,7 +1636,7 @@
"php",
"upf"
],
"time": "2020-06-20T11:33:46+00:00"
"time": "2020-06-25T18:21:48+00:00"
},
{
"name": "utopia-php/locale",
@@ -3363,12 +3363,12 @@
"source": {
"type": "git",
"url": "https://github.com/twigphp/Twig.git",
"reference": "3beabd64bdc91558b41f140cc4b14925f0416cb2"
"reference": "f32950c872a995a93807909bab69387f47afaa25"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/twigphp/Twig/zipball/3beabd64bdc91558b41f140cc4b14925f0416cb2",
"reference": "3beabd64bdc91558b41f140cc4b14925f0416cb2",
"url": "https://api.github.com/repos/twigphp/Twig/zipball/f32950c872a995a93807909bab69387f47afaa25",
"reference": "f32950c872a995a93807909bab69387f47afaa25",
"shasum": ""
},
"require": {
@@ -3420,7 +3420,7 @@
"keywords": [
"templating"
],
"time": "2020-06-08T10:41:25+00:00"
"time": "2020-06-22T15:25:21+00:00"
},
{
"name": "webmozart/assert",
@@ -1,3 +1,3 @@
Use this endpoint to send a verification message to your user email address to confirm they are the valid owners of that address. Both the **userId** and **secret** arguments will be passed as query parameters to the URL you have provider to be attached to the verification email. The provided URL should redirect the user back for your app and allow you to complete the verification process by verifying both the **userId** and **secret** parameters. Learn more about how to [complete the verification process](/docs/client/account#updateAccountVerification).
Use this endpoint to send a verification message to your user email address to confirm they are the valid owners of that address. Both the **userId** and **secret** arguments will be passed as query parameters to the URL you have provided to be attached to the verification email. The provided URL should redirect the user back to your app and allow you to complete the verification process by verifying both the **userId** and **secret** parameters. Learn more about how to [complete the verification process](/docs/client/account#updateAccountVerification).
Please note that in order to avoid a [Redirect Attack](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md) the only valid redirect URLs are the ones from domains you have set when adding your platforms in the console interface.
Please note that in order to avoid a [Redirect Attack](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md), the only valid redirect URLs are the ones from domains you have set when adding your platforms in the console interface.
+1 -12
View File
@@ -16,19 +16,8 @@ ini_set('display_errors', 0);
// error_reporting(E_ALL);
$path = (isset($_GET['q'])) ? explode('/', $_GET['q']) : [];
$domain = (isset($_SERVER['HTTP_HOST'])) ? $_SERVER['HTTP_HOST'] : '';
array_shift($path);
$version = array_shift($path);
switch ($version) { // Switch between API version
case 'v1':
$service = $version . '/' . array_shift($path);
include __DIR__ . '/../app/app.php';
break;
case 'console':
default:
$service = $version . '/';
include __DIR__ . '/../app/app.php';
break;
}
include __DIR__ . '/../app/app.php';
+1 -1
View File
@@ -320,7 +320,7 @@
var _date = function (format, timestamp) {
jsdate = (timestamp === undefined ? new Date() // Not provided
: (timestamp instanceof Date) ? new Date(timestamp) // JS Date()
: new Date(timestamp * 1000) // UNIX timestamp (auto-convert to int)
: new Date(timestamp * 1000) // Unix timestamp (auto-convert to int)
)
return format.replace(formatChr, formatChrCb)
}
+8 -8
View File
@@ -44,7 +44,7 @@ abstract class OAuth2
$this->appSecret = $appSecret;
$this->callback = $callback;
$this->state = $state;
foreach($scopes as $scope) {
foreach ($scopes as $scope) {
$this->addScope($scope);
}
}
@@ -89,21 +89,21 @@ abstract class OAuth2
/**
* @param $scope
*
*
* @return $this
*/
protected function addScope(string $scope):OAuth2
{
// Add a scope to the scopes array if it isn't already present
if (!\in_array($scope, $this->scopes)){
$this->scopes[] = $scope;
// Add a scope to the scopes array if it isn't already present
if (!\in_array($scope, $this->scopes)) {
$this->scopes[] = $scope;
}
return $this;
}
/**
* @return array
*/
/**
* @return array
*/
protected function getScopes():array
{
return $this->scopes;
+5 -4
View File
@@ -19,7 +19,7 @@ class Apple extends OAuth2
* @var array
*/
protected $scopes = [
"name",
"name",
"email"
];
@@ -166,7 +166,9 @@ class Apple extends OAuth2
$success = \openssl_sign($payload, $signature, $pkey, OPENSSL_ALGO_SHA256);
if (!$success) return '';
if (!$success) {
return '';
}
return $payload.'.'.$this->encode($this->fromDER($signature, 64));
}
@@ -205,8 +207,7 @@ class Apple extends OAuth2
if ('81' === \mb_substr($hex, 2, 2, '8bit')) { // LENGTH > 128
$hex = \mb_substr($hex, 6, null, '8bit');
}
else {
} else {
$hex = \mb_substr($hex, 4, null, '8bit');
}
if ('02' !== \mb_substr($hex, 0, 2, '8bit')) { // INTEGER
+1 -1
View File
@@ -58,7 +58,7 @@ class Facebook extends OAuth2
'redirect_uri' => $this->callback,
'client_secret' => $this->appSecret,
'code' => $code
])
])
);
$accessToken = \json_decode($accessToken, true);
-1
View File
@@ -37,7 +37,6 @@ class Github extends OAuth2
'scope' => \implode(' ', $this->getScopes()),
'state' => \json_encode($this->state)
]);
}
/**
+1 -1
View File
@@ -4,7 +4,7 @@ namespace Appwrite\Auth\OAuth2;
use Appwrite\Auth\OAuth2;
// Reference Material
// Reference Material
// https://docs.gitlab.com/ee/api/oauth2.html
class Gitlab extends OAuth2
+1 -1
View File
@@ -4,7 +4,7 @@ namespace Appwrite\Auth\OAuth2;
use Appwrite\Auth\OAuth2;
// Reference Material
// Reference Material
// https://developers.google.com/oauthplayground/
// https://developers.google.com/identity/protocols/OAuth2
// https://developers.google.com/identity/protocols/OAuth2WebServer
+1 -1
View File
@@ -19,7 +19,7 @@ class Microsoft extends OAuth2
* @var array
*/
protected $scopes = [
'offline_access',
'offline_access',
'user.read'
];
+1 -1
View File
@@ -134,4 +134,4 @@ class Mock extends OAuth2
return $this->user;
}
}
}
+2 -3
View File
@@ -15,8 +15,8 @@ class Slack extends OAuth2
* @var array
*/
protected $scopes = [
'identity.avatar',
'identity.basic',
'identity.avatar',
'identity.basic',
'identity.email',
'identity.team'
];
@@ -125,7 +125,6 @@ class Slack extends OAuth2
*/
protected function getUser(string $accessToken):array
{
if (empty($this->user)) {
// https://api.slack.com/methods/users.identity
$user = $this->request(
+5 -2
View File
@@ -137,8 +137,11 @@ class Spotify extends OAuth2
protected function getUser(string $accessToken)
{
if (empty($this->user)) {
$this->user = \json_decode($this->request('GET',
$this->resourceEndpoint . "me", ['Authorization: Bearer '.\urlencode($accessToken)]), true);
$this->user = \json_decode($this->request(
'GET',
$this->resourceEndpoint . "me",
['Authorization: Bearer '.\urlencode($accessToken)]
), true);
}
return $this->user;
+5 -2
View File
@@ -139,8 +139,11 @@ class Twitch extends OAuth2
protected function getUser(string $accessToken)
{
if (empty($this->user)) {
$this->user = \json_decode($this->request('GET',
$this->resourceEndpoint, ['Authorization: Bearer '.\urlencode($accessToken)]), true)['data']['0'];
$this->user = \json_decode($this->request(
'GET',
$this->resourceEndpoint,
['Authorization: Bearer '.\urlencode($accessToken)]
), true)['data']['0'];
}
return $this->user;
+5 -2
View File
@@ -153,8 +153,11 @@ class Yahoo extends OAuth2
protected function getUser(string $accessToken)
{
if (empty($this->user)) {
$this->user = \json_decode($this->request('GET',
$this->resourceEndpoint, ['Authorization: Bearer '.\urlencode($accessToken)]), true);
$this->user = \json_decode($this->request(
'GET',
$this->resourceEndpoint,
['Authorization: Bearer '.\urlencode($accessToken)]
), true);
}
return $this->user;
+1 -1
View File
@@ -127,7 +127,7 @@ abstract class Adapter
/**
* Last Modified.
*
* Return unix timestamp of last time a node queried in corrent session has been changed
* Return Unix timestamp of last time a node queried in corrent session has been changed
*
* @return int
*/
+4 -4
View File
@@ -175,7 +175,7 @@ class MySQL extends Adapter
$result = $st->fetch();
if($result && isset($result['signature'])) {
if ($result && isset($result['signature'])) {
$oldSignature = $result['signature'];
if ($signature === $oldSignature) {
@@ -187,14 +187,14 @@ class MySQL extends Adapter
/**
* Check Unique Keys
*/
foreach($unique as $key => $value) {
foreach ($unique as $key => $value) {
$st = $this->getPDO()->prepare('INSERT INTO `'.$this->getNamespace().'.database.unique`
SET `key` = :key;
');
$st->bindValue(':key', \md5($data['$collection'].':'.$key.'='.$value), PDO::PARAM_STR);
if(!$st->execute()) {
if (!$st->execute()) {
throw new Duplicate('Duplicated Property: '.$key.'='.$value);
}
}
@@ -774,7 +774,7 @@ class MySQL extends Adapter
/**
* Last Modified.
*
* Return unix timestamp of last time a node queried in corrent session has been changed
* Return Unix timestamp of last time a node queried in corrent session has been changed
*
* @return int
*/
+1 -1
View File
@@ -221,7 +221,7 @@ class Redis extends Adapter
/**
* Last Modified.
*
* Return unix timestamp of last time a node queried in current session has been changed
* Return Unix timestamp of last time a node queried in current session has been changed
*
* @return int
*/
+1 -1
View File
@@ -367,7 +367,7 @@ class Database
/**
* Get Last Modified.
*
* Return unix timestamp of last time a node queried in current session has been changed
* Return Unix timestamp of last time a node queried in current session has been changed
*
* @return int
*/
+15 -3
View File
@@ -25,11 +25,11 @@ class Document extends ArrayObject
{
foreach ($input as $key => &$value) {
if (\is_array($value)) {
if (isset($value['$id']) || isset($value['$collection'])) {
if ((isset($value['$id']) || isset($value['$collection'])) && (!$value instanceof self)) {
$input[$key] = new self($value);
} else {
foreach ($value as $childKey => $child) {
if (isset($child['$id']) || isset($child['$collection'])) {
if ((isset($child['$id']) || isset($child['$collection'])) && (!$child instanceof self)) {
$value[$childKey] = new self($child);
}
}
@@ -134,7 +134,7 @@ class Document extends ArrayObject
*/
public function removeAttribute($key)
{
if(isset($this[$key])) {
if (isset($this[$key])) {
unset($this[$key]);
}
@@ -193,6 +193,18 @@ class Document extends ArrayObject
return empty($this->getId());
}
/**
* Checks if a document key is set.
*
* @param $key
*
* @return bool
*/
public function isSet($key)
{
return isset($this[$key]);
}
/**
* Get Array Copy.
*
@@ -111,7 +111,7 @@ class Authorization extends Validator
/**
* Default value in case we need
* to reset Authorization status
*
*
* @var bool
*/
public static $statusDefault = true;
@@ -119,9 +119,10 @@ class Authorization extends Validator
/**
* Change default status.
* This will be used for the
* value set on the self::reset() method
* value set on the self::reset() method
*/
public static function setDefaultStatus($status) {
public static function setDefaultStatus($status)
{
self::$statusDefault = $status;
self::$status = $status;
}
@@ -60,19 +60,19 @@ class DocumentId extends Validator
{
$document = $this->database->getDocument($id);
if(!$document) {
if (!$document) {
return false;
}
if(!$document instanceof Document) {
if (!$document instanceof Document) {
return false;
}
if(!$document->getId()) {
if (!$document->getId()) {
return false;
}
if($document->getCollection() !== $this->collection) {
if ($document->getCollection() !== $this->collection) {
return false;
}
+1 -1
View File
@@ -34,7 +34,7 @@ class Key extends Validator
*/
public function isValid($value)
{
if(!\is_string($value)) {
if (!\is_string($value)) {
return false;
}
+4 -4
View File
@@ -26,7 +26,7 @@ class CNAME extends Validator
/**
* Check if CNAME record target value matches selected target
*
*
* @param string $domain
*
* @return bool
@@ -39,12 +39,12 @@ class CNAME extends Validator
return false;
}
if(!$records || !\is_array($records)) {
if (!$records || !\is_array($records)) {
return false;
}
foreach($records as $record) {
if(isset($record['target']) && $record['target'] === $this->target) {
foreach ($records as $record) {
if (isset($record['target']) && $record['target'] === $this->target) {
return true;
}
}
+5 -5
View File
@@ -56,7 +56,7 @@ class Origin extends Validator
*/
public function __construct($platforms)
{
foreach($platforms as $platform) {
foreach ($platforms as $platform) {
$type = (isset($platform['type'])) ? $platform['type'] : '';
switch ($type) {
@@ -81,7 +81,7 @@ class Origin extends Validator
public function getDescription()
{
if(!\array_key_exists($this->client, $this->platforms)) {
if (!\array_key_exists($this->client, $this->platforms)) {
return 'Unsupported platform';
}
@@ -92,7 +92,7 @@ class Origin extends Validator
/**
* Check if Origin has been whiltlisted
* for access to the API
*
*
* @param string $origin
*
* @return bool
@@ -105,11 +105,11 @@ class Origin extends Validator
$this->host = $host;
$this->client = $scheme;
if(empty($host)) {
if (empty($host)) {
return true;
}
if(\in_array($host, $this->clients)) {
if (\in_array($host, $this->clients)) {
return true;
}
+4 -5
View File
@@ -157,16 +157,15 @@ class Local extends Device
*/
public function delete(string $path, bool $recursive = false):bool
{
if(\is_dir($path) && $recursive) {
if (\is_dir($path) && $recursive) {
$files = \glob($path.'*', GLOB_MARK); // GLOB_MARK adds a slash to directories returned
foreach($files as $file) {
$this->delete($file, true);
foreach ($files as $file) {
$this->delete($file, true);
}
\rmdir($path);
}
elseif(\is_file($path)) {
} elseif (\is_file($path)) {
return \unlink($path);
}
+1 -1
View File
@@ -78,7 +78,7 @@ class Storage
*
* @return string
*/
static public function human($bytes, $decimals = 2)
public static function human($bytes, $decimals = 2)
{
$units = array('B','kB','MB','GB','TB','PB','EB','ZB','YB');
$step = 1024;
+1 -1
View File
@@ -64,7 +64,7 @@ class FileType extends Validator
*/
public function isValid($path)
{
if(!\is_readable($path)) {
if (!\is_readable($path)) {
return false;
}
+17 -17
View File
@@ -6,14 +6,14 @@ class URL
{
/**
* Parse URL
*
*
* Take a URL string and split it to array parts
*
*
* @param string $url
*
*
* @return array
*/
static public function parse(string $url):array
public static function parse(string $url):array
{
$default = [
'scheme' => '',
@@ -31,15 +31,15 @@ class URL
/**
* Un-Parse URL
*
*
* Take URL parts and combine them to a valid string
*
*
* @param array $url
* @param array $ommit
*
*
* @return string
*/
static public function unparse(array $url, array $ommit = []):string
public static function unparse(array $url, array $ommit = []):string
{
if (isset($url['path']) && \mb_substr($url['path'], 0, 1) !== '/') {
$url['path'] = '/'.$url['path'];
@@ -78,14 +78,14 @@ class URL
/**
* Parse Query String
*
*
* Convert query string to array
*
*
* @param string $query
*
*
* @return array
*/
static public function parseQuery(string $query):array
public static function parseQuery(string $query):array
{
\parse_str($query, $result);
@@ -94,15 +94,15 @@ class URL
/**
* Un-Parse Query String
*
*
* Convert query string array to string
*
*
* @param string $query
*
*
* @return array
*/
static public function unparseQuery(array $query):string
public static function unparseQuery(array $query):string
{
return \http_build_query($query);
}
}
}
+46 -18
View File
@@ -8,39 +8,47 @@ use Appwrite\Utopia\Response\Model;
use Appwrite\Utopia\Response\Model\Error;
use Appwrite\Utopia\Response\Model\ErrorDev;
use Appwrite\Utopia\Response\Model\User;
use Appwrite\Utopia\Response\Model\Session;
use Appwrite\Utopia\Response\Model\Team;
use Appwrite\Utopia\Response\Model\TeamList;
use Appwrite\Utopia\Response\Model\Locale;
use Appwrite\Utopia\Response\Model\Membership;
use Appwrite\Utopia\Response\Model\MembershipList;
use Utopia\Response as UtopiaResponse;
class Response extends UtopiaResponse
{
// General
const MODEL_LOG = 'log';
const MODEL_LOG = 'log'; // - Missing
const MODEL_ERROR = 'error';
const MODEL_ERROR_DEV = 'errorDev';
const MODEL_BASE_LIST = 'baseList';
// Users
const MODEL_USER = 'user';
const MODEL_SESSION = 'session';
const MODEL_TOKEN = 'token';
const MODEL_TOKEN = 'token'; // - Missing
// Database
const MODEL_COLLECTION = 'collection';
const MODEL_COLLECTION = 'collection'; // - Missing
// Locale
const MODEL_LOCALE = 'locale';
const MODEL_COUNTRY = 'country';
const MODEL_CONTINENT = 'continent';
const MODEL_CURRENCY = 'currency';
const MODEL_LANGUAGE = 'langauge';
const MODEL_PHONE = 'phone';
const MODEL_COUNTRY = 'country'; // - Missing
const MODEL_CONTINENT = 'continent'; // - Missing
const MODEL_CURRENCY = 'currency'; // - Missing
const MODEL_LANGUAGE = 'langauge'; // - Missing
const MODEL_PHONE = 'phone'; // - Missing
// Storage
const MODEL_FILE = 'file';
const MODEL_BUCKET = 'bucket';
const MODEL_FILE = 'file'; // - Missing
const MODEL_BUCKET = 'bucket'; // - Missing
// Teams
const MODEL_TEAM = 'team';
const MODEL_MEMBERSHIP = 'membership';
const MODEL_TEAM_LIST = 'teamList';
const MODEL_MEMBERSHIP = 'membership'; // - Missing
const MODEL_MEMBERSHIP_LIST = 'membershipList'; // - Missing
public function __construct()
{
@@ -48,7 +56,12 @@ class Response extends UtopiaResponse
->setModel(new Error())
->setModel(new ErrorDev())
->setModel(new User())
->setModel(new Session())
->setModel(new Locale())
->setModel(new Team())
->setModel(new TeamList())
->setModel(new Membership())
->setModel(new MembershipList())
;
}
@@ -94,29 +107,44 @@ class Response extends UtopiaResponse
*/
public function dynamic(Document $document, string $model)
{
$data = $document->getArrayCopy();
return $this->json($this->output($document, $model));
}
/**
* Generate valid response object from document data
*/
protected function output(Document $document, string $model): array
{
$data = $document;
$model = $this->getModel($model);
$output = [];
foreach($model->getRules() as $key => $rule) {
if(!isset($data[$key])) {
if(!$document->isSet($key)) {
if(!is_null($rule['default'])) {
$data[$key] = $rule['default'];
$document->setAttribute($key, $rule['default']);
}
else {
throw new Exception('Missing response key: '.$key);
}
}
if($rule['array'] && !is_array($data[$key])) {
throw new Exception($key.' must be an array of '.$rule['type'].' types');
if($rule['array']) {
if(!is_array($data[$key])) {
throw new Exception($key.' must be an array of '.$rule['type'].' types');
}
foreach ($data[$key] as &$item) {
if(array_key_exists($rule['type'], $this->models) && $item instanceof Document) {
$item = $this->output($item, $rule['type']);
}
}
}
$output[$key] = $data[$key];
}
return $this->json($output);
//return $this->yaml($output);
return $output;
}
/**
@@ -0,0 +1,40 @@
<?php
namespace Appwrite\Utopia\Response\Model;
use Appwrite\Utopia\Response;
use Appwrite\Utopia\Response\Model;
abstract class BaseList extends Model
{
public function __construct()
{
$this
->addRule('sum', [
'type' => 'integer',
'description' => 'Total sum of items in the list.',
'example' => '5',
])
;
}
/**
* Get Name
*
* @return string
*/
public function getName():string
{
return 'Base List';
}
/**
* Get Collection
*
* @return string
*/
public function getType():string
{
return Response::MODEL_BASE_LIST;
}
}
@@ -0,0 +1,84 @@
<?php
namespace Appwrite\Utopia\Response\Model;
use Appwrite\Utopia\Response;
use Appwrite\Utopia\Response\Model;
class Membership extends Model
{
public function __construct()
{
$this
->addRule('$id', [
'type' => 'string',
'description' => 'Membership ID.',
'example' => '5e5ea5c16897e',
])
->addRule('userId', [
'type' => 'string',
'description' => 'User ID.',
'example' => '5e5ea5c16897e',
])
->addRule('teamId', [
'type' => 'string',
'description' => 'Team ID.',
'example' => '5e5ea5c16897e',
])
->addRule('name', [
'type' => 'string',
'description' => 'User name.',
'default' => '',
'example' => 'VIP',
])
->addRule('email', [
'type' => 'string',
'description' => 'User email address.',
'default' => '',
'example' => 'john@appwrite.io',
])
->addRule('invited', [
'type' => 'integer',
'description' => 'Date, the user has been invited to join the team in Unix timestamp.',
'example' => 1592981250,
])
->addRule('joined', [
'type' => 'integer',
'description' => 'Date, the user has accepted the invitation to join the team in Unix timestamp.',
'example' => 1592981250,
])
->addRule('confirm', [
'type' => 'boolean',
'description' => 'User confirmation status, true if the user has joined the team or false otherwise.',
'example' => false,
])
->addRule('roles', [
'type' => 'string',
'description' => 'User list of roles',
'default' => [],
'example' => [],
'array' => true,
])
;
}
/**
* Get Name
*
* @return string
*/
public function getName():string
{
return 'Membership';
}
/**
* Get Collection
*
* @return string
*/
public function getType():string
{
return Response::MODEL_MEMBERSHIP;
}
}
@@ -0,0 +1,41 @@
<?php
namespace Appwrite\Utopia\Response\Model;
use Appwrite\Utopia\Response;
class MembershipList extends BaseList
{
public function __construct()
{
parent::__construct();
$this
->addRule('memberships', [
'type' => Response::MODEL_MEMBERSHIP,
'description' => 'List of memberships.',
'example' => [],
'array' => true,
])
;
}
/**
* Get Name
*
* @return string
*/
public function getName():string
{
return 'Membership List';
}
/**
* Get Collection
*
* @return string
*/
public function getType():string
{
return Response::MODEL_MEMBERSHIP_LIST;
}
}
+18 -1
View File
@@ -9,6 +9,23 @@ class Session extends Model
{
public function __construct()
{
$this
->addRule('$id', [
'type' => 'string',
'description' => 'Session ID.',
'example' => '5e5ea5c16897e',
])
->addRule('expire', [
'type' => 'string',
'description' => 'Session expiration date in Unix timestamp.',
'example' => 1592981250,
])
->addRule('ip', [
'type' => 'string',
'description' => 'IP session in use when the session was created.',
'example' => '127.0.0.1',
])
;
}
/**
@@ -28,6 +45,6 @@ class Session extends Model
*/
public function getType():string
{
return Response::MODEL_LOCALE;
return Response::MODEL_SESSION;
}
}
@@ -0,0 +1,56 @@
<?php
namespace Appwrite\Utopia\Response\Model;
use Appwrite\Utopia\Response;
use Appwrite\Utopia\Response\Model;
class Team extends Model
{
public function __construct()
{
$this
->addRule('$id', [
'type' => 'string',
'description' => 'Team ID.',
'example' => '5e5ea5c16897e',
])
->addRule('name', [
'type' => 'string',
'description' => 'Team name.',
'default' => '',
'example' => 'VIP',
])
->addRule('dateCreated', [
'type' => 'integer',
'description' => 'Team creation date in Unix timestamp.',
'example' => 1592981250,
])
->addRule('sum', [ // TODO change key name?
'type' => 'integer',
'description' => 'Total sum of team members.',
'example' => 7,
])
;
}
/**
* Get Name
*
* @return string
*/
public function getName():string
{
return 'Team';
}
/**
* Get Collection
*
* @return string
*/
public function getType():string
{
return Response::MODEL_TEAM;
}
}
@@ -0,0 +1,41 @@
<?php
namespace Appwrite\Utopia\Response\Model;
use Appwrite\Utopia\Response;
class TeamList extends BaseList
{
public function __construct()
{
parent::__construct();
$this
->addRule('teams', [
'type' => Response::MODEL_TEAM,
'description' => 'List of teams.',
'example' => [],
'array' => true,
])
;
}
/**
* Get Name
*
* @return string
*/
public function getName():string
{
return 'Team List';
}
/**
* Get Collection
*
* @return string
*/
public function getType():string
{
return Response::MODEL_TEAM_LIST;
}
}
+2 -3
View File
@@ -23,9 +23,8 @@ class User extends Model
])
->addRule('registration', [
'type' => 'integer',
'description' => 'User registration date in unix timestamp.',
'default' => false,
'example' => true,
'description' => 'User registration date in Unix timestamp.',
'example' => 1592981250,
])
->addRule('status', [
'type' => 'integer',
@@ -173,7 +173,7 @@ class HealthCustomClientTest extends Scope
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertIsInt($response['body']['size']);
$this->assertLessThan(100, $response['body']['size']);
$this->assertLessThan(120, $response['body']['size']);
/**
* Test for FAILURE