1
0
Fork 0
mirror of synced 2024-06-29 11:40:45 +12:00

Merge branch 'feat-storage-buckets' into feat-sb-delete

This commit is contained in:
Damodar Lohani 2021-07-28 15:33:10 +05:45
commit f9df66b925
39 changed files with 675 additions and 674 deletions

View file

@ -1,3 +1,11 @@
# Version 0.9.2
## Bugs
- Fixed JWT session validation (#1408)
- Fixed passing valid JWT session to Cloud Functions (#1421)
- Fixed race condition when uploading and extracting bigger Cloud Functions (#1419)
# Version 0.9.1
## Bugs

View file

@ -609,13 +609,13 @@ $collections = [
],
],
'indexes' => [
// [
// '$id' => '_key_provider_providerUid',
// 'type' => Database::INDEX_KEY,
// 'attributes' => ['provider', 'providerUid'],
// 'lengths' => [100, 100],
// 'orders' => [Database::ORDER_ASC, Database::ORDER_ASC],
// ]
[
'$id' => '_key_provider_providerUid',
'type' => Database::INDEX_KEY,
'attributes' => ['provider', 'providerUid'],
'lengths' => [100, 100],
'orders' => [Database::ORDER_ASC, Database::ORDER_ASC],
]
],
],

View file

@ -53,7 +53,7 @@ App::post('/v1/account')
->action(function ($email, $password, $name, $request, $response, $project, $dbForInternal, $audits) {
/** @var Utopia\Swoole\Request $request */
/** @var Appwrite\Utopia\Response $response */
/** @var Appwrite\Database\Document $project */
/** @var Utopia\Database\Document $project */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Appwrite\Event\Event $audits */
@ -119,7 +119,7 @@ App::post('/v1/account')
;
$response->setStatusCode(Response::STATUS_CODE_CREATED);
$response->dynamic2($user, Response::MODEL_USER);
$response->dynamic($user, Response::MODEL_USER);
});
App::post('/v1/account/sessions')
@ -229,7 +229,7 @@ App::post('/v1/account/sessions')
->setAttribute('countryName', $countryName)
;
$response->dynamic2($session, Response::MODEL_SESSION);
$response->dynamic($session, Response::MODEL_SESSION);
});
App::get('/v1/account/sessions/oauth2/:provider')
@ -256,7 +256,7 @@ App::get('/v1/account/sessions/oauth2/:provider')
->action(function ($provider, $success, $failure, $scopes, $request, $response, $project) {
/** @var Utopia\Swoole\Request $request */
/** @var Appwrite\Utopia\Response $response */
/** @var Appwrite\Database\Document $project */
/** @var Utopia\Database\Document $project */
$protocol = $request->getProtocol();
$callback = $protocol.'://'.$request->getHostname().'/v1/account/sessions/oauth2/callback/'.$provider.'/'.$project->getId();
@ -362,7 +362,7 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect')
->action(function ($provider, $code, $state, $request, $response, $project, $user, $dbForInternal, $geodb, $audits, $events) use ($oauthDefaultSuccess) {
/** @var Utopia\Swoole\Request $request */
/** @var Appwrite\Utopia\Response $response */
/** @var Appwrite\Database\Document $project */
/** @var Utopia\Database\Document $project */
/** @var Utopia\Database\Document $user */
/** @var Utopia\Database\Database $dbForInternal */
/** @var MaxMind\Db\Reader $geodb */
@ -546,7 +546,7 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect')
->setParam('data', ['provider' => $provider])
;
$events->setParam('eventData', $response->output2($session, Response::MODEL_SESSION));
$events->setParam('eventData', $response->output($session, Response::MODEL_SESSION));
if (!Config::getParam('domainVerification')) {
$response
@ -603,7 +603,7 @@ App::post('/v1/account/sessions/anonymous')
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Locale\Locale $locale */
/** @var Utopia\Database\Document $user */
/** @var Appwrite\Database\Document $project */
/** @var Utopia\Database\Document $project */
/** @var Utopia\Database\Database $dbForInternal */
/** @var MaxMind\Db\Reader $geodb */
/** @var Appwrite\Event\Event $audits */
@ -710,7 +710,7 @@ App::post('/v1/account/sessions/anonymous')
->setAttribute('countryName', $countryName)
;
$response->dynamic2($session, Response::MODEL_SESSION);
$response->dynamic($session, Response::MODEL_SESSION);
});
App::post('/v1/account/jwt')
@ -737,7 +737,7 @@ App::post('/v1/account/jwt')
$current = new Document();
foreach ($sessions as $session) {
/** @var Appwrite\Database\Document $session */
/** @var Utopia\Database\Document $session */
if ($session->getAttribute('secret') == Auth::hash(Auth::$secret)) { // If current session delete the cookies too
$current = $session;
@ -751,7 +751,7 @@ App::post('/v1/account/jwt')
$jwt = new JWT(App::getEnv('_APP_OPENSSL_KEY_V1'), 'HS256', 900, 10); // Instantiate with key, algo, maxAge and leeway.
$response->setStatusCode(Response::STATUS_CODE_CREATED);
$response->dynamic2(new Document(['jwt' => $jwt->encode([
$response->dynamic(new Document(['jwt' => $jwt->encode([
// 'uid' => 1,
// 'aud' => 'http://site.com',
// 'scopes' => ['user'],
@ -778,7 +778,7 @@ App::get('/v1/account')
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Document $user */
$response->dynamic2($user, Response::MODEL_USER);
$response->dynamic($user, Response::MODEL_USER);
});
App::get('/v1/account/prefs')
@ -800,7 +800,7 @@ App::get('/v1/account/prefs')
$prefs = $user->getAttribute('prefs', new \stdClass());
$response->dynamic2(new Document($prefs), Response::MODEL_PREFERENCES);
$response->dynamic(new Document($prefs), Response::MODEL_PREFERENCES);
});
App::get('/v1/account/sessions')
@ -837,7 +837,7 @@ App::get('/v1/account/sessions')
$sessions[$key] = $session;
}
$response->dynamic2(new Document([
$response->dynamic(new Document([
'sessions' => $sessions,
'sum' => count($sessions),
]), Response::MODEL_SESSION_LIST);
@ -861,7 +861,7 @@ App::get('/v1/account/logs')
->inject('dbForInternal')
->action(function ($response, $user, $locale, $geodb, $dbForInternal) {
/** @var Appwrite\Utopia\Response $response */
/** @var Appwrite\Database\Document $project */
/** @var Utopia\Database\Document $project */
/** @var Utopia\Database\Document $user */
/** @var Utopia\Locale\Locale $locale */
/** @var MaxMind\Db\Reader $geodb */
@ -914,7 +914,7 @@ App::get('/v1/account/logs')
}
$response->dynamic2(new Document(['logs' => $output]), Response::MODEL_LOG_LIST);
$response->dynamic(new Document(['logs' => $output]), Response::MODEL_LOG_LIST);
});
App::get('/v1/account/sessions/:sessionId')
@ -935,7 +935,7 @@ App::get('/v1/account/sessions/:sessionId')
->inject('dbForInternal')
->action(function ($sessionId, $response, $user, $locale, $dbForInternal) {
/** @var Appwrite\Utopia\Response $response */
/** @var Appwrite\Database\Document $user */
/** @var Utopia\Database\Document $user */
/** @var Utopia\Locale\Locale $locale */
/** @var Utopia\Database\Database $dbForInternal */
@ -956,7 +956,7 @@ App::get('/v1/account/sessions/:sessionId')
->setAttribute('countryName', $countryName)
;
return $response->dynamic2($session, Response::MODEL_SESSION);
return $response->dynamic($session, Response::MODEL_SESSION);
}
}
@ -994,7 +994,7 @@ App::patch('/v1/account/name')
->setParam('resource', 'users/'.$user->getId())
;
$response->dynamic2($user, Response::MODEL_USER);
$response->dynamic($user, Response::MODEL_USER);
});
App::patch('/v1/account/password')
@ -1037,7 +1037,7 @@ App::patch('/v1/account/password')
->setParam('resource', 'users/'.$user->getId())
;
$response->dynamic2($user, Response::MODEL_USER);
$response->dynamic($user, Response::MODEL_USER);
});
App::patch('/v1/account/email')
@ -1092,7 +1092,7 @@ App::patch('/v1/account/email')
->setParam('resource', 'users/'.$user->getId())
;
$response->dynamic2($user, Response::MODEL_USER);
$response->dynamic($user, Response::MODEL_USER);
});
App::patch('/v1/account/prefs')
@ -1125,7 +1125,7 @@ App::patch('/v1/account/prefs')
->setParam('resource', 'users/'.$user->getId())
;
$response->dynamic2($user, Response::MODEL_USER);
$response->dynamic($user, Response::MODEL_USER);
});
App::delete('/v1/account')
@ -1172,7 +1172,7 @@ App::delete('/v1/account')
;
$events
->setParam('eventData', $response->output2($user, Response::MODEL_USER))
->setParam('eventData', $response->output($user, Response::MODEL_USER))
;
if (!Config::getParam('domainVerification')) {
@ -1259,7 +1259,7 @@ App::delete('/v1/account/sessions/:sessionId')
$dbForInternal->updateDocument('users', $user->getId(), $user->setAttribute('sessions', $sessions));
$events
->setParam('eventData', $response->output2($session, Response::MODEL_SESSION))
->setParam('eventData', $response->output($session, Response::MODEL_SESSION))
;
return $response->noContent();
@ -1332,7 +1332,7 @@ App::delete('/v1/account/sessions')
$dbForInternal->updateDocument('users', $user->getId(), $user->setAttribute('sessions', []));
$events
->setParam('eventData', $response->output2(new Document([
->setParam('eventData', $response->output(new Document([
'sessions' => $sessions,
'sum' => count($sessions),
]), Response::MODEL_SESSION_LIST))
@ -1369,7 +1369,7 @@ App::post('/v1/account/recovery')
/** @var Utopia\Swoole\Request $request */
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Appwrite\Database\Document $project */
/** @var Utopia\Database\Document $project */
/** @var Utopia\Locale\Locale $locale */
/** @var Appwrite\Event\Event $mails */
/** @var Appwrite\Event\Event $audits */
@ -1443,7 +1443,7 @@ App::post('/v1/account/recovery')
$events
->setParam('eventData',
$response->output2($recovery->setAttribute('secret', $secret),
$response->output($recovery->setAttribute('secret', $secret),
Response::MODEL_TOKEN
))
;
@ -1459,7 +1459,7 @@ App::post('/v1/account/recovery')
;
$response->setStatusCode(Response::STATUS_CODE_CREATED);
$response->dynamic2($recovery, Response::MODEL_TOKEN);
$response->dynamic($recovery, Response::MODEL_TOKEN);
});
App::put('/v1/account/recovery')
@ -1533,7 +1533,7 @@ App::put('/v1/account/recovery')
->setParam('resource', 'users/'.$profile->getId())
;
$response->dynamic2($recovery, Response::MODEL_TOKEN);
$response->dynamic($recovery, Response::MODEL_TOKEN);
});
App::post('/v1/account/verification')
@ -1563,7 +1563,7 @@ App::post('/v1/account/verification')
->action(function ($url, $request, $response, $project, $user, $dbForInternal, $locale, $audits, $events, $mails) {
/** @var Utopia\Swoole\Request $request */
/** @var Appwrite\Utopia\Response $response */
/** @var Appwrite\Database\Document $project */
/** @var Utopia\Database\Document $project */
/** @var Utopia\Database\Document $user */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Locale\Locale $locale */
@ -1629,7 +1629,7 @@ App::post('/v1/account/verification')
$events
->setParam('eventData',
$response->output2($verification->setAttribute('secret', $verificationSecret),
$response->output($verification->setAttribute('secret', $verificationSecret),
Response::MODEL_TOKEN
))
;
@ -1645,7 +1645,7 @@ App::post('/v1/account/verification')
;
$response->setStatusCode(Response::STATUS_CODE_CREATED);
$response->dynamic2($verification, Response::MODEL_TOKEN);
$response->dynamic($verification, Response::MODEL_TOKEN);
});
App::put('/v1/account/verification')
@ -1710,5 +1710,5 @@ App::put('/v1/account/verification')
->setParam('resource', 'users/'.$user->getId())
;
$response->dynamic2($verification, Response::MODEL_TOKEN);
$response->dynamic($verification, Response::MODEL_TOKEN);
});

View file

@ -424,7 +424,7 @@ App::get('/v1/avatars/initials')
->inject('user')
->action(function ($name, $width, $height, $color, $background, $response, $user) {
/** @var Appwrite\Utopia\Response $response */
/** @var Appwrite\Database\Document $user */
/** @var Utopia\Database\Document $user */
$themes = [
['color' => '#27005e', 'background' => '#e1d2f6'], // VIOLET

View file

@ -67,7 +67,7 @@ App::post('/v1/database/collections')
;
$response->setStatusCode(Response::STATUS_CODE_CREATED);
$response->dynamic2($collection, Response::MODEL_COLLECTION);
$response->dynamic($collection, Response::MODEL_COLLECTION);
});
App::get('/v1/database/collections')
@ -93,7 +93,7 @@ App::get('/v1/database/collections')
$queries = ($search) ? [new Query('name', Query::TYPE_SEARCH, [$search])] : [];
$response->dynamic2(new Document([
$response->dynamic(new Document([
'collections' => $dbForExternal->find(Database::COLLECTIONS, $queries, $limit, $offset, ['_id'], [$orderType]),
'sum' => $dbForExternal->count(Database::COLLECTIONS, $queries, APP_LIMIT_COUNT),
]), Response::MODEL_COLLECTION_LIST);
@ -123,7 +123,7 @@ App::get('/v1/database/collections/:collectionId')
throw new Exception('Collection not found', 404);
}
$response->dynamic2($collection, Response::MODEL_COLLECTION);
$response->dynamic($collection, Response::MODEL_COLLECTION);
});
App::put('/v1/database/collections/:collectionId')
@ -177,7 +177,7 @@ App::put('/v1/database/collections/:collectionId')
->setParam('data', $collection->getArrayCopy())
;
$response->dynamic2($collection, Response::MODEL_COLLECTION);
$response->dynamic($collection, Response::MODEL_COLLECTION);
});
App::delete('/v1/database/collections/:collectionId')
@ -212,7 +212,7 @@ App::delete('/v1/database/collections/:collectionId')
$dbForExternal->deleteCollection($collectionId);
$events
->setParam('eventData', $response->output2($collection, Response::MODEL_COLLECTION))
->setParam('eventData', $response->output($collection, Response::MODEL_COLLECTION))
;
$audits
@ -296,7 +296,7 @@ App::post('/v1/database/collections/:collectionId/attributes')
;
$response->setStatusCode(Response::STATUS_CODE_CREATED);
$response->dynamic2($attribute, Response::MODEL_ATTRIBUTE);
$response->dynamic($attribute, Response::MODEL_ATTRIBUTE);
});
App::get('/v1/database/collections/:collectionId/attributes')
@ -331,7 +331,7 @@ App::get('/v1/database/collections/:collectionId/attributes')
])]);
}, $attributes);
$response->dynamic2(new Document([
$response->dynamic(new Document([
'sum' => \count($attributes),
'attributes' => $attributes
]), Response::MODEL_ATTRIBUTE_LIST);
@ -375,7 +375,7 @@ App::get('/v1/database/collections/:collectionId/attributes/:attributeId')
'collectionId' => $collectionId,
])]);
$response->dynamic2($attribute, Response::MODEL_ATTRIBUTE);
$response->dynamic($attribute, Response::MODEL_ATTRIBUTE);
});
App::delete('/v1/database/collections/:collectionId/attributes/:attributeId')
@ -428,7 +428,7 @@ App::delete('/v1/database/collections/:collectionId/attributes/:attributeId')
;
$events
->setParam('payload', $response->output2($attribute, Response::MODEL_ATTRIBUTE))
->setParam('payload', $response->output($attribute, Response::MODEL_ATTRIBUTE))
;
$audits
@ -526,7 +526,7 @@ App::post('/v1/database/collections/:collectionId/indexes')
;
$response->setStatusCode(Response::STATUS_CODE_CREATED);
$response->dynamic2($index, Response::MODEL_INDEX);
$response->dynamic($index, Response::MODEL_INDEX);
});
@ -562,7 +562,7 @@ App::get('/v1/database/collections/:collectionId/indexes')
])]);
}, $indexes);
$response->dynamic2(new Document([
$response->dynamic(new Document([
'sum' => \count($indexes),
'attributes' => $indexes,
]), Response::MODEL_INDEX_LIST);
@ -606,7 +606,7 @@ App::get('/v1/database/collections/:collectionId/indexes/:indexId')
'collectionId' => $collectionId,
])]);
$response->dynamic2($index, Response::MODEL_INDEX);
$response->dynamic($index, Response::MODEL_INDEX);
});
App::delete('/v1/database/collections/:collectionId/indexes/:indexId')
@ -659,7 +659,7 @@ App::delete('/v1/database/collections/:collectionId/indexes/:indexId')
;
$events
->setParam('payload', $response->output2($index, Response::MODEL_INDEX))
->setParam('payload', $response->output($index, Response::MODEL_INDEX))
;
$audits
@ -731,7 +731,7 @@ App::post('/v1/database/collections/:collectionId/documents')
;
$response->setStatusCode(Response::STATUS_CODE_CREATED);
$response->dynamic2($document, Response::MODEL_DOCUMENT);
$response->dynamic($document, Response::MODEL_DOCUMENT);
});
App::get('/v1/database/collections/:collectionId/documents')
@ -782,7 +782,7 @@ App::get('/v1/database/collections/:collectionId/documents')
$documents = $dbForExternal->find($collectionId, $queries, $limit, $offset, $orderAttributes, $orderTypes);
$response->dynamic2(new Document([
$response->dynamic(new Document([
'sum' => \count($documents),
'documents' => $documents,
]), Response::MODEL_DOCUMENT_LIST);
@ -819,7 +819,7 @@ App::get('/v1/database/collections/:collectionId/documents/:documentId')
throw new Exception('No document found', 404);
}
$response->dynamic2($document, Response::MODEL_DOCUMENT);
$response->dynamic($document, Response::MODEL_DOCUMENT);
});
App::patch('/v1/database/collections/:collectionId/documents/:documentId')
@ -890,7 +890,7 @@ App::patch('/v1/database/collections/:collectionId/documents/:documentId')
->setParam('data', $document->getArrayCopy())
;
$response->dynamic2($document, Response::MODEL_DOCUMENT);
$response->dynamic($document, Response::MODEL_DOCUMENT);
});
App::delete('/v1/database/collections/:collectionId/documents/:documentId')
@ -931,7 +931,7 @@ App::delete('/v1/database/collections/:collectionId/documents/:documentId')
$success = $dbForExternal->deleteDocument($collectionId, $documentId);
$events
->setParam('eventData', $response->output2($document, Response::MODEL_DOCUMENT))
->setParam('eventData', $response->output($document, Response::MODEL_DOCUMENT))
;
$audits

View file

@ -2,7 +2,7 @@
use Ahc\Jwt\JWT;
use Appwrite\Auth\Auth;
use Appwrite\Database\Validator\UID;
use Utopia\Database\Validator\UID;
use Utopia\Storage\Storage;
use Utopia\Storage\Validator\File;
use Utopia\Storage\Validator\FileExt;
@ -68,7 +68,7 @@ App::post('/v1/functions')
]));
$response->setStatusCode(Response::STATUS_CODE_CREATED);
$response->dynamic2($function, Response::MODEL_FUNCTION);
$response->dynamic($function, Response::MODEL_FUNCTION);
});
App::get('/v1/functions')
@ -94,7 +94,7 @@ App::get('/v1/functions')
$queries = ($search) ? [new Query('name', Query::TYPE_SEARCH, [$search])] : [];
$response->dynamic2(new Document([
$response->dynamic(new Document([
'functions' => $dbForInternal->find('functions', $queries, $limit, $offset, ['_id'], [$orderType]),
'sum' => $dbForInternal->count('functions', $queries, APP_LIMIT_COUNT),
]), Response::MODEL_FUNCTION_LIST);
@ -124,7 +124,7 @@ App::get('/v1/functions/:functionId')
throw new Exception('Function not found', 404);
}
$response->dynamic2($function, Response::MODEL_FUNCTION);
$response->dynamic($function, Response::MODEL_FUNCTION);
});
App::get('/v1/functions/:functionId/usage')
@ -142,7 +142,7 @@ App::get('/v1/functions/:functionId/usage')
->inject('register')
->action(function ($functionId, $range, $response, $project, $dbForInternal, $register) {
/** @var Appwrite\Utopia\Response $response */
/** @var Appwrite\Database\Document $project */
/** @var Utopia\Database\Document $project */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Registry\Registry $register */
@ -272,7 +272,7 @@ App::put('/v1/functions/:functionId')
->action(function ($functionId, $name, $execute, $vars, $events, $schedule, $timeout, $response, $dbForInternal, $project) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Appwrite\Database\Document $project */
/** @var Utopia\Database\Document $project */
$function = $dbForInternal->getDocument('functions', $functionId);
@ -305,7 +305,7 @@ App::put('/v1/functions/:functionId')
]); // Async task rescheduale
}
$response->dynamic2($function, Response::MODEL_FUNCTION);
$response->dynamic($function, Response::MODEL_FUNCTION);
});
App::patch('/v1/functions/:functionId/tag')
@ -328,7 +328,7 @@ App::patch('/v1/functions/:functionId/tag')
->action(function ($functionId, $tag, $response, $dbForInternal, $project) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Appwrite\Database\Document $project */
/** @var Utopia\Database\Document $project */
$function = $dbForInternal->getDocument('functions', $functionId);
$tag = $dbForInternal->getDocument('tags', $tag);
@ -360,7 +360,7 @@ App::patch('/v1/functions/:functionId/tag')
]); // Async task rescheduale
}
$response->dynamic2($function, Response::MODEL_FUNCTION);
$response->dynamic($function, Response::MODEL_FUNCTION);
});
App::delete('/v1/functions/:functionId')
@ -484,7 +484,7 @@ App::post('/v1/functions/:functionId/tags')
;
$response->setStatusCode(Response::STATUS_CODE_CREATED);
$response->dynamic2($tag, Response::MODEL_TAG);
$response->dynamic($tag, Response::MODEL_TAG);
});
App::get('/v1/functions/:functionId/tags')
@ -520,7 +520,7 @@ App::get('/v1/functions/:functionId/tags')
$results = $dbForInternal->find('tags', $queries, $limit, $offset, ['_id'], [$orderType]);
$sum = $dbForInternal->count('tags', $queries, APP_LIMIT_COUNT);
$response->dynamic2(new Document([
$response->dynamic(new Document([
'tags' => $results,
'sum' => $sum,
]), Response::MODEL_TAG_LIST);
@ -561,7 +561,7 @@ App::get('/v1/functions/:functionId/tags/:tagId')
throw new Exception('Tag not found', 404);
}
$response->dynamic2($tag, Response::MODEL_TAG);
$response->dynamic($tag, Response::MODEL_TAG);
});
App::delete('/v1/functions/:functionId/tags/:tagId')
@ -645,9 +645,9 @@ App::post('/v1/functions/:functionId/executions')
->inject('user')
->action(function ($functionId, $data, /*$async,*/ $response, $project, $dbForInternal, $user) {
/** @var Appwrite\Utopia\Response $response */
/** @var Appwrite\Database\Document $project */
/** @var Utopia\Database\Document $project */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Appwrite\Database\Document $user */
/** @var Utopia\Database\Document $user */
Authorization::disable();
@ -696,20 +696,20 @@ App::post('/v1/functions/:functionId/executions')
$jwt = ''; // initialize
if (!$user->isEmpty()) { // If userId exists, generate a JWT for function
$tokens = $user->getAttribute('tokens', []);
$session = new Document();
$sessions = $user->getAttribute('sessions', []);
$current = new Document();
foreach ($tokens as $token) { /** @var Appwrite\Database\Document $token */
if ($token->getAttribute('secret') == Auth::hash(Auth::$secret)) { // If current session delete the cookies too
$session = $token;
foreach ($sessions as $session) { /** @var Utopia\Database\Document $session */
if ($session->getAttribute('secret') == Auth::hash(Auth::$secret)) { // If current session delete the cookies too
$current = $session;
}
}
if(!$session->isEmpty()) {
if(!$current->isEmpty()) {
$jwtObj = new JWT(App::getEnv('_APP_OPENSSL_KEY_V1'), 'HS256', 900, 10); // Instantiate with key, algo, maxAge and leeway.
$jwt = $jwtObj->encode([
'userId' => $user->getId(),
'sessionId' => $session->getId(),
'sessionId' => $current->getId(),
]);
}
}
@ -726,7 +726,7 @@ App::post('/v1/functions/:functionId/executions')
]);
$response->setStatusCode(Response::STATUS_CODE_CREATED);
$response->dynamic2($execution, Response::MODEL_EXECUTION);
$response->dynamic($execution, Response::MODEL_EXECUTION);
});
App::get('/v1/functions/:functionId/executions')
@ -765,7 +765,7 @@ App::get('/v1/functions/:functionId/executions')
new Query('functionId', Query::TYPE_EQUAL, [$function->getId()]),
], APP_LIMIT_COUNT);
$response->dynamic2(new Document([
$response->dynamic(new Document([
'executions' => $results,
'sum' => $sum,
]), Response::MODEL_EXECUTION_LIST);
@ -808,5 +808,5 @@ App::get('/v1/functions/:functionId/executions/:executionId')
throw new Exception('Execution not found', 404);
}
$response->dynamic2($execution, Response::MODEL_EXECUTION);
$response->dynamic($execution, Response::MODEL_EXECUTION);
});

View file

@ -1,6 +1,6 @@
<?php
use Appwrite\Database\Document;
use Utopia\Database\Document;
use Appwrite\Utopia\Response;
use Utopia\App;
use Utopia\Config\Config;

View file

@ -134,7 +134,7 @@ App::post('/v1/projects')
$consoleDB->createNamespace($project->getId());
$response->setStatusCode(Response::STATUS_CODE_CREATED);
$response->dynamic2($project, Response::MODEL_PROJECT);
$response->dynamic($project, Response::MODEL_PROJECT);
});
App::get('/v1/projects')
@ -162,7 +162,7 @@ App::get('/v1/projects')
$results = $dbForConsole->find('projects', $queries, $limit, $offset, ['_id'], [$orderType]);
$sum = $dbForConsole->count('projects', $queries, APP_LIMIT_COUNT);
$response->dynamic2(new Document([
$response->dynamic(new Document([
'projects' => $results,
'sum' => $sum,
]), Response::MODEL_PROJECT_LIST);
@ -191,7 +191,7 @@ App::get('/v1/projects/:projectId')
throw new Exception('Project not found', 404);
}
$response->dynamic2($project, Response::MODEL_PROJECT);
$response->dynamic($project, Response::MODEL_PROJECT);
});
App::get('/v1/projects/:projectId/usage')
@ -440,7 +440,7 @@ App::patch('/v1/projects/:projectId')
->setAttribute('legalTaxId', $legalTaxId)
);
$response->dynamic2($project, Response::MODEL_PROJECT);
$response->dynamic($project, Response::MODEL_PROJECT);
});
App::patch('/v1/projects/:projectId/oauth2')
@ -474,7 +474,7 @@ App::patch('/v1/projects/:projectId/oauth2')
->setAttribute('usersOauth2' . \ucfirst($provider) . 'Secret', $secret)
);
$response->dynamic2($project, Response::MODEL_PROJECT);
$response->dynamic($project, Response::MODEL_PROJECT);
});
App::patch('/v1/projects/:projectId/auth/limit')
@ -505,7 +505,7 @@ App::patch('/v1/projects/:projectId/auth/limit')
->setAttribute('usersAuthLimit', $limit)
);
$response->dynamic2($project, Response::MODEL_PROJECT);
$response->dynamic($project, Response::MODEL_PROJECT);
});
App::patch('/v1/projects/:projectId/auth/:method')
@ -540,7 +540,7 @@ App::patch('/v1/projects/:projectId/auth/:method')
->setAttribute($authKey, $status)
);
$response->dynamic2($project, Response::MODEL_PROJECT);
$response->dynamic($project, Response::MODEL_PROJECT);
});
App::delete('/v1/projects/:projectId')
@ -638,7 +638,7 @@ App::post('/v1/projects/:projectId/webhooks')
);
$response->setStatusCode(Response::STATUS_CODE_CREATED);
$response->dynamic2($webhook, Response::MODEL_WEBHOOK);
$response->dynamic($webhook, Response::MODEL_WEBHOOK);
});
App::get('/v1/projects/:projectId/webhooks')
@ -666,7 +666,7 @@ App::get('/v1/projects/:projectId/webhooks')
$webhooks = $project->getAttribute('webhooks', []);
$response->dynamic2(new Document([
$response->dynamic(new Document([
'webhooks' => $webhooks,
'sum' => count($webhooks),
]), Response::MODEL_WEBHOOK_LIST);
@ -702,7 +702,7 @@ App::get('/v1/projects/:projectId/webhooks/:webhookId')
throw new Exception('Webhook not found', 404);
}
$response->dynamic2($webhook, Response::MODEL_WEBHOOK);
$response->dynamic($webhook, Response::MODEL_WEBHOOK);
});
App::put('/v1/projects/:projectId/webhooks/:webhookId')
@ -754,7 +754,7 @@ App::put('/v1/projects/:projectId/webhooks/:webhookId')
$dbForConsole->updateDocument('projects', $project->getId(), $project);
$response->dynamic2($webhook, Response::MODEL_WEBHOOK);
$response->dynamic($webhook, Response::MODEL_WEBHOOK);
});
App::delete('/v1/projects/:projectId/webhooks/:webhookId')
@ -828,7 +828,7 @@ App::post('/v1/projects/:projectId/keys')
);
$response->setStatusCode(Response::STATUS_CODE_CREATED);
$response->dynamic2($key, Response::MODEL_KEY);
$response->dynamic($key, Response::MODEL_KEY);
});
App::get('/v1/projects/:projectId/keys')
@ -856,7 +856,7 @@ App::get('/v1/projects/:projectId/keys')
$keys = $project->getAttribute('keys', []);
$response->dynamic2(new Document([
$response->dynamic(new Document([
'keys' => $keys,
'sum' => count($keys),
]), Response::MODEL_KEY_LIST);
@ -889,7 +889,7 @@ App::get('/v1/projects/:projectId/keys/:keyId')
throw new Exception('Key not found', 404);
}
$response->dynamic2($key, Response::MODEL_KEY);
$response->dynamic($key, Response::MODEL_KEY);
});
App::put('/v1/projects/:projectId/keys/:keyId')
@ -931,7 +931,7 @@ App::put('/v1/projects/:projectId/keys/:keyId')
$dbForConsole->updateDocument('projects', $project->getId(), $project);
$response->dynamic2($key, Response::MODEL_KEY);
$response->dynamic($key, Response::MODEL_KEY);
});
App::delete('/v1/projects/:projectId/keys/:keyId')
@ -1032,7 +1032,7 @@ App::post('/v1/projects/:projectId/tasks')
}
$response->setStatusCode(Response::STATUS_CODE_CREATED);
$response->dynamic2($task, Response::MODEL_TASK);
$response->dynamic($task, Response::MODEL_TASK);
});
App::get('/v1/projects/:projectId/tasks')
@ -1060,7 +1060,7 @@ App::get('/v1/projects/:projectId/tasks')
$tasks = $project->getAttribute('tasks', []);
$response->dynamic2(new Document([
$response->dynamic(new Document([
'tasks' => $tasks,
'sum' => count($tasks),
]), Response::MODEL_TASK_LIST);
@ -1097,7 +1097,7 @@ App::get('/v1/projects/:projectId/tasks/:taskId')
throw new Exception('Task not found', 404);
}
$response->dynamic2($task, Response::MODEL_TASK);
$response->dynamic($task, Response::MODEL_TASK);
});
App::put('/v1/projects/:projectId/tasks/:taskId')
@ -1163,7 +1163,7 @@ App::put('/v1/projects/:projectId/tasks/:taskId')
ResqueScheduler::enqueueAt($next, 'v1-tasks', 'TasksV1', $task->getArrayCopy());
}
$response->dynamic2($task, Response::MODEL_TASK);
$response->dynamic($task, Response::MODEL_TASK);
});
App::delete('/v1/projects/:projectId/tasks/:taskId')
@ -1244,7 +1244,7 @@ App::post('/v1/projects/:projectId/platforms')
);
$response->setStatusCode(Response::STATUS_CODE_CREATED);
$response->dynamic2($platform, Response::MODEL_PLATFORM);
$response->dynamic($platform, Response::MODEL_PLATFORM);
});
App::get('/v1/projects/:projectId/platforms')
@ -1272,7 +1272,7 @@ App::get('/v1/projects/:projectId/platforms')
$platforms = $project->getAttribute('platforms', []);
$response->dynamic2(new Document([
$response->dynamic(new Document([
'platforms' => $platforms,
'sum' => count($platforms),
]), Response::MODEL_PLATFORM_LIST);
@ -1308,7 +1308,7 @@ App::get('/v1/projects/:projectId/platforms/:platformId')
throw new Exception('Platform not found', 404);
}
$response->dynamic2($platform, Response::MODEL_PLATFORM);
$response->dynamic($platform, Response::MODEL_PLATFORM);
});
App::put('/v1/projects/:projectId/platforms/:platformId')
@ -1363,7 +1363,7 @@ App::put('/v1/projects/:projectId/platforms/:platformId')
$dbForConsole->updateDocument('projects', $project->getId(), $project);
$response->dynamic2($platform, Response::MODEL_PLATFORM);
$response->dynamic($platform, Response::MODEL_PLATFORM);
});
App::delete('/v1/projects/:projectId/platforms/:platformId')
@ -1453,7 +1453,7 @@ App::post('/v1/projects/:projectId/domains')
);
$response->setStatusCode(Response::STATUS_CODE_CREATED);
$response->dynamic2($domain, Response::MODEL_DOMAIN);
$response->dynamic($domain, Response::MODEL_DOMAIN);
});
App::get('/v1/projects/:projectId/domains')
@ -1481,7 +1481,7 @@ App::get('/v1/projects/:projectId/domains')
$domains = $project->getAttribute('domains', []);
$response->dynamic2(new Document([
$response->dynamic(new Document([
'domains' => $domains,
'sum' => count($domains),
]), Response::MODEL_DOMAIN_LIST);
@ -1517,7 +1517,7 @@ App::get('/v1/projects/:projectId/domains/:domainId')
throw new Exception('Domain not found', 404);
}
$response->dynamic2($domain, Response::MODEL_DOMAIN);
$response->dynamic($domain, Response::MODEL_DOMAIN);
});
App::patch('/v1/projects/:projectId/domains/:domainId/verification')
@ -1557,7 +1557,7 @@ App::patch('/v1/projects/:projectId/domains/:domainId/verification')
}
if ($domain->getAttribute('verification') === true) {
return $response->dynamic2($domain, Response::MODEL_DOMAIN);
return $response->dynamic($domain, Response::MODEL_DOMAIN);
}
$validator = new CNAME($target->get()); // Verify Domain with DNS records
@ -1578,7 +1578,7 @@ App::patch('/v1/projects/:projectId/domains/:domainId/verification')
'domain' => $domain->getAttribute('domain'),
]);
$response->dynamic2($domain, Response::MODEL_DOMAIN);
$response->dynamic($domain, Response::MODEL_DOMAIN);
});
App::delete('/v1/projects/:projectId/domains/:domainId')

View file

@ -12,7 +12,7 @@ use Utopia\Cache\Cache;
use Utopia\Cache\Adapter\Filesystem;
use Appwrite\ClamAV\Network;
use Utopia\Database\Document;
use Appwrite\Database\Validator\UID;
use Utopia\Database\Validator\UID;
use Utopia\Storage\Storage;
use Utopia\Storage\Validator\File;
use Utopia\Storage\Validator\FileSize;
@ -77,7 +77,7 @@ App::post('/v1/storage/buckets')
;
$response->setStatusCode(Response::STATUS_CODE_CREATED);
$response->dynamic2($data, Response::MODEL_BUCKET);
$response->dynamic($data, Response::MODEL_BUCKET);
});
App::get('/v1/storage/buckets')
@ -103,7 +103,7 @@ App::get('/v1/storage/buckets')
$queries = ($search) ? [new Query('name', Query::TYPE_SEARCH, $search)] : [];
$response->dynamic2(new Document([
$response->dynamic(new Document([
'buckets' => $dbForInternal->find('buckets', $queries, $limit, $offset, ['_id'], [$orderType]),
'sum' => $dbForInternal->count('buckets', $queries, APP_LIMIT_COUNT),
]), Response::MODEL_BUCKET_LIST);
@ -133,7 +133,7 @@ App::get('/v1/storage/buckets/:bucketId')
throw new Exception('Bucket not found', 404);
}
$response->dynamic2($bucket, Response::MODEL_BUCKET);
$response->dynamic($bucket, Response::MODEL_BUCKET);
});
App::put('/v1/storage/buckets/:bucketId')
@ -173,6 +173,13 @@ App::put('/v1/storage/buckets/:bucketId')
$read ??= $bucket->getAttribute('$read', []); // By default inherit read permissions
$write ??= $bucket->getAttribute('$write',[]); // By default inherit write permissions
$read??=$bucket->getAttribute('$read', []); // By default inherit read permissions
$write??=$bucket->getAttribute('$write', []); // By default inherit write permissions
$maximumFileSize??=$bucket->getAttribute('maximumFileSize', (int)App::getEnv('_APP_STORAGE_LIMIT', 0));
$allowedFileExtensions??=$bucket->getAttribute('allowedFileExtensions', []);
$enabled??=$bucket->getAttribute('enabled', true);
$encryption??=$bucket->getAttribute('encryption', true);
$antiVirus??=$bucket->getAttribute('antiVirus', true);
$bucket = $dbForInternal->updateDocument('buckets', $bucket->getId(), $bucket
->setAttribute('name',$name)
@ -191,7 +198,7 @@ App::put('/v1/storage/buckets/:bucketId')
->setParam('data', $bucket->getArrayCopy())
;
$response->dynamic2($bucket, Response::MODEL_BUCKET);
$response->dynamic($bucket, Response::MODEL_BUCKET);
});
App::delete('/v1/storage/buckets/:bucketId')
@ -234,7 +241,7 @@ App::delete('/v1/storage/buckets/:bucketId')
}
$events
->setParam('eventData', $response->output2($bucket, Response::MODEL_BUCKET))
->setParam('eventData', $response->output($bucket, Response::MODEL_BUCKET))
;
$audits
@ -275,7 +282,7 @@ App::post('/v1/storage/buckets/:bucketId/files')
/** @var Utopia\Swoole\Request $request */
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Appwrite\Database\Document $user */
/** @var Utopia\Database\Document $user */
/** @var Appwrite\Event\Event $audits */
/** @var Appwrite\Event\Event $usage */
@ -399,7 +406,8 @@ App::post('/v1/storage/buckets/:bucketId/files')
;
$response->setStatusCode(Response::STATUS_CODE_CREATED);
$response->dynamic2($file, Response::MODEL_FILE);
$response->dynamic($file, Response::MODEL_FILE);
;
});
App::get('/v1/storage/buckets/:bucketId/files')
@ -437,7 +445,7 @@ App::get('/v1/storage/buckets/:bucketId/files')
$queries[] = [new Query('name', Query::TYPE_SEARCH, [$search])];
}
$response->dynamic2(new Document([
$response->dynamic(new Document([
'files' => $dbForInternal->find('files', $queries, $limit, $offset, ['_id'], [$orderType]),
'sum' => $dbForInternal->count('files', $queries, APP_LIMIT_COUNT),
]), Response::MODEL_FILE_LIST);
@ -475,7 +483,7 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId')
throw new Exception('File not found', 404);
}
$response->dynamic2($file, Response::MODEL_FILE);
$response->dynamic($file, Response::MODEL_FILE);
});
App::get('/v1/storage/buckets/:bucketId/files/:fileId/preview')
@ -827,7 +835,7 @@ App::put('/v1/storage/buckets/:bucketId/files/:fileId')
->setParam('resource', 'storage/files/'.$file->getId())
;
$response->dynamic2($file, Response::MODEL_FILE);
$response->dynamic($file, Response::MODEL_FILE);
});
App::delete('/v1/storage/buckets/:bucketId/files/:fileId')
@ -886,7 +894,7 @@ App::delete('/v1/storage/buckets/:bucketId/files/:fileId')
;
$events
->setParam('eventData', $response->output2($file, Response::MODEL_FILE))
->setParam('eventData', $response->output($file, Response::MODEL_FILE))
;
$response->noContent();

View file

@ -1,7 +1,6 @@
<?php
use Appwrite\Auth\Auth;
use Appwrite\Database\Validator\UID;
use Appwrite\Detector\Detector;
use Appwrite\Template\Template;
use Appwrite\Utopia\Response;
@ -19,6 +18,7 @@ use Utopia\Database\Exception\Duplicate;
use Utopia\Database\Query;
use Utopia\Database\Validator\Authorization;
use Utopia\Database\Validator\Key;
use Utopia\Database\Validator\UID;
App::post('/v1/teams')
->desc('Create Team')
@ -80,7 +80,7 @@ App::post('/v1/teams')
}
$response->setStatusCode(Response::STATUS_CODE_CREATED);
$response->dynamic2($team, Response::MODEL_TEAM);
$response->dynamic($team, Response::MODEL_TEAM);
});
App::get('/v1/teams')
@ -109,7 +109,7 @@ App::get('/v1/teams')
$results = $dbForInternal->find('teams', $queries, $limit, $offset, ['_id'], [$orderType]);
$sum = $dbForInternal->count('teams', $queries, APP_LIMIT_COUNT);
$response->dynamic2(new Document([
$response->dynamic(new Document([
'teams' => $results,
'sum' => $sum,
]), Response::MODEL_TEAM_LIST);
@ -139,7 +139,7 @@ App::get('/v1/teams/:teamId')
throw new Exception('Team not found', 404);
}
$response->dynamic2($team, Response::MODEL_TEAM);
$response->dynamic($team, Response::MODEL_TEAM);
});
App::put('/v1/teams/:teamId')
@ -170,7 +170,7 @@ App::put('/v1/teams/:teamId')
$team = $dbForInternal->updateDocument('teams', $team->getId(), $team->setAttribute('name', $name));
$response->dynamic2($team, Response::MODEL_TEAM);
$response->dynamic($team, Response::MODEL_TEAM);
});
App::delete('/v1/teams/:teamId')
@ -222,7 +222,7 @@ App::delete('/v1/teams/:teamId')
;
$events
->setParam('eventData', $response->output2($team, Response::MODEL_TEAM))
->setParam('eventData', $response->output($team, Response::MODEL_TEAM))
;
$response->noContent();
@ -256,8 +256,8 @@ App::post('/v1/teams/:teamId/memberships')
->inject('mails')
->action(function ($teamId, $email, $name, $roles, $url, $response, $project, $user, $dbForInternal, $locale, $audits, $mails) {
/** @var Appwrite\Utopia\Response $response */
/** @var Appwrite\Database\Document $project */
/** @var Appwrite\Database\Document $user */
/** @var Utopia\Database\Document $project */
/** @var Utopia\Database\Document $user */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Appwrite\Event\Event $audits */
/** @var Appwrite\Event\Event $mails */
@ -409,7 +409,7 @@ App::post('/v1/teams/:teamId/memberships')
;
$response->setStatusCode(Response::STATUS_CODE_CREATED);
$response->dynamic2($membership
$response->dynamic($membership
->setAttribute('email', $email)
->setAttribute('name', $name)
, Response::MODEL_MEMBERSHIP);
@ -457,7 +457,7 @@ App::get('/v1/teams/:teamId/memberships')
$users[] = new Document(\array_merge($temp, $membership->getArrayCopy()));
}
$response->dynamic2(new Document([
$response->dynamic(new Document([
'memberships' => $users,
'sum' => $sum,
]), Response::MODEL_MEMBERSHIP_LIST);
@ -486,7 +486,7 @@ App::patch('/v1/teams/:teamId/memberships/:membershipId')
->action(function ($teamId, $membershipId, $roles, $request, $response, $user, $dbForInternal, $audits) {
/** @var Utopia\Swoole\Request $request */
/** @var Appwrite\Utopia\Response $response */
/** @var Appwrite\Database\Document $user */
/** @var Utopia\Database\Document $user */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Appwrite\Event\Event $audits */
@ -525,7 +525,7 @@ App::patch('/v1/teams/:teamId/memberships/:membershipId')
->setParam('resource', 'teams/'.$teamId)
;
$response->dynamic2($membership, Response::MODEL_MEMBERSHIP);
$response->dynamic($membership, Response::MODEL_MEMBERSHIP);
});
App::patch('/v1/teams/:teamId/memberships/:membershipId/status')
@ -553,7 +553,7 @@ App::patch('/v1/teams/:teamId/memberships/:membershipId/status')
->action(function ($teamId, $membershipId, $userId, $secret, $request, $response, $user, $dbForInternal, $geodb, $audits) {
/** @var Utopia\Swoole\Request $request */
/** @var Appwrite\Utopia\Response $response */
/** @var Appwrite\Database\Document $user */
/** @var Utopia\Database\Document $user */
/** @var Utopia\Database\Database $dbForInternal */
/** @var MaxMind\Db\Reader $geodb */
/** @var Appwrite\Event\Event $audits */
@ -661,7 +661,7 @@ App::patch('/v1/teams/:teamId/memberships/:membershipId/status')
->addCookie(Auth::$cookieName, Auth::encodeSession($user->getId(), $secret), $expiry, '/', Config::getParam('cookieDomain'), ('https' == $protocol), true, Config::getParam('cookieSamesite'))
;
$response->dynamic2($membership
$response->dynamic($membership
->setAttribute('email', $user->getAttribute('email'))
->setAttribute('name', $user->getAttribute('name'))
, Response::MODEL_MEMBERSHIP);
@ -744,7 +744,7 @@ App::delete('/v1/teams/:teamId/memberships/:membershipId')
;
$events
->setParam('eventData', $response->output2($membership, Response::MODEL_MEMBERSHIP))
->setParam('eventData', $response->output($membership, Response::MODEL_MEMBERSHIP))
;
$response->noContent();

View file

@ -65,7 +65,7 @@ App::post('/v1/users')
}
$response->setStatusCode(Response::STATUS_CODE_CREATED);
$response->dynamic2($user, Response::MODEL_USER);
$response->dynamic($user, Response::MODEL_USER);
});
App::get('/v1/users')
@ -92,7 +92,7 @@ App::get('/v1/users')
$results = $dbForInternal->find('users', [], $limit, $offset, ['_id'], [$orderType]);
$sum = $dbForInternal->count('users', [], APP_LIMIT_COUNT);
$response->dynamic2(new Document([
$response->dynamic(new Document([
'users' => $results,
'sum' => $sum,
]), Response::MODEL_USER_LIST);
@ -122,7 +122,7 @@ App::get('/v1/users/:userId')
throw new Exception('User not found', 404);
}
$response->dynamic2($user, Response::MODEL_USER);
$response->dynamic($user, Response::MODEL_USER);
});
App::get('/v1/users/:userId/prefs')
@ -151,7 +151,7 @@ App::get('/v1/users/:userId/prefs')
$prefs = $user->getAttribute('prefs', new \stdClass());
$response->dynamic2(new Document($prefs), Response::MODEL_PREFERENCES);
$response->dynamic(new Document($prefs), Response::MODEL_PREFERENCES);
});
App::get('/v1/users/:userId/sessions')
@ -194,7 +194,7 @@ App::get('/v1/users/:userId/sessions')
$sessions[$key] = $session;
}
$response->dynamic2(new Document([
$response->dynamic(new Document([
'sessions' => $sessions,
'sum' => count($sessions),
]), Response::MODEL_SESSION_LIST);
@ -218,7 +218,7 @@ App::get('/v1/users/:userId/logs')
->inject('geodb')
->action(function ($userId, $response, $dbForInternal, $locale, $geodb) {
/** @var Appwrite\Utopia\Response $response */
/** @var Appwrite\Database\Document $project */
/** @var Utopia\Database\Document $project */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Locale\Locale $locale */
/** @var MaxMind\Db\Reader $geodb */
@ -305,7 +305,7 @@ App::get('/v1/users/:userId/logs')
}
}
$response->dynamic2(new Document(['logs' => $output]), Response::MODEL_LOG_LIST);
$response->dynamic(new Document(['logs' => $output]), Response::MODEL_LOG_LIST);
});
App::patch('/v1/users/:userId/status')
@ -336,7 +336,7 @@ App::patch('/v1/users/:userId/status')
$user = $dbForInternal->updateDocument('users', $user->getId(), $user->setAttribute('status', (bool) $status));
$response->dynamic2($user, Response::MODEL_USER);
$response->dynamic($user, Response::MODEL_USER);
});
App::patch('/v1/users/:userId/verification')
@ -367,7 +367,7 @@ App::patch('/v1/users/:userId/verification')
$user = $dbForInternal->updateDocument('users', $user->getId(), $user->setAttribute('emailVerification', $emailVerification));
$response->dynamic2($user, Response::MODEL_USER);
$response->dynamic($user, Response::MODEL_USER);
});
App::patch('/v1/users/:userId/prefs')
@ -398,7 +398,7 @@ App::patch('/v1/users/:userId/prefs')
$user = $dbForInternal->updateDocument('users', $user->getId(), $user->setAttribute('prefs', $prefs));
$response->dynamic2(new Document($prefs), Response::MODEL_PREFERENCES);
$response->dynamic(new Document($prefs), Response::MODEL_PREFERENCES);
});
App::delete('/v1/users/:userId/sessions/:sessionId')
@ -440,7 +440,7 @@ App::delete('/v1/users/:userId/sessions/:sessionId')
$user->setAttribute('sessions', $sessions);
$events
->setParam('eventData', $response->output2($user, Response::MODEL_USER))
->setParam('eventData', $response->output($user, Response::MODEL_USER))
;
$dbForInternal->updateDocument('users', $user->getId(), $user);
@ -486,7 +486,7 @@ App::delete('/v1/users/:userId/sessions')
$dbForInternal->updateDocument('users', $user->getId(), $user->getAttribute('sessions', []));
$events
->setParam('eventData', $response->output2($user, Response::MODEL_USER))
->setParam('eventData', $response->output($user, Response::MODEL_USER))
;
$response->noContent();
@ -535,7 +535,7 @@ App::delete('/v1/users/:userId')
;
$events
->setParam('eventData', $response->output2($user, Response::MODEL_USER))
->setParam('eventData', $response->output($user, Response::MODEL_USER))
;
// TODO : Response filter implementation

View file

@ -10,16 +10,14 @@ use Utopia\Exception;
use Utopia\Config\Config;
use Utopia\Domains\Domain;
use Appwrite\Auth\Auth;
use Appwrite\Database\Validator\Authorization;
use Appwrite\Network\Validator\Origin;
use Appwrite\Utopia\Response\Filters\V06;
use Appwrite\Utopia\Response\Filters\V07;
use Appwrite\Utopia\Response\Filters\V08;
use Utopia\CLI\Console;
use Utopia\Database\Database;
use Utopia\Database\Document;
use Utopia\Database\Query;
use Utopia\Database\Validator\Authorization as Authorization2;
use Utopia\Database\Validator\Authorization;
Config::setParam('domainVerification', false);
Config::setParam('cookieDomain', 'localhost');
@ -44,7 +42,7 @@ App::init(function ($utopia, $request, $response, $console, $project, $dbForCons
$domains[$domain->get()] = false;
Console::warning($domain->get() . ' is not a publicly accessible domain. Skipping SSL certificate generation.');
} else {
Authorization2::disable();
Authorization::disable();
$certificate = $dbForConsole->findFirst('certificates', [
new Query('domain', QUERY::TYPE_EQUAL, [$domain->get()])
@ -55,7 +53,7 @@ App::init(function ($utopia, $request, $response, $console, $project, $dbForCons
'domain' => $domain->get(),
]);
$certificate = $dbForConsole->createDocument('certificates', $certificate);
Authorization2::enable();
Authorization::enable();
Console::info('Issuing a TLS certificate for the master domain (' . $domain->get() . ') in a few seconds...');
@ -66,7 +64,7 @@ App::init(function ($utopia, $request, $response, $console, $project, $dbForCons
'validateCNAME' => false,
]);
} else {
Authorization2::enable(); // ensure authorization is reenabled
Authorization::enable(); // ensure authorization is reenabled
}
$domains[$domain->get()] = true;
}
@ -239,26 +237,21 @@ App::init(function ($utopia, $request, $response, $console, $project, $dbForCons
$scopes = \array_merge($roles[$role]['scopes'], $key->getAttribute('scopes', []));
Authorization::setDefaultStatus(false); // Cancel security segmentation for API keys.
Authorization2::setDefaultStatus(false); // Cancel security segmentation for API keys.
}
}
if ($user->getId()) {
Authorization::setRole('user:'.$user->getId());
Authorization2::setRole('user:'.$user->getId());
}
Authorization::setRole('role:'.$role);
Authorization2::setRole('role:'.$role);
\array_map(function ($node) {
if (isset($node['teamId']) && isset($node['roles'])) {
Authorization::setRole('team:'.$node['teamId']);
Authorization2::setRole('team:'.$node['teamId']);
foreach ($node['roles'] as $nodeRole) { // Set all team roles
Authorization::setRole('team:'.$node['teamId'].'/'.$nodeRole);
Authorization2::setRole('team:'.$node['teamId'].'/'.$nodeRole);
}
}
}, $user->getAttribute('memberships', []));
@ -305,7 +298,7 @@ App::error(function ($error, $utopia, $request, $response, $layout, $project) {
/** @var Utopia\Swoole\Request $request */
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\View $layout */
/** @var Appwrite\Database\Document $project */
/** @var Utopia\Database\Document $project */
if ($error instanceof PDOException) {
throw $error;
@ -393,7 +386,7 @@ App::error(function ($error, $utopia, $request, $response, $layout, $project) {
$response->html($layout->render());
}
$response->dynamic2(new Document($output),
$response->dynamic(new Document($output),
$utopia->isDevelopment() ? Response::MODEL_ERROR_DEV : Response::MODEL_ERROR);
}, ['error', 'utopia', 'request', 'response', 'layout', 'project']);

View file

@ -2,7 +2,7 @@
global $utopia, $request, $response;
use Appwrite\Database\Document;
use Utopia\Database\Document;
use Appwrite\Network\Validator\Host;
use Appwrite\Utopia\Response;
use Utopia\App;

View file

@ -1,7 +1,7 @@
<?php
use Appwrite\Auth\Auth;
use Appwrite\Database\Validator\Authorization;
use Utopia\Database\Validator\Authorization;
use Utopia\App;
use Utopia\Exception;
use Utopia\Abuse\Abuse;
@ -120,8 +120,8 @@ App::init(function ($utopia, $request, $response, $project, $user) {
/** @var Utopia\App $utopia */
/** @var Utopia\Swoole\Request $request */
/** @var Appwrite\Utopia\Response $response */
/** @var Appwrite\Database\Document $project */
/** @var Appwrite\Database\Document $user */
/** @var Utopia\Database\Document $project */
/** @var Utopia\Database\Document $user */
/** @var Utopia\Registry\Registry $register */
/** @var Appwrite\Event\Event $events */
/** @var Appwrite\Event\Event $audits */
@ -174,7 +174,7 @@ App::shutdown(function ($utopia, $request, $response, $project, $events, $audits
/** @var Utopia\App $utopia */
/** @var Utopia\Swoole\Request $request */
/** @var Appwrite\Utopia\Response $response */
/** @var Appwrite\Database\Document $project */
/** @var Utopia\Database\Document $project */
/** @var Appwrite\Event\Event $events */
/** @var Appwrite\Event\Event $audits */
/** @var Appwrite\Event\Event $usage */

View file

@ -1,6 +1,5 @@
<?php
use Appwrite\Database\Database;
use Appwrite\Specification\Format\OpenAPI3;
use Appwrite\Specification\Format\Swagger2;
use Appwrite\Specification\Specification;
@ -8,7 +7,6 @@ use Utopia\App;
use Utopia\View;
use Utopia\Config\Config;
use Utopia\Exception;
use Utopia\Validator\Boolean;
use Utopia\Validator\Range;
use Utopia\Validator\WhiteList;

View file

@ -2,7 +2,6 @@
require_once __DIR__.'/../vendor/autoload.php';
use Appwrite\Database\Validator\Authorization;
use Appwrite\Utopia\Response;
use Swoole\Process;
use Swoole\Http\Server;
@ -11,7 +10,7 @@ use Swoole\Http\Response as SwooleResponse;
use Utopia\App;
use Utopia\CLI\Console;
use Utopia\Config\Config;
use Utopia\Database\Validator\Authorization as Authorization2;
use Utopia\Database\Validator\Authorization;
use Utopia\Audit\Audit;
use Utopia\Abuse\Adapters\TimeLimit;
use Utopia\Database\Document;
@ -54,8 +53,25 @@ $http->on('start', function (Server $http) use ($payloadSize, $register) {
$app = new App('UTC');
go(function() use ($register, $app) {
$db = $register->get('dbPool')->get();
$redis = $register->get('redisPool')->get();
// wait for database to be ready
$attempts = 0;
$max = 10;
$sleep = 1;
do {
try {
$attempts++;
$db = $register->get('dbPool')->get();
$redis = $register->get('redisPool')->get();
break; // leave the do-while if successful
} catch(\Exception $e) {
Console::warning("Database not ready. Retrying connection ({$attempts})...");
if ($attempts >= $max) {
throw new \Exception('Failed to connect to database: '. $e->getMessage());
}
sleep($sleep);
}
} while ($attempts < $max);
App::setResource('db', function () use (&$db) {
return $db;
@ -69,9 +85,6 @@ $http->on('start', function (Server $http) use ($payloadSize, $register) {
return $app;
});
// wait for database to be ready
sleep(5);
$dbForConsole = $app->getResource('dbForConsole'); /** @var Utopia\Database\Database $dbForConsole */
if(!$dbForConsole->exists()) {
@ -170,9 +183,6 @@ $http->on('request', function (SwooleRequest $swooleRequest, SwooleResponse $swo
Authorization::cleanRoles();
Authorization::setRole('role:all');
Authorization2::cleanRoles();
Authorization2::setRole('role:all');
$app->run($request, $response);
} catch (\Throwable $th) {
Console::error('[Error] Type: '.get_class($th));

View file

@ -24,7 +24,6 @@ use Appwrite\Database\Database;
use Appwrite\Database\Adapter\MySQL as MySQLAdapter;
use Appwrite\Database\Adapter\Redis as RedisAdapter;
use Appwrite\Database\Document;
use Appwrite\Database\Validator\Authorization;
use Appwrite\Event\Event;
use Appwrite\OpenSSL\OpenSSL;
use Utopia\App;
@ -39,7 +38,7 @@ use Utopia\Cache\Cache;
use Utopia\Database\Adapter\MariaDB;
use Utopia\Database\Document as Document2;
use Utopia\Database\Database as Database2;
use Utopia\Database\Validator\Authorization as Authorization2;
use Utopia\Database\Validator\Authorization;
use Swoole\Database\PDOConfig;
use Swoole\Database\PDOPool;
use Swoole\Database\RedisConfig;
@ -58,8 +57,8 @@ const APP_LIMIT_USERS = 10000;
const APP_LIMIT_ANTIVIRUS = 20971520; //20MB
const APP_LIMIT_ENCRYPTION = 20971520; //20MB
const APP_LIMIT_COMPRESSION = 20971520; //20MB
const APP_CACHE_BUSTER = 149;
const APP_VERSION_STABLE = '0.9.1';
const APP_CACHE_BUSTER = 150;
const APP_VERSION_STABLE = '0.9.2';
const APP_STORAGE_UPLOADS = '/storage/uploads';
const APP_STORAGE_FUNCTIONS = '/storage/functions';
const APP_STORAGE_CACHE = '/storage/cache';
@ -443,7 +442,6 @@ App::setResource('user', function($mode, $project, $console, $request, $response
/** @var string $mode */
Authorization::setDefaultStatus(true);
Authorization2::setDefaultStatus(true);
Auth::setCookieName('a_session_'.$project->getId());
@ -488,7 +486,6 @@ App::setResource('user', function($mode, $project, $console, $request, $response
if (APP_MODE_ADMIN === $mode) {
if ($user->find('teamId', $project->getAttribute('teamId'), 'memberships')) {
Authorization::setDefaultStatus(false); // Cancel security segmentation for admin users.
Authorization2::setDefaultStatus(false); // Cancel security segmentation for admin users.
} else {
$user = new Document2(['$id' => '', '$collection' => 'users']);
}
@ -533,12 +530,10 @@ App::setResource('project', function($dbForConsole, $request, $console) {
}
Authorization::disable();
Authorization2::disable();
$project = $dbForConsole->getDocument('projects', $projectId);
Authorization::reset();
Authorization2::reset();
return $project;
}, ['dbForConsole', 'request', 'console']);

View file

@ -23,10 +23,12 @@ $register->set('db', function () {
return $pdo;
});
$register->set('cache', function () { // Register cache connection
$redis = new Redis();
$redis->pconnect(App::getEnv('_APP_REDIS_HOST', ''), App::getEnv('_APP_REDIS_PORT', ''));
$redis->setOption(Redis::OPT_READ_TIMEOUT, -1);
return $redis;
});
});

View file

@ -2,11 +2,7 @@
use Appwrite\Resque\Worker;
use Utopia\Audit\Audit;
use Utopia\Cache\Adapter\Redis;
use Utopia\Cache\Cache;
use Utopia\CLI\Console;
use Utopia\Database\Adapter\MariaDB;
use Utopia\Database\Database;
require_once __DIR__.'/../workers.php';
@ -23,8 +19,6 @@ class AuditsV1 extends Worker
public function run(): void
{
global $register;
$projectId = $this->args['projectId'];
$userId = $this->args['userId'];
$event = $this->args['event'];
@ -32,12 +26,8 @@ class AuditsV1 extends Worker
$userAgent = $this->args['userAgent'];
$ip = $this->args['ip'];
$data = $this->args['data'];
$db = $register->get('db', true);
$cache = new Cache(new Redis($register->get('cache')));
$dbForInternal = new Database(new MariaDB($db), $cache);
$dbForInternal->setNamespace('project_'.$projectId.'_internal');
$dbForInternal = $this->getInternalDB($projectId);
$audit = new Audit($dbForInternal);
$audit->log($userId, $event, $resource, $userAgent, $ip, '', $data);

View file

@ -3,13 +3,9 @@
use Appwrite\Network\Validator\CNAME;
use Appwrite\Resque\Worker;
use Utopia\App;
use Utopia\Cache\Adapter\Redis;
use Utopia\Cache\Cache;
use Utopia\CLI\Console;
use Utopia\Database\Database;
use Utopia\Database\Document;
use Utopia\Database\Query;
use Utopia\Database\Adapter\MariaDB;
use Utopia\Database\Validator\Authorization;
use Utopia\Domains\Domain;
@ -28,180 +24,167 @@ class CertificatesV1 extends Worker
public function run(): void
{
global $register;
$dbForConsole = $this->getConsoleDB();
go(function() use ($register) {
$db = $register->get('dbPool')->get();
$redis = $register->get('redisPool')->get();
/**
* 1. Get new domain document - DONE
* 1.1. Validate domain is valid, public suffix is known and CNAME records are verified - DONE
* 2. Check if a certificate already exists - DONE
* 3. Check if certificate is about to expire, if not - skip it
* 3.1. Create / renew certificate
* 3.2. Update loadblancer
* 3.3. Update database (domains, change date, expiry)
* 3.4. Set retry on failure
* 3.5. Schedule to renew certificate in 60 days
*/
$cache = new Cache(new Redis($redis));
$dbForConsole = new Database(new MariaDB($db), $cache);
$dbForConsole->setNamespace('project_console_internal');
Authorization::disable();
/**
* 1. Get new domain document - DONE
* 1.1. Validate domain is valid, public suffix is known and CNAME records are verified - DONE
* 2. Check if a certificate already exists - DONE
* 3. Check if certificate is about to expire, if not - skip it
* 3.1. Create / renew certificate
* 3.2. Update loadblancer
* 3.3. Update database (domains, change date, expiry)
* 3.4. Set retry on failure
* 3.5. Schedule to renew certificate in 60 days
*/
// Args
$document = $this->args['document'];
$domain = $this->args['domain'];
Authorization::disable();
// Args
$document = $this->args['document'];
$domain = $this->args['domain'];
// Validation Args
$validateTarget = $this->args['validateTarget'] ?? true;
$validateCNAME = $this->args['validateCNAME'] ?? true;
// Options
$domain = new Domain((!empty($domain)) ? $domain : '');
$expiry = 60 * 60 * 24 * 30 * 2; // 60 days
$safety = 60 * 60; // 1 hour
$renew = (\time() + $expiry);
if(empty($domain->get())) {
throw new Exception('Missing domain');
}
if(!$domain->isKnown() || $domain->isTest()) {
throw new Exception('Unknown public suffix for domain');
}
if($validateTarget) {
$target = new Domain(App::getEnv('_APP_DOMAIN_TARGET', ''));
// Validation Args
$validateTarget = $this->args['validateTarget'] ?? true;
$validateCNAME = $this->args['validateCNAME'] ?? true;
if(!$target->isKnown() || $target->isTest()) {
throw new Exception('Unreachable CNAME target ('.$target->get().'), please use a domain with a public suffix.');
}
// Options
$domain = new Domain((!empty($domain)) ? $domain : '');
$expiry = 60 * 60 * 24 * 30 * 2; // 60 days
$safety = 60 * 60; // 1 hour
$renew = (\time() + $expiry);
if(empty($domain->get())) {
throw new Exception('Missing domain');
}
if(!$domain->isKnown() || $domain->isTest()) {
throw new Exception('Unknown public suffix for domain');
}
if($validateTarget) {
$target = new Domain(App::getEnv('_APP_DOMAIN_TARGET', ''));
if(!$target->isKnown() || $target->isTest()) {
throw new Exception('Unreachable CNAME target ('.$target->get().'), please use a domain with a public suffix.');
}
}
if($validateCNAME) {
$validator = new CNAME($target->get()); // Verify Domain with DNS records
if(!$validator->isValid($domain->get())) {
throw new Exception('Failed to verify domain DNS records');
}
if($validateCNAME) {
$validator = new CNAME($target->get()); // Verify Domain with DNS records
if(!$validator->isValid($domain->get())) {
throw new Exception('Failed to verify domain DNS records');
}
}
$certificate = $dbForConsole->findFirst('certificates', [
new Query('domain', QUERY::TYPE_EQUAL, [$domain->get()])
], /*limit*/ 1);
$certificate = $dbForConsole->findFirst('certificates', [
new Query('domain', QUERY::TYPE_EQUAL, [$domain->get()])
], /*limit*/ 1);
// $condition = ($certificate
// && $certificate instanceof Document
// && isset($certificate['issueDate'])
// && (($certificate['issueDate'] + ($expiry)) > time())) ? 'true' : 'false';
// $condition = ($certificate
// && $certificate instanceof Document
// && isset($certificate['issueDate'])
// && (($certificate['issueDate'] + ($expiry)) > time())) ? 'true' : 'false';
// throw new Exception('cert issued at'.date('d.m.Y H:i', $certificate['issueDate']).' | renew date is: '.date('d.m.Y H:i', ($certificate['issueDate'] + ($expiry))).' | condition is '.$condition);
// throw new Exception('cert issued at'.date('d.m.Y H:i', $certificate['issueDate']).' | renew date is: '.date('d.m.Y H:i', ($certificate['issueDate'] + ($expiry))).' | condition is '.$condition);
$certificate = (!empty($certificate) && $certificate instanceof $certificate) ? $certificate->getArrayCopy() : [];
$certificate = (!empty($certificate) && $certificate instanceof $certificate) ? $certificate->getArrayCopy() : [];
if(!empty($certificate)
&& isset($certificate['issueDate'])
&& (($certificate['issueDate'] + ($expiry)) > \time())) { // Check last issue time
throw new Exception('Renew isn\'t required');
if(!empty($certificate)
&& isset($certificate['issueDate'])
&& (($certificate['issueDate'] + ($expiry)) > \time())) { // Check last issue time
throw new Exception('Renew isn\'t required');
}
$staging = (App::isProduction()) ? '' : ' --dry-run';
$email = App::getEnv('_APP_SYSTEM_SECURITY_EMAIL_ADDRESS');
if(empty($email)) {
throw new Exception('You must set a valid security email address (_APP_SYSTEM_SECURITY_EMAIL_ADDRESS) to issue an SSL certificate');
}
$stdout = '';
$stderr = '';
$exit = Console::execute("certbot certonly --webroot --noninteractive --agree-tos{$staging}"
." --email ".$email
." -w ".APP_STORAGE_CERTIFICATES
." -d {$domain->get()}", '', $stdout, $stderr);
if($exit !== 0) {
throw new Exception('Failed to issue a certificate with message: '.$stderr);
}
$path = APP_STORAGE_CERTIFICATES.'/'.$domain->get();
if(!\is_readable($path)) {
if (!\mkdir($path, 0755, true)) {
throw new Exception('Failed to create path...');
}
}
$staging = (App::isProduction()) ? '' : ' --dry-run';
$email = App::getEnv('_APP_SYSTEM_SECURITY_EMAIL_ADDRESS');
if(!@\rename('/etc/letsencrypt/live/'.$domain->get().'/cert.pem', APP_STORAGE_CERTIFICATES.'/'.$domain->get().'/cert.pem')) {
throw new Exception('Failed to rename certificate cert.pem: '.\json_encode($stdout));
}
if(empty($email)) {
throw new Exception('You must set a valid security email address (_APP_SYSTEM_SECURITY_EMAIL_ADDRESS) to issue an SSL certificate');
}
if(!@\rename('/etc/letsencrypt/live/'.$domain->get().'/chain.pem', APP_STORAGE_CERTIFICATES.'/'.$domain->get().'/chain.pem')) {
throw new Exception('Failed to rename certificate chain.pem: '.\json_encode($stdout));
}
$stdout = '';
$stderr = '';
if(!@\rename('/etc/letsencrypt/live/'.$domain->get().'/fullchain.pem', APP_STORAGE_CERTIFICATES.'/'.$domain->get().'/fullchain.pem')) {
throw new Exception('Failed to rename certificate fullchain.pem: '.\json_encode($stdout));
}
$exit = Console::execute("certbot certonly --webroot --noninteractive --agree-tos{$staging}"
." --email ".$email
." -w ".APP_STORAGE_CERTIFICATES
." -d {$domain->get()}", '', $stdout, $stderr);
if(!@\rename('/etc/letsencrypt/live/'.$domain->get().'/privkey.pem', APP_STORAGE_CERTIFICATES.'/'.$domain->get().'/privkey.pem')) {
throw new Exception('Failed to rename certificate privkey.pem: '.\json_encode($stdout));
}
if($exit !== 0) {
throw new Exception('Failed to issue a certificate with message: '.$stderr);
}
$certificate = new Document(\array_merge($certificate, [
'domain' => $domain->get(),
'issueDate' => \time(),
'renewDate' => $renew,
'attempts' => 0,
'log' => \json_encode($stdout),
]));
$path = APP_STORAGE_CERTIFICATES.'/'.$domain->get();
$certificate = $dbForConsole->createDocument('certificates', $certificate);
if(!\is_readable($path)) {
if (!\mkdir($path, 0755, true)) {
throw new Exception('Failed to create path...');
}
}
if(!@\rename('/etc/letsencrypt/live/'.$domain->get().'/cert.pem', APP_STORAGE_CERTIFICATES.'/'.$domain->get().'/cert.pem')) {
throw new Exception('Failed to rename certificate cert.pem: '.\json_encode($stdout));
}
if(!$certificate) {
throw new Exception('Failed saving certificate to DB');
}
if(!@\rename('/etc/letsencrypt/live/'.$domain->get().'/chain.pem', APP_STORAGE_CERTIFICATES.'/'.$domain->get().'/chain.pem')) {
throw new Exception('Failed to rename certificate chain.pem: '.\json_encode($stdout));
}
if(!@\rename('/etc/letsencrypt/live/'.$domain->get().'/fullchain.pem', APP_STORAGE_CERTIFICATES.'/'.$domain->get().'/fullchain.pem')) {
throw new Exception('Failed to rename certificate fullchain.pem: '.\json_encode($stdout));
}
if(!@\rename('/etc/letsencrypt/live/'.$domain->get().'/privkey.pem', APP_STORAGE_CERTIFICATES.'/'.$domain->get().'/privkey.pem')) {
throw new Exception('Failed to rename certificate privkey.pem: '.\json_encode($stdout));
}
$certificate = new Document(\array_merge($certificate, [
'domain' => $domain->get(),
'issueDate' => \time(),
'renewDate' => $renew,
'attempts' => 0,
'log' => \json_encode($stdout),
if(!empty($document)) {
$certificate = new Document(\array_merge($document, [
'updated' => \time(),
'certificateId' => $certificate->getId(),
]));
$certificate = $dbForConsole->createDocument('certificates', $certificate);
$certificate = $dbForConsole->updateDocument('certificates', $certificate->getId(), $certificate);
if(!$certificate) {
throw new Exception('Failed saving certificate to DB');
throw new Exception('Failed saving domain to DB');
}
}
if(!empty($document)) {
$certificate = new Document(\array_merge($document, [
'updated' => \time(),
'certificateId' => $certificate->getId(),
]));
$certificate = $dbForConsole->updateDocument('certificates', $certificate->getId(), $certificate);
if(!$certificate) {
throw new Exception('Failed saving domain to DB');
}
}
$config =
"tls:
certificates:
- certFile: /storage/certificates/{$domain->get()}/fullchain.pem
keyFile: /storage/certificates/{$domain->get()}/privkey.pem";
$config =
"tls:
certificates:
- certFile: /storage/certificates/{$domain->get()}/fullchain.pem
keyFile: /storage/certificates/{$domain->get()}/privkey.pem";
if(!\file_put_contents(APP_STORAGE_CONFIG.'/'.$domain->get().'.yml', $config)) {
throw new Exception('Failed to save SSL configuration');
}
if(!\file_put_contents(APP_STORAGE_CONFIG.'/'.$domain->get().'.yml', $config)) {
throw new Exception('Failed to save SSL configuration');
}
ResqueScheduler::enqueueAt($renew + $safety, 'v1-certificates', 'CertificatesV1', [
'document' => [],
'domain' => $domain->get(),
'validateTarget' => $validateTarget,
'validateCNAME' => $validateCNAME,
]); // Async task rescheduale
ResqueScheduler::enqueueAt($renew + $safety, 'v1-certificates', 'CertificatesV1', [
'document' => [],
'domain' => $domain->get(),
'validateTarget' => $validateTarget,
'validateCNAME' => $validateCNAME,
]); // Async task rescheduale
Authorization::reset();
// Return db connections to pool
$register->get('dbPool')->put($db);
$register->get('redisPool')->put($redis);
});
Authorization::reset();
}
public function shutdown(): void

View file

@ -1,14 +1,10 @@
<?php
use Appwrite\Resque\Worker;
use Utopia\Cache\Cache;
use Utopia\Cache\Adapter\Redis as RedisCache;
use Utopia\CLI\Console;
use Utopia\Database\Database;
use Utopia\Database\Document;
use Utopia\Database\Adapter\MariaDB;
require_once __DIR__.'/../init.php';
require_once __DIR__.'/../workers.php';
Console::title('Database V1 Worker');
Console::success(APP_NAME.' database worker v1 has started'."\n");
@ -131,53 +127,4 @@ class DatabaseV1 extends Worker
$success = $dbForExternal->deleteIndex($collectionId, $id);
}
/**
* @param string $projectId
*
* @return Database
*/
protected function getInternalDB($projectId): Database
{
global $register;
$dbForInternal = null;
go(function() use ($register, $projectId, &$dbForInternal) {
$db = $register->get('dbPool')->get();
$redis = $register->get('redisPool')->get();
$cache = new Cache(new RedisCache($redis));
$dbForInternal = new Database(new MariaDB($db), $cache);
$dbForInternal->setNamespace('project_'.$projectId.'_internal'); // Main DB
});
return $dbForInternal;
}
/**
* @param string $projectId
*
* @return Database
*/
protected function getExternalDB($projectId): Database
{
global $register;
/** @var Database $dbForExternal */
$dbForExternal = null;
go(function() use ($register, $projectId, &$dbForExternal) {
$db = $register->get('dbPool')->get();
$redis = $register->get('redisPool')->get();
$cache = new Cache(new RedisCache($redis));
$dbForExternal = new Database(new MariaDB($db), $cache);
$dbForExternal->setNamespace('project_'.$projectId.'_external'); // Main DB
});
return $dbForExternal;
}
}

View file

@ -3,15 +3,14 @@
use Utopia\Database\Database;
use Utopia\Database\Document;
use Utopia\Database\Query;
use Utopia\Cache\Adapter\Redis as RedisCache;
use Utopia\Database\Validator\Authorization;
use Appwrite\Resque\Worker;
use Utopia\Storage\Device\Local;
use Utopia\Abuse\Abuse;
use Utopia\Abuse\Adapters\TimeLimit;
use Utopia\CLI\Console;
use Utopia\Config\Config;
use Utopia\Audit\Audit;
use Utopia\Cache\Adapter\Redis as RedisCache;
use Utopia\Cache\Cache;
use Utopia\Database\Adapter\MariaDB;

View file

@ -6,11 +6,8 @@ use Appwrite\Utopia\Response\Model\Execution;
use Cron\CronExpression;
use Swoole\Runtime;
use Utopia\App;
use Utopia\Cache\Adapter\Redis;
use Utopia\Cache\Cache;
use Utopia\CLI\Console;
use Utopia\Config\Config;
use Utopia\Database\Adapter\MariaDB;
use Utopia\Database\Database;
use Utopia\Database\Document;
use Utopia\Database\Validator\Authorization;
@ -139,9 +136,6 @@ class FunctionsV1 extends Worker
{
global $register;
$db = $register->get('db');
$cache = $register->get('cache');
$projectId = $this->args['projectId'] ?? '';
$functionId = $this->args['functionId'] ?? '';
$webhooks = $this->args['webhooks'] ?? [];
@ -154,9 +148,7 @@ class FunctionsV1 extends Worker
$userId = $this->args['userId'] ?? '';
$jwt = $this->args['jwt'] ?? '';
$cache = new Cache(new Redis($cache));
$database = new Database(new MariaDB($db), $cache);
$database->setNamespace('project_'.$projectId.'_internal');
$database = $this->getInternalDB($projectId);
switch ($trigger) {
case 'event':
@ -413,15 +405,24 @@ class FunctionsV1 extends Worker
" --workdir /usr/local/src".
" ".\implode(" ", $vars).
" {$runtime['image']}".
" sh -c 'mv /tmp/code.tar.gz /usr/local/src/code.tar.gz && tar -zxf /usr/local/src/code.tar.gz --strip 1 && rm /usr/local/src/code.tar.gz && tail -f /dev/null'"
" tail -f /dev/null"
, '', $stdout, $stderr, 30);
$executionEnd = \microtime(true);
if($exitCode !== 0) {
throw new Exception('Failed to create function environment: '.$stderr);
}
$exitCodeUntar = Console::execute("docker exec ".
$container.
" sh -c 'mv /tmp/code.tar.gz /usr/local/src/code.tar.gz && tar -zxf /usr/local/src/code.tar.gz --strip 1 && rm /usr/local/src/code.tar.gz'"
, '', $stdout, $stderr, 60);
if($exitCodeUntar !== 0) {
throw new Exception('Failed to extract tar: '.$stderr);
}
$executionEnd = \microtime(true);
$list[$container] = [
'name' => $container,
'online' => true,

View file

@ -28,11 +28,6 @@ class TasksV1 extends Worker
public function run(): void
{
global $register;
$db = $register->get('db');
$cache = $register->get('cache');
$projectId = $this->args['projectId'] ?? null;
$taskId = $this->args['$id'] ?? null;
$updated = $this->args['updated'] ?? null;
@ -44,9 +39,7 @@ class TasksV1 extends Worker
$logLimit = 5;
$alert = '';
$cache = new Cache(new Redis($cache));
$dbForConsole = new Database(new MariaDB($db), $cache);
$dbForConsole->setNamespace('project_console_internal');
$dbForConsole = $this->getConsoleDB();
/*
* 1. Get Original Task

56
composer.lock generated
View file

@ -2079,16 +2079,16 @@
},
{
"name": "utopia-php/framework",
"version": "0.16.1",
"version": "0.16.2",
"source": {
"type": "git",
"url": "https://github.com/utopia-php/framework.git",
"reference": "e7440b91077ccf2f4f3908fde4f31d177f8ea692"
"reference": "df02354a670df366b92e2e927fbf128be9a8e64e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/utopia-php/framework/zipball/e7440b91077ccf2f4f3908fde4f31d177f8ea692",
"reference": "e7440b91077ccf2f4f3908fde4f31d177f8ea692",
"url": "https://api.github.com/repos/utopia-php/framework/zipball/df02354a670df366b92e2e927fbf128be9a8e64e",
"reference": "df02354a670df366b92e2e927fbf128be9a8e64e",
"shasum": ""
},
"require": {
@ -2122,9 +2122,9 @@
],
"support": {
"issues": "https://github.com/utopia-php/framework/issues",
"source": "https://github.com/utopia-php/framework/tree/0.16.1"
"source": "https://github.com/utopia-php/framework/tree/0.16.2"
},
"time": "2021-07-18T10:59:00+00:00"
"time": "2021-07-20T10:24:56+00:00"
},
{
"name": "utopia-php/image",
@ -3367,16 +3367,16 @@
},
{
"name": "nikic/php-parser",
"version": "v4.11.0",
"version": "v4.12.0",
"source": {
"type": "git",
"url": "https://github.com/nikic/PHP-Parser.git",
"reference": "fe14cf3672a149364fb66dfe11bf6549af899f94"
"reference": "6608f01670c3cc5079e18c1dab1104e002579143"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/fe14cf3672a149364fb66dfe11bf6549af899f94",
"reference": "fe14cf3672a149364fb66dfe11bf6549af899f94",
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/6608f01670c3cc5079e18c1dab1104e002579143",
"reference": "6608f01670c3cc5079e18c1dab1104e002579143",
"shasum": ""
},
"require": {
@ -3417,9 +3417,9 @@
],
"support": {
"issues": "https://github.com/nikic/PHP-Parser/issues",
"source": "https://github.com/nikic/PHP-Parser/tree/v4.11.0"
"source": "https://github.com/nikic/PHP-Parser/tree/v4.12.0"
},
"time": "2021-07-03T13:36:55+00:00"
"time": "2021-07-21T10:44:31+00:00"
},
{
"name": "openlss/lib-array2xml",
@ -3476,16 +3476,16 @@
},
{
"name": "phar-io/manifest",
"version": "2.0.1",
"version": "2.0.3",
"source": {
"type": "git",
"url": "https://github.com/phar-io/manifest.git",
"reference": "85265efd3af7ba3ca4b2a2c34dbfc5788dd29133"
"reference": "97803eca37d319dfa7826cc2437fc020857acb53"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phar-io/manifest/zipball/85265efd3af7ba3ca4b2a2c34dbfc5788dd29133",
"reference": "85265efd3af7ba3ca4b2a2c34dbfc5788dd29133",
"url": "https://api.github.com/repos/phar-io/manifest/zipball/97803eca37d319dfa7826cc2437fc020857acb53",
"reference": "97803eca37d319dfa7826cc2437fc020857acb53",
"shasum": ""
},
"require": {
@ -3530,9 +3530,9 @@
"description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)",
"support": {
"issues": "https://github.com/phar-io/manifest/issues",
"source": "https://github.com/phar-io/manifest/tree/master"
"source": "https://github.com/phar-io/manifest/tree/2.0.3"
},
"time": "2020-06-27T14:33:11+00:00"
"time": "2021-07-20T11:28:43+00:00"
},
{
"name": "phar-io/version",
@ -5132,6 +5132,7 @@
"type": "github"
}
],
"abandoned": true,
"time": "2020-09-28T06:45:17+00:00"
},
{
@ -5297,16 +5298,16 @@
},
{
"name": "symfony/console",
"version": "v5.3.2",
"version": "v5.3.4",
"source": {
"type": "git",
"url": "https://github.com/symfony/console.git",
"reference": "649730483885ff2ca99ca0560ef0e5f6b03f2ac1"
"reference": "ebd610dacd40d75b6a12bf64b5ccd494fc7d6ab1"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/console/zipball/649730483885ff2ca99ca0560ef0e5f6b03f2ac1",
"reference": "649730483885ff2ca99ca0560ef0e5f6b03f2ac1",
"url": "https://api.github.com/repos/symfony/console/zipball/ebd610dacd40d75b6a12bf64b5ccd494fc7d6ab1",
"reference": "ebd610dacd40d75b6a12bf64b5ccd494fc7d6ab1",
"shasum": ""
},
"require": {
@ -5314,11 +5315,12 @@
"symfony/deprecation-contracts": "^2.1",
"symfony/polyfill-mbstring": "~1.0",
"symfony/polyfill-php73": "^1.8",
"symfony/polyfill-php80": "^1.15",
"symfony/polyfill-php80": "^1.16",
"symfony/service-contracts": "^1.1|^2",
"symfony/string": "^5.1"
},
"conflict": {
"psr/log": ">=3",
"symfony/dependency-injection": "<4.4",
"symfony/dotenv": "<5.1",
"symfony/event-dispatcher": "<4.4",
@ -5326,10 +5328,10 @@
"symfony/process": "<4.4"
},
"provide": {
"psr/log-implementation": "1.0"
"psr/log-implementation": "1.0|2.0"
},
"require-dev": {
"psr/log": "~1.0",
"psr/log": "^1|^2",
"symfony/config": "^4.4|^5.0",
"symfony/dependency-injection": "^4.4|^5.0",
"symfony/event-dispatcher": "^4.4|^5.0",
@ -5375,7 +5377,7 @@
"terminal"
],
"support": {
"source": "https://github.com/symfony/console/tree/v5.3.2"
"source": "https://github.com/symfony/console/tree/v5.3.4"
},
"funding": [
{
@ -5391,7 +5393,7 @@
"type": "tidelift"
}
],
"time": "2021-06-12T09:42:48+00:00"
"time": "2021-07-26T16:33:26+00:00"
},
{
"name": "symfony/deprecation-contracts",

View file

@ -508,17 +508,6 @@ services:
networks:
- appwrite
swagger-validator:
image: 'swaggerapi/swagger-validator-v2:v2.0.5'
container_name: appwrite-swagger-validator
ports:
- '9506:8080'
environment:
- REJECT_LOCAL=false
- REJECT_REDIRECT=false
networks:
- appwrite
# redis-commander:
# image: rediscommander/redis-commander:latest
# restart: unless-stopped

View file

@ -1,5 +1,5 @@
Use this endpoint to invite a new member to join your team. An email with a link to join the team will be sent to the new member email address if the member doesn't exist in the project it will be created automatically.
Use this endpoint to invite a new member to join your team. If initiated from Client SDK, an email with a link to join the team will be sent to the new member's email address if the member doesn't exist in the project it will be created automatically. If initiated from server side SDKs, new member will automatically be added to the team.
Use the 'URL' parameter to redirect the user from the invitation email back to your app. When the user is redirected, use the [Update Team Membership Status](/docs/client/teams#teamsUpdateMembershipStatus) endpoint to allow the user to accept the invitation to the team.
Use the 'URL' parameter to redirect the user from the invitation email back to your app. When the user is redirected, use the [Update Team Membership Status](/docs/client/teams#teamsUpdateMembershipStatus) endpoint to allow the user to accept the invitation to the team. While calling from side SDKs the redirect url can be empty string.
Please note that in order to avoid a [Redirect Attacks](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md) the only valid redirect URL's are the once from domains you have set when added your platforms in the console interface.

View file

@ -2,7 +2,7 @@
namespace Appwrite\Auth;
use Appwrite\Database\Document;
use Utopia\Database\Document;
class Auth
{

View file

@ -40,6 +40,7 @@ abstract class Migration
'0.8.0' => 'V07',
'0.9.0' => 'V08',
'0.9.1' => 'V08',
'0.9.2' => 'V08',
];
/**

View file

@ -2,6 +2,12 @@
namespace Appwrite\Resque;
use Utopia\Cache\Cache;
use Utopia\Cache\Adapter\Redis as RedisCache;
use Utopia\CLI\Console;
use Utopia\Database\Database;
use Utopia\Database\Adapter\MariaDB;
abstract class Worker
{
public $args = [];
@ -12,6 +18,13 @@ abstract class Worker
abstract public function shutdown(): void;
const MAX_ATTEMPTS = 10;
const SLEEP_TIME = 2;
const DATABASE_INTERNAL = 'internal';
const DATABASE_EXTERNAL = 'external';
const DATABASE_CONSOLE = 'console';
public function setUp(): void
{
$this->init();
@ -26,4 +39,91 @@ abstract class Worker
{
$this->shutdown();
}
/**
* Get internal project database
* @param string $projectId
* @return Database
*/
protected function getInternalDB(string $projectId): Database
{
return $this->getDB(self::DATABASE_INTERNAL, $projectId);
}
/**
* Get external project database
* @param string $projectId
* @return Database
*/
protected function getExternalDB(string $projectId): Database
{
return $this->getDB(self::DATABASE_EXTERNAL, $projectId);
}
/**
* Get console database
* @return Database
*/
protected function getConsoleDB(): Database
{
return $this->getDB(self::DATABASE_CONSOLE);
}
/**
* Get console database
* @param string $type One of (internal, external, console)
* @param string $projectId of internal or external DB
* @return Database
*/
private function getDB($type, $projectId = ''): Database
{
global $register;
$namespace = '';
$sleep = self::SLEEP_TIME; // overwritten when necessary
switch ($type) {
case self::DATABASE_INTERNAL:
if (!$projectId) {
throw new \Exception('ProjectID not provided - cannot get database');
}
$namespace = "project_{$projectId}_internal";
break;
case self::DATABASE_EXTERNAL:
if (!$projectId) {
throw new \Exception('ProjectID not provided - cannot get database');
}
$namespace = "project_{$projectId}_external";
break;
case self::DATABASE_CONSOLE:
$namespace = "project_console_internal";
$sleep = 5; // ConsoleDB needs extra sleep time to ensure tables are created
break;
default:
throw new \Exception('Unknown database type: ' . $type);
break;
}
$attempts = 0;
do {
try {
$attempts++;
$cache = new Cache(new RedisCache($register->get('cache')));
$database = new Database(new MariaDB($register->get('db')), $cache);
$database->setNamespace($namespace); // Main DB
if (!$database->exists()) {
throw new \Exception("Table does not exist: {$database->getNamespace()}");
}
break; // leave loop if successful
} catch(\Exception $e) {
Console::warning("Database not ready. Retrying connection ({$attempts})...");
if ($attempts >= self::MAX_ATTEMPTS) {
throw new \Exception('Failed to connect to database: '. $e->getMessage());
}
sleep($sleep);
}
} while ($attempts < self::MAX_ATTEMPTS);
return $database;
}
}

View file

@ -238,7 +238,7 @@ class OpenAPI3 extends Format
$node['schema']['type'] = $validator->getType();
$node['schema']['x-example'] = false;
break;
case 'Appwrite\Database\Validator\UID':
case 'Utopia\Database\Validator\UID':
$node['schema']['type'] = $validator->getType();
$node['schema']['x-example'] = '['.\strtoupper(Template::fromCamelCaseToSnake($node['name'])).']';
break;

View file

@ -234,7 +234,7 @@ class Swagger2 extends Format
$node['type'] = $validator->getType();
$node['x-example'] = false;
break;
case 'Appwrite\Database\Validator\UID':
case 'Utopia\Database\Validator\UID':
$node['type'] = $validator->getType();
$node['x-example'] = '['.\strtoupper(Template::fromCamelCaseToSnake($node['name'])).']';
break;

View file

@ -5,7 +5,7 @@ namespace Appwrite\Utopia;
use Exception;
use Utopia\Swoole\Response as SwooleResponse;
use Swoole\Http\Response as SwooleHTTPResponse;
use Appwrite\Database\Document;
use Utopia\Database\Document;
use Appwrite\Utopia\Response\Filter;
use Appwrite\Utopia\Response\Model;
use Appwrite\Utopia\Response\Model\None;
@ -46,7 +46,6 @@ use Appwrite\Utopia\Response\Model\Webhook;
use Appwrite\Utopia\Response\Model\Preferences;
use Appwrite\Utopia\Response\Model\Mock; // Keep last
use stdClass;
use Utopia\Database\Document as DatabaseDocument;
/**
* @method Response public function setStatusCode(int $code = 200)
@ -290,27 +289,6 @@ class Response extends SwooleResponse
$this->json(!empty($output) ? $output : new stdClass());
}
/**
* Validate response objects and outputs
* the response according to given format type
*
* @param DatabaseDocument $document
* @param string $model
*
* return void
*/
public function dynamic2(DatabaseDocument $document, string $model): void
{
$output = $this->output2($document, $model);
// If filter is set, parse the output
if(self::isFilter()){
$output = self::getFilter()->parse($output, $model);
}
$this->json(!empty($output) ? $output : new stdClass());
}
/**
* Generate valid response object from document data
*
@ -363,58 +341,6 @@ class Response extends SwooleResponse
return $this->payload;
}
/**
* Generate valid response object from document data
*
* @param DatabaseDocument $document
* @param string $model
*
* return array
*/
public function output2(DatabaseDocument $document, string $model): array
{
$data = $document;
$model = $this->getModel($model);
$output = [];
if ($model->isAny()) {
$this->payload = $document->getArrayCopy();
return $this->payload;
}
foreach ($model->getRules() as $key => $rule) {
if (!$document->isSet($key)) {
if (!is_null($rule['default'])) {
$document->setAttribute($key, $rule['default']);
} else {
throw new Exception('Model '.$model->getName().' is missing response key: '.$key);
}
}
if ($rule['array']) {
if (!is_array($data[$key])) {
throw new Exception($key.' must be an array of type '.$rule['type']);
}
foreach ($data[$key] as &$item) {
if ($item instanceof Document) {
if (!array_key_exists($rule['type'], $this->models)) {
throw new Exception('Missing model for rule: '. $rule['type']);
}
$item = $this->output($item, $rule['type']);
}
}
}
$output[$key] = $data[$key];
}
$this->payload = $output;
return $this->payload;
}
/**
* YAML
*

View file

@ -133,7 +133,7 @@ class HTTPTest extends Scope
}
$client = new Client();
$client->setEndpoint('http://appwrite-swagger-validator:8080');
$client->setEndpoint('https://validator.swagger.io');
/**
* Test for SUCCESS

View file

@ -185,7 +185,32 @@ class FunctionsCustomClientTest extends Scope
$this->assertEquals(201, $execution['headers']['status-code']);
$executionId = $execution['body']['$id'] ?? '';
sleep(10);
$executions = $this->client->call(Client::METHOD_GET, '/functions/'.$functionId.'/executions/'.$executionId, [
'content-type' => 'application/json',
'x-appwrite-project' => $projectId,
'x-appwrite-key' => $apikey,
]);
$output = json_decode($executions['body']['stdout'], true);
$this->assertEquals(200, $executions['headers']['status-code']);
$this->assertEquals('completed', $executions['body']['status']);
$this->assertEquals($functionId, $output['APPWRITE_FUNCTION_ID']);
$this->assertEquals('Test', $output['APPWRITE_FUNCTION_NAME']);
$this->assertEquals($tagId, $output['APPWRITE_FUNCTION_TAG']);
$this->assertEquals('http', $output['APPWRITE_FUNCTION_TRIGGER']);
$this->assertEquals('PHP', $output['APPWRITE_FUNCTION_RUNTIME_NAME']);
$this->assertEquals('8.0', $output['APPWRITE_FUNCTION_RUNTIME_VERSION']);
$this->assertEquals('', $output['APPWRITE_FUNCTION_EVENT']);
$this->assertEquals('', $output['APPWRITE_FUNCTION_EVENT_DATA']);
$this->assertEquals('foobar', $output['APPWRITE_FUNCTION_DATA']);
$this->assertEquals($this->getUser()['$id'], $output['APPWRITE_FUNCTION_USER_ID']);
$this->assertNotEmpty($output['APPWRITE_FUNCTION_JWT']);
$executions = $this->client->call(Client::METHOD_GET, '/functions/'.$functionId.'/executions', [
'content-type' => 'application/json',
'x-appwrite-project' => $projectId,

View file

@ -582,8 +582,31 @@ class FunctionsCustomServerTest extends Scope
$this->assertEquals(201, $execution['headers']['status-code']);
$executionId = $execution['body']['$id'] ?? '';
sleep(10);
$executions = $this->client->call(Client::METHOD_GET, '/functions/'.$functionId.'/executions/'.$executionId, array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()));
$output = json_decode($executions['body']['stdout'], true);
$this->assertEquals(200, $executions['headers']['status-code']);
$this->assertEquals('completed', $executions['body']['status']);
$this->assertEquals($functionId, $output['APPWRITE_FUNCTION_ID']);
$this->assertEquals('Test '.$name, $output['APPWRITE_FUNCTION_NAME']);
$this->assertEquals($tagId, $output['APPWRITE_FUNCTION_TAG']);
$this->assertEquals('http', $output['APPWRITE_FUNCTION_TRIGGER']);
$this->assertEquals('PHP', $output['APPWRITE_FUNCTION_RUNTIME_NAME']);
$this->assertEquals('8.0', $output['APPWRITE_FUNCTION_RUNTIME_VERSION']);
$this->assertEquals('', $output['APPWRITE_FUNCTION_EVENT']);
$this->assertEquals('', $output['APPWRITE_FUNCTION_EVENT_DATA']);
$this->assertEquals('foobar', $output['APPWRITE_FUNCTION_DATA']);
$this->assertEquals('', $output['APPWRITE_FUNCTION_USER_ID']);
$this->assertEmpty($output['APPWRITE_FUNCTION_JWT']);
$executions = $this->client->call(Client::METHOD_GET, '/functions/'.$functionId.'/executions', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],

View file

@ -233,12 +233,92 @@ trait WebhooksBase
return $data;
}
public function testCreateFile(): array
public function testCreateStorageBucket(): array
{
/**
* Test for SUCCESS
*/
$file = $this->client->call(Client::METHOD_POST, '/storage/files', array_merge([
$bucket = $this->client->call(Client::METHOD_POST, '/storage/buckets', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
]), [
'name' => 'Test Bucket',
'read' => ['role:all'],
'write' => ['role:all']
]);
$this->assertEquals($bucket['headers']['status-code'], 201);
$this->assertNotEmpty($bucket['body']['$id']);
$webhook = $this->getLastRequest();
$this->assertEquals($webhook['method'], 'POST');
$this->assertEquals($webhook['headers']['Content-Type'], 'application/json');
$this->assertEquals($webhook['headers']['User-Agent'], 'Appwrite-Server vdev. Please report abuse at security@appwrite.io');
$this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Event'], 'storage.buckets.create');
$this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Signature'], 'not-yet-implemented');
$this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Id'] ?? '', $this->getProject()['webhookId']);
$this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Project-Id'] ?? '', $this->getProject()['$id']);
$this->assertEquals(empty($webhook['headers']['X-Appwrite-Webhook-User-Id'] ?? ''), true);
$this->assertNotEmpty($webhook['data']['$id']);
$this->assertEquals('Test Bucket', $webhook['data']['name']);
$this->assertEquals(true, $webhook['data']['enabled']);
$this->assertIsArray($webhook['data']['$read']);
$this->assertIsArray($webhook['data']['$write']);
return array_merge(['bucketId' => $bucket['body']['$id']]);
}
/**
* @depends testCreateStorageBucket
*/
public function testUpdateStorageBucket(array $data): array
{
/**
* Test for SUCCESS
*/
$bucket = $this->client->call(Client::METHOD_PUT, '/storage/buckets/' . $data['bucketId'], array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
]), [
'name' => 'Test Bucket Updated',
'enabled' => false,
]);
$this->assertEquals($bucket['headers']['status-code'], 200);
$this->assertNotEmpty($bucket['body']['$id']);
$webhook = $this->getLastRequest();
$this->assertEquals($webhook['method'], 'POST');
$this->assertEquals($webhook['headers']['Content-Type'], 'application/json');
$this->assertEquals($webhook['headers']['User-Agent'], 'Appwrite-Server vdev. Please report abuse at security@appwrite.io');
$this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Event'], 'storage.buckets.update');
$this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Signature'], 'not-yet-implemented');
$this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Id'] ?? '', $this->getProject()['webhookId']);
$this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Project-Id'] ?? '', $this->getProject()['$id']);
$this->assertEquals(empty($webhook['headers']['X-Appwrite-Webhook-User-Id'] ?? ''), true);
$this->assertNotEmpty($webhook['data']['$id']);
$this->assertEquals('Test Bucket Updated', $webhook['data']['name']);
$this->assertEquals(false, $webhook['data']['enabled']);
$this->assertIsArray($webhook['data']['$read']);
$this->assertIsArray($webhook['data']['$write']);
return array_merge(['bucketId' => $bucket['body']['$id']]);
}
/**
* @depends testCreateStorageBucket
*/
public function testCreateBucketFile(array $data): array
{
/**
* Test for SUCCESS
*/
$file = $this->client->call(Client::METHOD_POST, '/storage/buckets/'. $data['bucketId'] . '/files', array_merge([
'content-type' => 'multipart/form-data',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
@ -273,18 +353,19 @@ trait WebhooksBase
/**
* Test for FAILURE
*/
return ['fileId' => $file['body']['$id']];
$data ['fileId'] = $file['body']['$id'];
return $data;
}
/**
* @depends testCreateFile
* @depends testCreateBucketFile
*/
public function testUpdateFile(array $data): array
public function testUpdateBucketFile(array $data): array
{
/**
* Test for SUCCESS
*/
$file = $this->client->call(Client::METHOD_PUT, '/storage/files/' . $data['fileId'], array_merge([
$file = $this->client->call(Client::METHOD_PUT, '/storage/buckets/' . $data['bucketId'] . '/files/' . $data['fileId'], array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
@ -318,14 +399,14 @@ trait WebhooksBase
}
/**
* @depends testUpdateFile
* @depends testUpdateBucketFile
*/
public function testDeleteFile(array $data): array
public function testDeleteBucketFile(array $data): array
{
/**
* Test for SUCCESS
*/
$file = $this->client->call(Client::METHOD_DELETE, '/storage/files/' . $data['fileId'], array_merge([
$file = $this->client->call(Client::METHOD_DELETE, '/storage/buckets/' . $data['bucketId'] . '/files/' . $data['fileId'], array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()));
@ -355,6 +436,40 @@ trait WebhooksBase
return $data;
}
/**
* @depends testDeleteBucketFile
*/
public function testDeleteStorageBucket(array $data)
{
/**
* Test for SUCCESS
*/
$bucket = $this->client->call(Client::METHOD_DELETE, '/storage/buckets/' . $data['bucketId'] , array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
]));
$this->assertEquals($bucket['headers']['status-code'], 204);
$this->assertEmpty($bucket['body']);
$webhook = $this->getLastRequest();
$this->assertEquals($webhook['method'], 'POST');
$this->assertEquals($webhook['headers']['Content-Type'], 'application/json');
$this->assertEquals($webhook['headers']['User-Agent'], 'Appwrite-Server vdev. Please report abuse at security@appwrite.io');
$this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Event'], 'storage.buckets.delete');
$this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Signature'], 'not-yet-implemented');
$this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Id'] ?? '', $this->getProject()['webhookId']);
$this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Project-Id'] ?? '', $this->getProject()['$id']);
$this->assertEquals(empty($webhook['headers']['X-Appwrite-Webhook-User-Id'] ?? ''), true);
$this->assertNotEmpty($webhook['data']['$id']);
$this->assertEquals('Test Bucket Updated', $webhook['data']['name']);
$this->assertEquals(false, $webhook['data']['enabled']);
$this->assertIsArray($webhook['data']['$read']);
$this->assertIsArray($webhook['data']['$write']);
}
public function testCreateTeam(): array
{
/**
@ -586,114 +701,4 @@ trait WebhooksBase
*/
return [];
}
public function testCreateStorageBucket(): array
{
/**
* Test for SUCCESS
*/
$bucket = $this->client->call(Client::METHOD_POST, '/storage/buckets', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
]), [
'name' => 'Test Bucket',
]);
$this->assertEquals($bucket['headers']['status-code'], 201);
$this->assertNotEmpty($bucket['body']['$id']);
$webhook = $this->getLastRequest();
$this->assertEquals($webhook['method'], 'POST');
$this->assertEquals($webhook['headers']['Content-Type'], 'application/json');
$this->assertEquals($webhook['headers']['User-Agent'], 'Appwrite-Server vdev. Please report abuse at security@appwrite.io');
$this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Event'], 'storage.buckets.create');
$this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Signature'], 'not-yet-implemented');
$this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Id'] ?? '', $this->getProject()['webhookId']);
$this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Project-Id'] ?? '', $this->getProject()['$id']);
$this->assertEquals(empty($webhook['headers']['X-Appwrite-Webhook-User-Id'] ?? ''), true);
$this->assertNotEmpty($webhook['data']['$id']);
$this->assertEquals('Test Bucket', $webhook['data']['name']);
$this->assertEquals(true, $webhook['data']['enabled']);
$this->assertIsArray($webhook['data']['$read']);
$this->assertIsArray($webhook['data']['$write']);
return array_merge(['bucketId' => $bucket['body']['$id']]);
}
/**
* @depends testCreateStorageBucket
*/
public function testUpdateStorageBucket(array $data): array
{
$id = $data['bucketId'];
/**
* Test for SUCCESS
*/
$bucket = $this->client->call(Client::METHOD_PUT, '/storage/buckets/' . $id, array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
]), [
'name' => 'Test Bucket Updated',
'enabled' => false,
]);
$this->assertEquals($bucket['headers']['status-code'], 200);
$this->assertNotEmpty($bucket['body']['$id']);
$webhook = $this->getLastRequest();
$this->assertEquals($webhook['method'], 'POST');
$this->assertEquals($webhook['headers']['Content-Type'], 'application/json');
$this->assertEquals($webhook['headers']['User-Agent'], 'Appwrite-Server vdev. Please report abuse at security@appwrite.io');
$this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Event'], 'storage.buckets.update');
$this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Signature'], 'not-yet-implemented');
$this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Id'] ?? '', $this->getProject()['webhookId']);
$this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Project-Id'] ?? '', $this->getProject()['$id']);
$this->assertEquals(empty($webhook['headers']['X-Appwrite-Webhook-User-Id'] ?? ''), true);
$this->assertNotEmpty($webhook['data']['$id']);
$this->assertEquals('Test Bucket Updated', $webhook['data']['name']);
$this->assertEquals(false, $webhook['data']['enabled']);
$this->assertIsArray($webhook['data']['$read']);
$this->assertIsArray($webhook['data']['$write']);
return array_merge(['bucketId' => $bucket['body']['$id']]);
}
/**
* @depends testCreateStorageBucket
*/
public function testDeleteStorageBucket(array $data)
{
$id = $data['bucketId'];
/**
* Test for SUCCESS
*/
$bucket = $this->client->call(Client::METHOD_DELETE, '/storage/buckets/' . $id, array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
]));
$this->assertEquals($bucket['headers']['status-code'], 204);
$this->assertEmpty($bucket['body']);
$webhook = $this->getLastRequest();
$this->assertEquals($webhook['method'], 'POST');
$this->assertEquals($webhook['headers']['Content-Type'], 'application/json');
$this->assertEquals($webhook['headers']['User-Agent'], 'Appwrite-Server vdev. Please report abuse at security@appwrite.io');
$this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Event'], 'storage.buckets.delete');
$this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Signature'], 'not-yet-implemented');
$this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Id'] ?? '', $this->getProject()['webhookId']);
$this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Project-Id'] ?? '', $this->getProject()['$id']);
$this->assertEquals(empty($webhook['headers']['X-Appwrite-Webhook-User-Id'] ?? ''), true);
$this->assertNotEmpty($webhook['data']['$id']);
$this->assertEquals('Test Bucket Updated', $webhook['data']['name']);
$this->assertEquals(false, $webhook['data']['enabled']);
$this->assertIsArray($webhook['data']['$read']);
$this->assertIsArray($webhook['data']['$write']);
}
}

View file

@ -17,15 +17,18 @@ use Appwrite\Services\Storage;
// $result = $storage->getFile($_ENV['APPWRITE_FILEID']);
echo $_ENV['APPWRITE_FUNCTION_ID']."\n";
echo $_ENV['APPWRITE_FUNCTION_NAME']."\n";
echo $_ENV['APPWRITE_FUNCTION_TAG']."\n";
echo $_ENV['APPWRITE_FUNCTION_TRIGGER']."\n";
echo $_ENV['APPWRITE_FUNCTION_RUNTIME_NAME']."\n";
echo $_ENV['APPWRITE_FUNCTION_RUNTIME_VERSION']."\n";
// echo $result['$id'];
echo $_ENV['APPWRITE_FUNCTION_EVENT']."\n";
echo $_ENV['APPWRITE_FUNCTION_EVENT_DATA']."\n";
echo 'data:'.$_ENV['APPWRITE_FUNCTION_DATA']."\n";
echo 'userId:'.$_ENV['APPWRITE_FUNCTION_USER_ID']."\n";
echo 'jwt:'.$_ENV['APPWRITE_FUNCTION_JWT']."\n";
$output = [
'APPWRITE_FUNCTION_ID' => $_ENV['APPWRITE_FUNCTION_ID'],
'APPWRITE_FUNCTION_NAME' => $_ENV['APPWRITE_FUNCTION_NAME'],
'APPWRITE_FUNCTION_TAG' => $_ENV['APPWRITE_FUNCTION_TAG'],
'APPWRITE_FUNCTION_TRIGGER' => $_ENV['APPWRITE_FUNCTION_TRIGGER'],
'APPWRITE_FUNCTION_RUNTIME_NAME' => $_ENV['APPWRITE_FUNCTION_RUNTIME_NAME'],
'APPWRITE_FUNCTION_RUNTIME_VERSION' => $_ENV['APPWRITE_FUNCTION_RUNTIME_VERSION'],
'APPWRITE_FUNCTION_EVENT' => $_ENV['APPWRITE_FUNCTION_EVENT'],
'APPWRITE_FUNCTION_EVENT_DATA' => $_ENV['APPWRITE_FUNCTION_EVENT_DATA'],
'APPWRITE_FUNCTION_DATA' => $_ENV['APPWRITE_FUNCTION_DATA'],
'APPWRITE_FUNCTION_USER_ID' => $_ENV['APPWRITE_FUNCTION_USER_ID'],
'APPWRITE_FUNCTION_JWT' => $_ENV['APPWRITE_FUNCTION_JWT'],
];
echo json_encode($output);