Merge pull request #3380 from appwrite/origin/feat-internal-id
Origin/feat internal ids for account / teams / users
This commit is contained in:
commit
e7f328c2fe
|
@ -97,6 +97,17 @@ $collections = [
|
|||
'$id' => 'attributes',
|
||||
'name' => 'Attributes',
|
||||
'attributes' => [
|
||||
[
|
||||
'$id' => 'collectionInternalId',
|
||||
'type' => Database::VAR_STRING,
|
||||
'format' => '',
|
||||
'size' => Database::LENGTH_KEY,
|
||||
'signed' => true,
|
||||
'required' => false,
|
||||
'default' => null,
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => 'collectionId',
|
||||
'type' => Database::VAR_STRING,
|
||||
|
@ -229,7 +240,7 @@ $collections = [
|
|||
[
|
||||
'$id' => '_key_collection',
|
||||
'type' => Database::INDEX_KEY,
|
||||
'attributes' => ['collectionId'],
|
||||
'attributes' => ['collectionInternalId'],
|
||||
'lengths' => [Database::LENGTH_KEY],
|
||||
'orders' => [Database::ORDER_ASC],
|
||||
],
|
||||
|
@ -241,6 +252,17 @@ $collections = [
|
|||
'$id' => 'indexes',
|
||||
'name' => 'Indexes',
|
||||
'attributes' => [
|
||||
[
|
||||
'$id' => 'collectionInternalId',
|
||||
'type' => Database::VAR_STRING,
|
||||
'format' => '',
|
||||
'size' => Database::LENGTH_KEY,
|
||||
'signed' => true,
|
||||
'required' => false,
|
||||
'default' => null,
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => 'collectionId',
|
||||
'type' => Database::VAR_STRING,
|
||||
|
@ -323,10 +345,10 @@ $collections = [
|
|||
[
|
||||
'$id' => '_key_collection',
|
||||
'type' => Database::INDEX_KEY,
|
||||
'attributes' => ['collectionId'],
|
||||
'attributes' => ['collectionInternalId'],
|
||||
'lengths' => [Database::LENGTH_KEY],
|
||||
'orders' => [Database::ORDER_ASC],
|
||||
],
|
||||
]
|
||||
],
|
||||
],
|
||||
|
||||
|
@ -335,6 +357,17 @@ $collections = [
|
|||
'$id' => 'projects',
|
||||
'name' => 'Projects',
|
||||
'attributes' => [
|
||||
[
|
||||
'$id' => 'teamInternalId',
|
||||
'type' => Database::VAR_STRING,
|
||||
'format' => '',
|
||||
'size' => Database::LENGTH_KEY,
|
||||
'signed' => true,
|
||||
'required' => false,
|
||||
'default' => null,
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => 'teamId',
|
||||
'type' => Database::VAR_STRING,
|
||||
|
@ -572,6 +605,17 @@ $collections = [
|
|||
'$id' => 'platforms',
|
||||
'name' => 'platforms',
|
||||
'attributes' => [
|
||||
[
|
||||
'$id' => 'projectInternalId',
|
||||
'type' => Database::VAR_STRING,
|
||||
'format' => '',
|
||||
'size' => Database::LENGTH_KEY,
|
||||
'signed' => true,
|
||||
'required' => false,
|
||||
'default' => null,
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => 'projectId',
|
||||
'type' => Database::VAR_STRING,
|
||||
|
@ -643,7 +687,7 @@ $collections = [
|
|||
[
|
||||
'$id' => '_key_project',
|
||||
'type' => Database::INDEX_KEY,
|
||||
'attributes' => ['projectId'],
|
||||
'attributes' => ['projectInternalId'],
|
||||
'lengths' => [Database::LENGTH_KEY],
|
||||
'orders' => [Database::ORDER_ASC],
|
||||
],
|
||||
|
@ -655,6 +699,17 @@ $collections = [
|
|||
'$id' => 'domains',
|
||||
'name' => 'domains',
|
||||
'attributes' => [
|
||||
[
|
||||
'$id' => 'projectInternalId',
|
||||
'type' => Database::VAR_STRING,
|
||||
'format' => '',
|
||||
'size' => Database::LENGTH_KEY,
|
||||
'signed' => true,
|
||||
'required' => false,
|
||||
'default' => null,
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => 'projectId',
|
||||
'type' => Database::VAR_STRING,
|
||||
|
@ -737,7 +792,7 @@ $collections = [
|
|||
[
|
||||
'$id' => '_key_project',
|
||||
'type' => Database::INDEX_KEY,
|
||||
'attributes' => ['projectId'],
|
||||
'attributes' => ['projectInternalId'],
|
||||
'lengths' => [Database::LENGTH_KEY],
|
||||
'orders' => [Database::ORDER_ASC],
|
||||
],
|
||||
|
@ -749,6 +804,17 @@ $collections = [
|
|||
'$id' => 'keys',
|
||||
'name' => 'keys',
|
||||
'attributes' => [
|
||||
[
|
||||
'$id' => 'projectInternalId',
|
||||
'type' => Database::VAR_STRING,
|
||||
'format' => '',
|
||||
'size' => Database::LENGTH_KEY,
|
||||
'signed' => true,
|
||||
'required' => false,
|
||||
'default' => null,
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => 'projectId',
|
||||
'type' => Database::VAR_STRING,
|
||||
|
@ -809,7 +875,7 @@ $collections = [
|
|||
[
|
||||
'$id' => '_key_project',
|
||||
'type' => Database::INDEX_KEY,
|
||||
'attributes' => ['projectId'],
|
||||
'attributes' => ['projectInternalId'],
|
||||
'lengths' => [Database::LENGTH_KEY],
|
||||
'orders' => [Database::ORDER_ASC],
|
||||
],
|
||||
|
@ -821,6 +887,17 @@ $collections = [
|
|||
'$id' => 'webhooks',
|
||||
'name' => 'webhooks',
|
||||
'attributes' => [
|
||||
[
|
||||
'$id' => 'projectInternalId',
|
||||
'type' => Database::VAR_STRING,
|
||||
'format' => '',
|
||||
'size' => Database::LENGTH_KEY,
|
||||
'signed' => true,
|
||||
'required' => false,
|
||||
'default' => null,
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => 'projectId',
|
||||
'type' => Database::VAR_STRING,
|
||||
|
@ -914,10 +991,10 @@ $collections = [
|
|||
[
|
||||
'$id' => '_key_project',
|
||||
'type' => Database::INDEX_KEY,
|
||||
'attributes' => ['projectId'],
|
||||
'attributes' => ['projectInternalId'],
|
||||
'lengths' => [Database::LENGTH_KEY],
|
||||
'orders' => [Database::ORDER_ASC],
|
||||
],
|
||||
]
|
||||
],
|
||||
],
|
||||
|
||||
|
@ -1093,6 +1170,17 @@ $collections = [
|
|||
'$id' => 'tokens',
|
||||
'name' => 'Tokens',
|
||||
'attributes' => [
|
||||
[
|
||||
'$id' => 'userInternalId',
|
||||
'type' => Database::VAR_STRING,
|
||||
'format' => '',
|
||||
'size' => Database::LENGTH_KEY,
|
||||
'signed' => true,
|
||||
'required' => false,
|
||||
'default' => null,
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => 'userId',
|
||||
'type' => Database::VAR_STRING,
|
||||
|
@ -1164,7 +1252,7 @@ $collections = [
|
|||
[
|
||||
'$id' => '_key_user',
|
||||
'type' => Database::INDEX_KEY,
|
||||
'attributes' => ['userId'],
|
||||
'attributes' => ['userInternalId'],
|
||||
'lengths' => [Database::LENGTH_KEY],
|
||||
'orders' => [Database::ORDER_ASC],
|
||||
],
|
||||
|
@ -1176,6 +1264,17 @@ $collections = [
|
|||
'$id' => 'sessions',
|
||||
'name' => 'Sessions',
|
||||
'attributes' => [
|
||||
[
|
||||
'$id' => 'userInternalId',
|
||||
'type' => Database::VAR_STRING,
|
||||
'format' => '',
|
||||
'size' => Database::LENGTH_KEY,
|
||||
'signed' => true,
|
||||
'required' => false,
|
||||
'default' => null,
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => 'userId',
|
||||
'type' => Database::VAR_STRING,
|
||||
|
@ -1441,7 +1540,7 @@ $collections = [
|
|||
[
|
||||
'$id' => '_key_user',
|
||||
'type' => Database::INDEX_KEY,
|
||||
'attributes' => ['userId'],
|
||||
'attributes' => ['userInternalId'],
|
||||
'lengths' => [Database::LENGTH_KEY],
|
||||
'orders' => [Database::ORDER_ASC],
|
||||
],
|
||||
|
@ -1504,7 +1603,7 @@ $collections = [
|
|||
'name' => 'Memberships',
|
||||
'attributes' => [
|
||||
[
|
||||
'$id' => 'teamId',
|
||||
'$id' => 'userInternalId',
|
||||
'type' => Database::VAR_STRING,
|
||||
'format' => '',
|
||||
'size' => Database::LENGTH_KEY,
|
||||
|
@ -1525,6 +1624,28 @@ $collections = [
|
|||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => 'teamInternalId',
|
||||
'type' => Database::VAR_STRING,
|
||||
'format' => '',
|
||||
'size' => Database::LENGTH_KEY,
|
||||
'signed' => true,
|
||||
'required' => false,
|
||||
'default' => null,
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => 'teamId',
|
||||
'type' => Database::VAR_STRING,
|
||||
'format' => '',
|
||||
'size' => Database::LENGTH_KEY,
|
||||
'signed' => true,
|
||||
'required' => false,
|
||||
'default' => null,
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => 'roles',
|
||||
'type' => Database::VAR_STRING,
|
||||
|
@ -1596,21 +1717,21 @@ $collections = [
|
|||
[
|
||||
'$id' => '_key_unique',
|
||||
'type' => Database::INDEX_UNIQUE,
|
||||
'attributes' => ['teamId', 'userId'],
|
||||
'attributes' => ['teamInternalId', 'userInternalId'],
|
||||
'lengths' => [Database::LENGTH_KEY, Database::LENGTH_KEY],
|
||||
'orders' => [Database::ORDER_ASC, Database::ORDER_ASC],
|
||||
],
|
||||
[
|
||||
'$id' => '_key_team',
|
||||
'$id' => '_key_internal',
|
||||
'type' => Database::INDEX_KEY,
|
||||
'attributes' => ['teamId'],
|
||||
'attributes' => ['userInternalId'],
|
||||
'lengths' => [Database::LENGTH_KEY],
|
||||
'orders' => [Database::ORDER_ASC],
|
||||
],
|
||||
[
|
||||
'$id' => '_key_user',
|
||||
'$id' => '_key_team',
|
||||
'type' => Database::INDEX_KEY,
|
||||
'attributes' => ['userId'],
|
||||
'attributes' => ['teamInternalId'],
|
||||
'lengths' => [Database::LENGTH_KEY],
|
||||
'orders' => [Database::ORDER_ASC],
|
||||
],
|
||||
|
@ -1660,7 +1781,6 @@ $collections = [
|
|||
'signed' => true,
|
||||
'required' => false,
|
||||
'default' => null,
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
|
@ -1821,7 +1941,6 @@ $collections = [
|
|||
'signed' => true,
|
||||
'required' => false,
|
||||
'default' => null,
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
|
@ -2101,7 +2220,6 @@ $collections = [
|
|||
'signed' => true,
|
||||
'required' => false,
|
||||
'default' => null,
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
|
@ -2529,7 +2647,6 @@ $collections = [
|
|||
'signed' => true,
|
||||
'required' => false,
|
||||
'default' => null,
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
|
|
|
@ -178,6 +178,7 @@ App::post('/v1/account/sessions')
|
|||
[
|
||||
'$id' => $dbForProject->getId(),
|
||||
'userId' => $profile->getId(),
|
||||
'userInternalId' => $profile->getInternalId(),
|
||||
'provider' => Auth::SESSION_PROVIDER_EMAIL,
|
||||
'providerUid' => $email,
|
||||
'secret' => Auth::hash($secret), // One way hash encryption to protect DB leak
|
||||
|
@ -507,6 +508,7 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect')
|
|||
$session = new Document(array_merge([
|
||||
'$id' => $dbForProject->getId(),
|
||||
'userId' => $user->getId(),
|
||||
'userInternalId' => $user->getInternalId(),
|
||||
'provider' => $provider,
|
||||
'providerUid' => $oauth2ID,
|
||||
'providerAccessToken' => $accessToken,
|
||||
|
@ -661,6 +663,7 @@ App::post('/v1/account/sessions/magic-url')
|
|||
$token = new Document([
|
||||
'$id' => $dbForProject->getId(),
|
||||
'userId' => $user->getId(),
|
||||
'userInternalId' => $user->getInternalId(),
|
||||
'type' => Auth::TOKEN_TYPE_MAGIC_URL,
|
||||
'secret' => Auth::hash($loginSecret), // One way hash encryption to protect DB leak
|
||||
'expire' => $expire,
|
||||
|
@ -738,6 +741,8 @@ App::put('/v1/account/sessions/magic-url')
|
|||
->inject('events')
|
||||
->action(function (string $userId, string $secret, Request $request, Response $response, Database $dbForProject, Locale $locale, Reader $geodb, Audit $audits, Event $events) {
|
||||
|
||||
/** @var Utopia\Database\Document $user */
|
||||
|
||||
$user = Authorization::skip(fn() => $dbForProject->getDocument('users', $userId));
|
||||
|
||||
if ($user->isEmpty()) {
|
||||
|
@ -758,6 +763,7 @@ App::put('/v1/account/sessions/magic-url')
|
|||
[
|
||||
'$id' => $dbForProject->getId(),
|
||||
'userId' => $user->getId(),
|
||||
'userInternalId' => $user->getInternalId(),
|
||||
'provider' => Auth::SESSION_PROVIDER_MAGIC_URL,
|
||||
'secret' => Auth::hash($secret), // One way hash encryption to protect DB leak
|
||||
'expire' => $expiry,
|
||||
|
@ -901,6 +907,7 @@ App::post('/v1/account/sessions/anonymous')
|
|||
[
|
||||
'$id' => $dbForProject->getId(),
|
||||
'userId' => $user->getId(),
|
||||
'userInternalId' => $user->getInternalId(),
|
||||
'provider' => Auth::SESSION_PROVIDER_ANONYMOUS,
|
||||
'secret' => Auth::hash($secret), // One way hash encryption to protect DB leak
|
||||
'expire' => $expiry,
|
||||
|
@ -1679,6 +1686,7 @@ App::post('/v1/account/recovery')
|
|||
$recovery = new Document([
|
||||
'$id' => $dbForProject->getId(),
|
||||
'userId' => $profile->getId(),
|
||||
'userInternalId' => $profile->getInternalId(),
|
||||
'type' => Auth::TOKEN_TYPE_RECOVERY,
|
||||
'secret' => Auth::hash($secret), // One way hash encryption to protect DB leak
|
||||
'expire' => $expire,
|
||||
|
@ -1839,6 +1847,7 @@ App::post('/v1/account/verification')
|
|||
$verification = new Document([
|
||||
'$id' => $dbForProject->getId(),
|
||||
'userId' => $user->getId(),
|
||||
'userInternalId' => $user->getInternalId(),
|
||||
'type' => Auth::TOKEN_TYPE_VERIFICATION,
|
||||
'secret' => Auth::hash($verificationSecret), // One way hash encryption to protect DB leak
|
||||
'expire' => $expire,
|
||||
|
|
|
@ -47,6 +47,7 @@ use MaxMind\Db\Reader;
|
|||
*
|
||||
*
|
||||
* @return Document Newly created attribute document
|
||||
* @throws Exception
|
||||
*/
|
||||
function createAttribute(string $collectionId, Document $attribute, Response $response, Database $dbForProject, EventDatabase $database, EventAudit $audits, Event $events, Stats $usage): Document
|
||||
{
|
||||
|
@ -84,8 +85,9 @@ function createAttribute(string $collectionId, Document $attribute, Response $re
|
|||
|
||||
try {
|
||||
$attribute = new Document([
|
||||
'$id' => $collectionId . '_' . $key,
|
||||
'$id' => $collection->getInternalId() . '_' . $key,
|
||||
'key' => $key,
|
||||
'collectionInternalId' => $collection->getInternalId(),
|
||||
'collectionId' => $collectionId,
|
||||
'type' => $type,
|
||||
'status' => 'processing', // processing, available, failed, deleting, stuck
|
||||
|
@ -1117,7 +1119,7 @@ App::get('/v1/database/collections/:collectionId/attributes/:key')
|
|||
throw new Exception('Collection not found', 404, Exception::COLLECTION_NOT_FOUND);
|
||||
}
|
||||
|
||||
$attribute = $dbForProject->getDocument('attributes', $collectionId . '_' . $key);
|
||||
$attribute = $dbForProject->getDocument('attributes', $collection->getInternalId() . '_' . $key);
|
||||
|
||||
if ($attribute->isEmpty()) {
|
||||
throw new Exception('Attribute not found', 404, Exception::ATTRIBUTE_NOT_FOUND);
|
||||
|
@ -1173,7 +1175,7 @@ App::delete('/v1/database/collections/:collectionId/attributes/:key')
|
|||
throw new Exception('Collection not found', 404, Exception::COLLECTION_NOT_FOUND);
|
||||
}
|
||||
|
||||
$attribute = $dbForProject->getDocument('attributes', $collectionId . '_' . $key);
|
||||
$attribute = $dbForProject->getDocument('attributes', $collection->getInternalId() . '_' . $key);
|
||||
|
||||
if ($attribute->isEmpty()) {
|
||||
throw new Exception('Attribute not found', 404, Exception::ATTRIBUTE_NOT_FOUND);
|
||||
|
@ -1260,8 +1262,8 @@ App::post('/v1/database/collections/:collectionId/indexes')
|
|||
}
|
||||
|
||||
$count = $dbForProject->count('indexes', [
|
||||
new Query('collectionId', Query::TYPE_EQUAL, [$collectionId])
|
||||
], 61);
|
||||
new Query('collectionInternalId', Query::TYPE_EQUAL, [$collection->getInternalId()])
|
||||
]);
|
||||
|
||||
$limit = 64 - MariaDB::getNumberOfDefaultIndexes();
|
||||
|
||||
|
@ -1298,9 +1300,10 @@ App::post('/v1/database/collections/:collectionId/indexes')
|
|||
|
||||
try {
|
||||
$index = $dbForProject->createDocument('indexes', new Document([
|
||||
'$id' => $collectionId . '_' . $key,
|
||||
'$id' => $collection->getInternalId() . '_' . $key,
|
||||
'key' => $key,
|
||||
'status' => 'processing', // processing, available, failed, deleting, stuck
|
||||
'collectionInternalId' => $collection->getInternalId(),
|
||||
'collectionId' => $collectionId,
|
||||
'type' => $type,
|
||||
'attributes' => $attributes,
|
||||
|
@ -1438,7 +1441,7 @@ App::delete('/v1/database/collections/:collectionId/indexes/:key')
|
|||
throw new Exception('Collection not found', 404, Exception::COLLECTION_NOT_FOUND);
|
||||
}
|
||||
|
||||
$index = $dbForProject->getDocument('indexes', $collectionId . '_' . $key);
|
||||
$index = $dbForProject->getDocument('indexes', $collection->getInternalId() . '_' . $key);
|
||||
|
||||
if (empty($index->getId())) {
|
||||
throw new Exception('Index not found', 404, Exception::INDEX_NOT_FOUND);
|
||||
|
|
|
@ -78,14 +78,17 @@ App::post('/v1/projects')
|
|||
}
|
||||
|
||||
$projectId = ($projectId == 'unique()') ? $dbForConsole->getId() : $projectId;
|
||||
|
||||
if ($projectId === 'console') {
|
||||
throw new Exception("'console' is a reserved project.", 400, Exception::PROJECT_RESERVED_PROJECT);
|
||||
}
|
||||
|
||||
$project = $dbForConsole->createDocument('projects', new Document([
|
||||
'$id' => $projectId == 'unique()' ? $dbForConsole->getId() : $projectId,
|
||||
'$id' => $projectId,
|
||||
'$read' => ['team:' . $teamId],
|
||||
'$write' => ['team:' . $teamId . '/owner', 'team:' . $teamId . '/developer'],
|
||||
'name' => $name,
|
||||
'teamInternalId' => $team->getInternalId(),
|
||||
'teamId' => $team->getId(),
|
||||
'description' => $description,
|
||||
'logo' => $logo,
|
||||
|
@ -109,7 +112,7 @@ App::post('/v1/projects')
|
|||
/** @var array $collections */
|
||||
$collections = Config::getParam('collections', []);
|
||||
|
||||
$dbForProject->setNamespace("_{$project->getId()}");
|
||||
$dbForProject->setNamespace("_{$project->getInternalId()}");
|
||||
$dbForProject->create('appwrite');
|
||||
|
||||
$audit = new Audit($dbForProject);
|
||||
|
@ -268,7 +271,7 @@ App::get('/v1/projects/:projectId/usage')
|
|||
],
|
||||
];
|
||||
|
||||
$dbForProject->setNamespace("_{$projectId}");
|
||||
$dbForProject->setNamespace("_{$project->getInternalId()}");
|
||||
|
||||
$metrics = [
|
||||
'requests',
|
||||
|
@ -589,6 +592,7 @@ App::post('/v1/projects/:projectId/webhooks')
|
|||
'$id' => $dbForConsole->getId(),
|
||||
'$read' => ['role:all'],
|
||||
'$write' => ['role:all'],
|
||||
'projectInternalId' => $project->getInternalId(),
|
||||
'projectId' => $project->getId(),
|
||||
'name' => $name,
|
||||
'events' => $events,
|
||||
|
@ -629,7 +633,7 @@ App::get('/v1/projects/:projectId/webhooks')
|
|||
}
|
||||
|
||||
$webhooks = $dbForConsole->find('webhooks', [
|
||||
new Query('projectId', Query::TYPE_EQUAL, [$project->getId()])
|
||||
new Query('projectInternalId', Query::TYPE_EQUAL, [$project->getInternalId()])
|
||||
], 5000);
|
||||
|
||||
$response->dynamic(new Document([
|
||||
|
@ -662,7 +666,7 @@ App::get('/v1/projects/:projectId/webhooks/:webhookId')
|
|||
|
||||
$webhook = $dbForConsole->findOne('webhooks', [
|
||||
new Query('_uid', Query::TYPE_EQUAL, [$webhookId]),
|
||||
new Query('projectId', Query::TYPE_EQUAL, [$project->getId()])
|
||||
new Query('projectInternalId', Query::TYPE_EQUAL, [$project->getInternalId()])
|
||||
]);
|
||||
|
||||
if ($webhook === false || $webhook->isEmpty()) {
|
||||
|
@ -705,7 +709,7 @@ App::put('/v1/projects/:projectId/webhooks/:webhookId')
|
|||
|
||||
$webhook = $dbForConsole->findOne('webhooks', [
|
||||
new Query('_uid', Query::TYPE_EQUAL, [$webhookId]),
|
||||
new Query('projectId', Query::TYPE_EQUAL, [$project->getId()])
|
||||
new Query('projectInternalId', Query::TYPE_EQUAL, [$project->getInternalId()])
|
||||
]);
|
||||
|
||||
if ($webhook === false || $webhook->isEmpty()) {
|
||||
|
@ -754,7 +758,7 @@ App::delete('/v1/projects/:projectId/webhooks/:webhookId')
|
|||
|
||||
$webhook = $dbForConsole->findOne('webhooks', [
|
||||
new Query('_uid', Query::TYPE_EQUAL, [$webhookId]),
|
||||
new Query('projectId', Query::TYPE_EQUAL, [$project->getId()])
|
||||
new Query('projectInternalId', Query::TYPE_EQUAL, [$project->getInternalId()])
|
||||
]);
|
||||
|
||||
if ($webhook === false || $webhook->isEmpty()) {
|
||||
|
@ -798,6 +802,7 @@ App::post('/v1/projects/:projectId/keys')
|
|||
'$id' => $dbForConsole->getId(),
|
||||
'$read' => ['role:all'],
|
||||
'$write' => ['role:all'],
|
||||
'projectInternalId' => $project->getInternalId(),
|
||||
'projectId' => $project->getId(),
|
||||
'name' => $name,
|
||||
'scopes' => $scopes,
|
||||
|
@ -835,7 +840,7 @@ App::get('/v1/projects/:projectId/keys')
|
|||
}
|
||||
|
||||
$keys = $dbForConsole->find('keys', [
|
||||
new Query('projectId', Query::TYPE_EQUAL, [$project->getId()]),
|
||||
new Query('projectInternalId', Query::TYPE_EQUAL, [$project->getInternalId()]),
|
||||
], 5000);
|
||||
|
||||
$response->dynamic(new Document([
|
||||
|
@ -868,7 +873,7 @@ App::get('/v1/projects/:projectId/keys/:keyId')
|
|||
|
||||
$key = $dbForConsole->findOne('keys', [
|
||||
new Query('_uid', Query::TYPE_EQUAL, [$keyId]),
|
||||
new Query('projectId', Query::TYPE_EQUAL, [$project->getId()])
|
||||
new Query('projectInternalId', Query::TYPE_EQUAL, [$project->getInternalId()])
|
||||
]);
|
||||
|
||||
if ($key === false || $key->isEmpty()) {
|
||||
|
@ -905,7 +910,7 @@ App::put('/v1/projects/:projectId/keys/:keyId')
|
|||
|
||||
$key = $dbForConsole->findOne('keys', [
|
||||
new Query('_uid', Query::TYPE_EQUAL, [$keyId]),
|
||||
new Query('projectId', Query::TYPE_EQUAL, [$project->getId()])
|
||||
new Query('projectInternalId', Query::TYPE_EQUAL, [$project->getInternalId()])
|
||||
]);
|
||||
|
||||
if ($key === false || $key->isEmpty()) {
|
||||
|
@ -948,7 +953,7 @@ App::delete('/v1/projects/:projectId/keys/:keyId')
|
|||
|
||||
$key = $dbForConsole->findOne('keys', [
|
||||
new Query('_uid', Query::TYPE_EQUAL, [$keyId]),
|
||||
new Query('projectId', Query::TYPE_EQUAL, [$project->getId()])
|
||||
new Query('projectInternalId', Query::TYPE_EQUAL, [$project->getInternalId()])
|
||||
]);
|
||||
|
||||
if ($key === false || $key->isEmpty()) {
|
||||
|
@ -993,6 +998,7 @@ App::post('/v1/projects/:projectId/platforms')
|
|||
'$id' => $dbForConsole->getId(),
|
||||
'$read' => ['role:all'],
|
||||
'$write' => ['role:all'],
|
||||
'projectInternalId' => $project->getInternalId(),
|
||||
'projectId' => $project->getId(),
|
||||
'type' => $type,
|
||||
'name' => $name,
|
||||
|
@ -1064,7 +1070,7 @@ App::get('/v1/projects/:projectId/platforms/:platformId')
|
|||
|
||||
$platform = $dbForConsole->findOne('platforms', [
|
||||
new Query('_uid', Query::TYPE_EQUAL, [$platformId]),
|
||||
new Query('projectId', Query::TYPE_EQUAL, [$project->getId()])
|
||||
new Query('projectInternalId', Query::TYPE_EQUAL, [$project->getInternalId()])
|
||||
]);
|
||||
|
||||
if ($platform === false || $platform->isEmpty()) {
|
||||
|
@ -1101,7 +1107,7 @@ App::put('/v1/projects/:projectId/platforms/:platformId')
|
|||
|
||||
$platform = $dbForConsole->findOne('platforms', [
|
||||
new Query('_uid', Query::TYPE_EQUAL, [$platformId]),
|
||||
new Query('projectId', Query::TYPE_EQUAL, [$project->getId()])
|
||||
new Query('projectInternalId', Query::TYPE_EQUAL, [$project->getInternalId()])
|
||||
]);
|
||||
|
||||
if ($platform === false || $platform->isEmpty()) {
|
||||
|
@ -1145,7 +1151,7 @@ App::delete('/v1/projects/:projectId/platforms/:platformId')
|
|||
|
||||
$platform = $dbForConsole->findOne('platforms', [
|
||||
new Query('_uid', Query::TYPE_EQUAL, [$platformId]),
|
||||
new Query('projectId', Query::TYPE_EQUAL, [$project->getId()])
|
||||
new Query('projectInternalId', Query::TYPE_EQUAL, [$project->getInternalId()])
|
||||
]);
|
||||
|
||||
if ($platform === false || $platform->isEmpty()) {
|
||||
|
@ -1185,7 +1191,7 @@ App::post('/v1/projects/:projectId/domains')
|
|||
|
||||
$document = $dbForConsole->findOne('domains', [
|
||||
new Query('domain', Query::TYPE_EQUAL, [$domain]),
|
||||
new Query('projectId', Query::TYPE_EQUAL, [$project->getId()]),
|
||||
new Query('projectInternalId', Query::TYPE_EQUAL, [$project->getInternalId()]),
|
||||
]);
|
||||
|
||||
if ($document && !$document->isEmpty()) {
|
||||
|
@ -1204,6 +1210,7 @@ App::post('/v1/projects/:projectId/domains')
|
|||
'$id' => $dbForConsole->getId(),
|
||||
'$read' => ['role:all'],
|
||||
'$write' => ['role:all'],
|
||||
'projectInternalId' => $project->getInternalId(),
|
||||
'projectId' => $project->getId(),
|
||||
'updated' => \time(),
|
||||
'domain' => $domain->get(),
|
||||
|
@ -1243,7 +1250,7 @@ App::get('/v1/projects/:projectId/domains')
|
|||
}
|
||||
|
||||
$domains = $dbForConsole->find('domains', [
|
||||
new Query('projectId', Query::TYPE_EQUAL, [$project->getId()])
|
||||
new Query('projectInternalId', Query::TYPE_EQUAL, [$project->getInternalId()])
|
||||
], 5000);
|
||||
|
||||
$response->dynamic(new Document([
|
||||
|
@ -1276,7 +1283,7 @@ App::get('/v1/projects/:projectId/domains/:domainId')
|
|||
|
||||
$domain = $dbForConsole->findOne('domains', [
|
||||
new Query('_uid', Query::TYPE_EQUAL, [$domainId]),
|
||||
new Query('projectId', Query::TYPE_EQUAL, [$project->getId()])
|
||||
new Query('projectInternalId', Query::TYPE_EQUAL, [$project->getInternalId()])
|
||||
]);
|
||||
|
||||
if ($domain === false || $domain->isEmpty()) {
|
||||
|
@ -1310,7 +1317,7 @@ App::patch('/v1/projects/:projectId/domains/:domainId/verification')
|
|||
|
||||
$domain = $dbForConsole->findOne('domains', [
|
||||
new Query('_uid', Query::TYPE_EQUAL, [$domainId]),
|
||||
new Query('projectId', Query::TYPE_EQUAL, [$project->getId()])
|
||||
new Query('projectInternalId', Query::TYPE_EQUAL, [$project->getInternalId()])
|
||||
]);
|
||||
|
||||
if ($domain === false || $domain->isEmpty()) {
|
||||
|
@ -1370,7 +1377,7 @@ App::delete('/v1/projects/:projectId/domains/:domainId')
|
|||
|
||||
$domain = $dbForConsole->findOne('domains', [
|
||||
new Query('_uid', Query::TYPE_EQUAL, [$domainId]),
|
||||
new Query('projectId', Query::TYPE_EQUAL, [$project->getId()])
|
||||
new Query('projectInternalId', Query::TYPE_EQUAL, [$project->getInternalId()])
|
||||
]);
|
||||
|
||||
if ($domain === false || $domain->isEmpty()) {
|
||||
|
|
|
@ -73,7 +73,9 @@ App::post('/v1/teams')
|
|||
'$read' => ['user:' . $user->getId(), 'team:' . $team->getId()],
|
||||
'$write' => ['user:' . $user->getId(), 'team:' . $team->getId() . '/owner'],
|
||||
'userId' => $user->getId(),
|
||||
'userInternalId' => $user->getInternalId(),
|
||||
'teamId' => $team->getId(),
|
||||
'teamInternalId' => $team->getInternalId(),
|
||||
'roles' => $roles,
|
||||
'invited' => \time(),
|
||||
'joined' => \time(),
|
||||
|
@ -366,7 +368,9 @@ App::post('/v1/teams/:teamId/memberships')
|
|||
'$read' => ['role:all'],
|
||||
'$write' => ['user:' . $invitee->getId(), 'team:' . $team->getId() . '/owner'],
|
||||
'userId' => $invitee->getId(),
|
||||
'userInternalId' => $invitee->getInternalId(),
|
||||
'teamId' => $team->getId(),
|
||||
'teamInternalId' => $team->getInternalId(),
|
||||
'roles' => $roles,
|
||||
'invited' => \time(),
|
||||
'joined' => ($isPrivilegedUser || $isAppUser) ? \time() : 0,
|
||||
|
@ -701,6 +705,7 @@ App::patch('/v1/teams/:teamId/memberships/:membershipId/status')
|
|||
$session = new Document(array_merge([
|
||||
'$id' => $dbForProject->getId(),
|
||||
'userId' => $user->getId(),
|
||||
'userInternalId' => $user->getInternalId(),
|
||||
'provider' => Auth::SESSION_PROVIDER_EMAIL,
|
||||
'providerUid' => $user->getAttribute('email'),
|
||||
'secret' => Auth::hash($secret), // One way hash encryption to protect DB leak
|
||||
|
|
23
app/init.php
23
app/init.php
|
@ -257,7 +257,7 @@ Database::addFilter(
|
|||
function (mixed $value, Document $document, Database $database) {
|
||||
return $database
|
||||
->find('attributes', [
|
||||
new Query('collectionId', Query::TYPE_EQUAL, [$document->getId()])
|
||||
new Query('collectionInternalId', Query::TYPE_EQUAL, [$document->getInternalId()])
|
||||
], $database->getAttributeLimit());
|
||||
}
|
||||
);
|
||||
|
@ -270,7 +270,7 @@ Database::addFilter(
|
|||
function (mixed $value, Document $document, Database $database) {
|
||||
return $database
|
||||
->find('indexes', [
|
||||
new Query('collectionId', Query::TYPE_EQUAL, [$document->getId()])
|
||||
new Query('collectionInternalId', Query::TYPE_EQUAL, [$document->getInternalId()])
|
||||
], 64);
|
||||
}
|
||||
);
|
||||
|
@ -283,7 +283,7 @@ Database::addFilter(
|
|||
function (mixed $value, Document $document, Database $database) {
|
||||
return $database
|
||||
->find('platforms', [
|
||||
new Query('projectId', Query::TYPE_EQUAL, [$document->getId()])
|
||||
new Query('projectInternalId', Query::TYPE_EQUAL, [$document->getInternalId()])
|
||||
], APP_LIMIT_SUBQUERY);
|
||||
}
|
||||
);
|
||||
|
@ -296,7 +296,7 @@ Database::addFilter(
|
|||
function (mixed $value, Document $document, Database $database) {
|
||||
return $database
|
||||
->find('domains', [
|
||||
new Query('projectId', Query::TYPE_EQUAL, [$document->getId()])
|
||||
new Query('projectInternalId', Query::TYPE_EQUAL, [$document->getInternalId()])
|
||||
], APP_LIMIT_SUBQUERY);
|
||||
}
|
||||
);
|
||||
|
@ -309,7 +309,7 @@ Database::addFilter(
|
|||
function (mixed $value, Document $document, Database $database) {
|
||||
return $database
|
||||
->find('keys', [
|
||||
new Query('projectId', Query::TYPE_EQUAL, [$document->getId()])
|
||||
new Query('projectInternalId', Query::TYPE_EQUAL, [$document->getInternalId()])
|
||||
], APP_LIMIT_SUBQUERY);
|
||||
}
|
||||
);
|
||||
|
@ -322,7 +322,7 @@ Database::addFilter(
|
|||
function (mixed $value, Document $document, Database $database) {
|
||||
return $database
|
||||
->find('webhooks', [
|
||||
new Query('projectId', Query::TYPE_EQUAL, [$document->getId()])
|
||||
new Query('projectInternalId', Query::TYPE_EQUAL, [$document->getInternalId()])
|
||||
], APP_LIMIT_SUBQUERY);
|
||||
}
|
||||
);
|
||||
|
@ -334,7 +334,7 @@ Database::addFilter(
|
|||
},
|
||||
function (mixed $value, Document $document, Database $database) {
|
||||
return Authorization::skip(fn () => $database->find('sessions', [
|
||||
new Query('userId', Query::TYPE_EQUAL, [$document->getId()])
|
||||
new Query('userInternalId', Query::TYPE_EQUAL, [$document->getInternalId()])
|
||||
], APP_LIMIT_SUBQUERY));
|
||||
}
|
||||
);
|
||||
|
@ -347,7 +347,7 @@ Database::addFilter(
|
|||
function (mixed $value, Document $document, Database $database) {
|
||||
return Authorization::skip(fn() => $database
|
||||
->find('tokens', [
|
||||
new Query('userId', Query::TYPE_EQUAL, [$document->getId()])
|
||||
new Query('userInternalId', Query::TYPE_EQUAL, [$document->getInternalId()])
|
||||
], APP_LIMIT_SUBQUERY));
|
||||
}
|
||||
);
|
||||
|
@ -360,7 +360,7 @@ Database::addFilter(
|
|||
function (mixed $value, Document $document, Database $database) {
|
||||
return Authorization::skip(fn() => $database
|
||||
->find('memberships', [
|
||||
new Query('userId', Query::TYPE_EQUAL, [$document->getId()])
|
||||
new Query('userInternalId', Query::TYPE_EQUAL, [$document->getInternalId()])
|
||||
], APP_LIMIT_SUBQUERY));
|
||||
}
|
||||
);
|
||||
|
@ -842,6 +842,7 @@ App::setResource('project', function ($dbForConsole, $request, $console) {
|
|||
App::setResource('console', function () {
|
||||
return new Document([
|
||||
'$id' => 'console',
|
||||
'$internalId' => 'console',
|
||||
'name' => 'Appwrite',
|
||||
'$collection' => 'projects',
|
||||
'description' => 'Appwrite core engine',
|
||||
|
@ -871,12 +872,12 @@ App::setResource('console', function () {
|
|||
]);
|
||||
}, []);
|
||||
|
||||
App::setResource('dbForProject', function ($db, $cache, $project) {
|
||||
App::setResource('dbForProject', function ($db, $cache, Document $project) {
|
||||
$cache = new Cache(new RedisCache($cache));
|
||||
|
||||
$database = new Database(new MariaDB($db), $cache);
|
||||
$database->setDefaultDatabase(App::getEnv('_APP_DB_SCHEMA', 'appwrite'));
|
||||
$database->setNamespace("_{$project->getId()}");
|
||||
$database->setNamespace("_{$project->getInternalId()}");
|
||||
|
||||
return $database;
|
||||
}, ['db', 'cache', 'project']);
|
||||
|
|
|
@ -150,6 +150,7 @@ $server->onStart(function () use ($stats, $register, $containerId, &$statsDocume
|
|||
'timestamp' => time(),
|
||||
'value' => '{}'
|
||||
]);
|
||||
|
||||
$statsDocument = Authorization::skip(fn () => $database->createDocument('realtime', $document));
|
||||
} catch (\Throwable $th) {
|
||||
call_user_func($logError, $th, "createWorkerDocument");
|
||||
|
@ -297,7 +298,9 @@ $server->onWorkerStart(function (int $workerId) use ($server, $register, $stats,
|
|||
|
||||
if ($realtime->hasSubscriber($projectId, 'user:' . $userId)) {
|
||||
$connection = array_key_first(reset($realtime->subscriptions[$projectId]['user:' . $userId]));
|
||||
[$database, $returnDatabase] = getDatabase($register, "_{$projectId}");
|
||||
[$consoleDatabase, $returnConsoleDatabase] = getDatabase($register, '_console');
|
||||
$project = Authorization::skip(fn() => $consoleDatabase->getDocument('projects', $projectId));
|
||||
[$database, $returnDatabase] = getDatabase($register, "_{$project->getInternalId()}");
|
||||
|
||||
$user = $database->getDocument('users', $userId);
|
||||
|
||||
|
@ -306,6 +309,7 @@ $server->onWorkerStart(function (int $workerId) use ($server, $register, $stats,
|
|||
$realtime->subscribe($projectId, $connection, $roles, $realtime->connections[$connection]['channels']);
|
||||
|
||||
call_user_func($returnDatabase);
|
||||
call_user_func($returnConsoleDatabase);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -373,7 +377,7 @@ $server->onOpen(function (int $connection, SwooleRequest $request) use ($server,
|
|||
$cache = new Cache(new RedisCache($redis));
|
||||
$database = new Database(new MariaDB($db), $cache);
|
||||
$database->setDefaultDatabase(App::getEnv('_APP_DB_SCHEMA', 'appwrite'));
|
||||
$database->setNamespace("_{$project->getId()}");
|
||||
$database->setNamespace("_{$project->getInternalId()}");
|
||||
|
||||
/*
|
||||
* Project Check
|
||||
|
@ -480,7 +484,9 @@ $server->onMessage(function (int $connection, string $message) use ($server, $re
|
|||
$cache = new Cache(new RedisCache($redis));
|
||||
$database = new Database(new MariaDB($db), $cache);
|
||||
$database->setDefaultDatabase(App::getEnv('_APP_DB_SCHEMA', 'appwrite'));
|
||||
$database->setNamespace("_{$realtime->connections[$connection]['projectId']}");
|
||||
$database->setNamespace("_console");
|
||||
$project = Authorization::skip(fn() => $database->getDocument('projects', $realtime->connections[$connection]['projectId']));
|
||||
$database->setNamespace("_{$project->getInternalId()}");
|
||||
|
||||
/*
|
||||
* Abuse Check
|
||||
|
|
|
@ -15,6 +15,9 @@ use Utopia\Database\Validator\Authorization;
|
|||
use Utopia\Registry\Registry;
|
||||
use Utopia\Logger\Log;
|
||||
|
||||
Authorization::disable();
|
||||
Authorization::setDefaultStatus(false);
|
||||
|
||||
function getDatabase(Registry &$register, string $namespace): Database
|
||||
{
|
||||
$attempts = 0;
|
||||
|
@ -120,11 +123,8 @@ $cli
|
|||
$influxDB = getInfluxDB($register);
|
||||
|
||||
$usage = new Usage($database, $influxDB, $logError);
|
||||
|
||||
$usageDB = new UsageDB($database, $logError);
|
||||
|
||||
Authorization::disable();
|
||||
|
||||
$iterations = 0;
|
||||
Console::loop(function () use ($interval, $usage, $usageDB, &$iterations) {
|
||||
$now = date('d-m-Y H:i:s', time());
|
||||
|
|
|
@ -15,9 +15,6 @@ use Utopia\Config\Config;
|
|||
|
||||
require_once __DIR__ . '/../init.php';
|
||||
|
||||
// Disable Auth since we already validate it in the API
|
||||
Authorization::disable();
|
||||
|
||||
Console::title('Builds V1 Worker');
|
||||
Console::success(APP_NAME . ' build worker v1 has started');
|
||||
|
||||
|
|
|
@ -36,8 +36,6 @@ class CertificatesV1 extends Worker
|
|||
|
||||
public function run(): void
|
||||
{
|
||||
Authorization::disable();
|
||||
Authorization::setDefaultStatus(false);
|
||||
/**
|
||||
* 1. Read arguments and validate domain
|
||||
* 2. Get main domain
|
||||
|
|
|
@ -5,7 +5,6 @@ use Appwrite\Messaging\Adapter\Realtime;
|
|||
use Appwrite\Resque\Worker;
|
||||
use Utopia\CLI\Console;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Database\Validator\Authorization;
|
||||
|
||||
require_once __DIR__ . '/../init.php';
|
||||
|
||||
|
@ -20,8 +19,6 @@ class DatabaseV1 extends Worker
|
|||
|
||||
public function run(): void
|
||||
{
|
||||
Authorization::disable();
|
||||
|
||||
$type = $this->args['type'];
|
||||
$project = new Document($this->args['project']);
|
||||
$collection = new Document($this->args['collection'] ?? []);
|
||||
|
@ -53,8 +50,6 @@ class DatabaseV1 extends Worker
|
|||
Console::error('No database operation for type: ' . $type);
|
||||
break;
|
||||
}
|
||||
|
||||
Authorization::reset();
|
||||
}
|
||||
|
||||
public function shutdown(): void
|
||||
|
|
|
@ -15,9 +15,6 @@ use Utopia\Audit\Audit;
|
|||
|
||||
require_once __DIR__ . '/../init.php';
|
||||
|
||||
Authorization::disable();
|
||||
Authorization::setDefaultStatus(false);
|
||||
|
||||
Console::title('Deletes V1 Worker');
|
||||
Console::success(APP_NAME . ' deletes worker v1 has started' . "\n");
|
||||
|
||||
|
|
|
@ -44,6 +44,10 @@ class FunctionsV1 extends Worker
|
|||
$user = new Document($this->args['user'] ?? []);
|
||||
$payload = json_encode($this->args['payload'] ?? []);
|
||||
|
||||
if ($project->getId() === 'console') {
|
||||
return;
|
||||
}
|
||||
|
||||
$database = $this->getProjectDB($project->getId());
|
||||
|
||||
/**
|
||||
|
@ -57,7 +61,7 @@ class FunctionsV1 extends Worker
|
|||
/** @var Document[] $functions */
|
||||
|
||||
while ($sum >= $limit) {
|
||||
$functions = Authorization::skip(fn () => $database->find('functions', [], $limit, $offset, ['name'], [Database::ORDER_ASC]));
|
||||
$functions = $database->find('functions', [], $limit, $offset, ['name'], [Database::ORDER_ASC]);
|
||||
$sum = \count($functions);
|
||||
$offset = $offset + $limit;
|
||||
|
||||
|
@ -101,7 +105,7 @@ class FunctionsV1 extends Worker
|
|||
$jwt = $this->args['jwt'] ?? '';
|
||||
$data = $this->args['data'] ?? '';
|
||||
|
||||
$function = Authorization::skip(fn () => $database->getDocument('functions', $execution->getAttribute('functionId')));
|
||||
$function = $database->getDocument('functions', $execution->getAttribute('functionId'));
|
||||
|
||||
$this->execute(
|
||||
project: $project,
|
||||
|
@ -132,7 +136,7 @@ class FunctionsV1 extends Worker
|
|||
*/
|
||||
|
||||
// Reschedule
|
||||
$function = Authorization::skip(fn () => $database->getDocument('functions', $function->getId()));
|
||||
$function = $database->getDocument('functions', $function->getId());
|
||||
|
||||
if (empty($function->getId())) {
|
||||
throw new Exception('Function not found (' . $function->getId() . ')');
|
||||
|
@ -149,11 +153,11 @@ class FunctionsV1 extends Worker
|
|||
->setAttribute('scheduleNext', $next)
|
||||
->setAttribute('schedulePrevious', \time());
|
||||
|
||||
$function = Authorization::skip(fn () => $database->updateDocument(
|
||||
$function = $database->updateDocument(
|
||||
'functions',
|
||||
$function->getId(),
|
||||
$function->setAttribute('scheduleNext', (int) $next)
|
||||
));
|
||||
);
|
||||
|
||||
if ($function === false) {
|
||||
throw new Exception('Function update failed.');
|
||||
|
@ -198,7 +202,7 @@ class FunctionsV1 extends Worker
|
|||
$deploymentId = $function->getAttribute('deployment', '');
|
||||
|
||||
/** Check if deployment exists */
|
||||
$deployment = Authorization::skip(fn () => $dbForProject->getDocument('deployments', $deploymentId));
|
||||
$deployment = $dbForProject->getDocument('deployments', $deploymentId);
|
||||
|
||||
if ($deployment->getAttribute('resourceId') !== $functionId) {
|
||||
throw new Exception('Deployment not found. Create deployment before trying to execute a function', 404);
|
||||
|
@ -209,7 +213,7 @@ class FunctionsV1 extends Worker
|
|||
}
|
||||
|
||||
/** Check if build has exists */
|
||||
$build = Authorization::skip(fn () => $dbForProject->getDocument('builds', $deployment->getAttribute('buildId', '')));
|
||||
$build = $dbForProject->getDocument('builds', $deployment->getAttribute('buildId', ''));
|
||||
if ($build->isEmpty()) {
|
||||
throw new Exception('Build not found', 404);
|
||||
}
|
||||
|
@ -227,38 +231,31 @@ class FunctionsV1 extends Worker
|
|||
|
||||
$runtime = $runtimes[$function->getAttribute('runtime')];
|
||||
|
||||
/**
|
||||
* Create execution or update execution status
|
||||
* @var Document $execution
|
||||
*/
|
||||
$execution = Authorization::skip(function () use ($dbForProject, &$executionId, $functionId, $deploymentId, $trigger, $user) {
|
||||
$execution = $dbForProject->getDocument('executions', $executionId ?? '');
|
||||
/** Create execution or update execution status */
|
||||
$execution = $dbForProject->getDocument('executions', $executionId ?? '');
|
||||
if ($execution->isEmpty()) {
|
||||
$executionId = $dbForProject->getId();
|
||||
$execution = $dbForProject->createDocument('executions', new Document([
|
||||
'$id' => $executionId,
|
||||
'$read' => $user->isEmpty() ? [] : ['user:' . $user->getId()],
|
||||
'$write' => [],
|
||||
'functionId' => $functionId,
|
||||
'deploymentId' => $deploymentId,
|
||||
'trigger' => $trigger,
|
||||
'status' => 'waiting',
|
||||
'statusCode' => 0,
|
||||
'response' => '',
|
||||
'stderr' => '',
|
||||
'time' => 0.0,
|
||||
'search' => implode(' ', [$functionId, $executionId]),
|
||||
]));
|
||||
|
||||
if ($execution->isEmpty()) {
|
||||
$executionId = $dbForProject->getId();
|
||||
$execution = $dbForProject->createDocument('executions', new Document([
|
||||
'$id' => $executionId,
|
||||
'$read' => $user->isEmpty() ? [] : ['user:' . $user->getId()],
|
||||
'$write' => [],
|
||||
'functionId' => $functionId,
|
||||
'deploymentId' => $deploymentId,
|
||||
'trigger' => $trigger,
|
||||
'status' => 'waiting',
|
||||
'statusCode' => 0,
|
||||
'response' => '',
|
||||
'stderr' => '',
|
||||
'time' => 0.0,
|
||||
'search' => implode(' ', [$functionId, $executionId]),
|
||||
]));
|
||||
|
||||
if ($execution->isEmpty()) {
|
||||
throw new Exception('Failed to create or read execution');
|
||||
}
|
||||
throw new Exception('Failed to create or read execution');
|
||||
}
|
||||
$execution->setAttribute('status', 'processing');
|
||||
$execution = $dbForProject->updateDocument('executions', $executionId, $execution);
|
||||
|
||||
return $execution;
|
||||
});
|
||||
}
|
||||
$execution->setAttribute('status', 'processing');
|
||||
$execution = $dbForProject->updateDocument('executions', $executionId, $execution);
|
||||
|
||||
/** Collect environment variables */
|
||||
$vars = [
|
||||
|
@ -309,8 +306,7 @@ class FunctionsV1 extends Worker
|
|||
Console::error($th->getMessage());
|
||||
}
|
||||
|
||||
$execution = Authorization::skip(fn () => $dbForProject->updateDocument('executions', $executionId, $execution));
|
||||
/** @var Document $execution */
|
||||
$execution = $dbForProject->updateDocument('executions', $executionId, $execution);
|
||||
|
||||
/** Trigger Webhook */
|
||||
$executionModel = new Execution();
|
||||
|
|
|
@ -17,6 +17,7 @@ use Utopia\Storage\Device\Wasabi;
|
|||
use Utopia\Storage\Device\Backblaze;
|
||||
use Utopia\Storage\Device\S3;
|
||||
use Exception;
|
||||
use Utopia\Database\Validator\Authorization;
|
||||
|
||||
abstract class Worker
|
||||
{
|
||||
|
@ -112,6 +113,11 @@ abstract class Worker
|
|||
public function perform(): void
|
||||
{
|
||||
try {
|
||||
/**
|
||||
* Disabling global authorization in workers.
|
||||
*/
|
||||
Authorization::disable();
|
||||
Authorization::setDefaultStatus(false);
|
||||
$this->run();
|
||||
} catch (\Throwable $error) {
|
||||
foreach (self::$errorCallbacks as $errorCallback) {
|
||||
|
@ -159,7 +165,16 @@ abstract class Worker
|
|||
*/
|
||||
protected function getProjectDB(string $projectId): Database
|
||||
{
|
||||
return $this->getDB(self::DATABASE_PROJECT, $projectId);
|
||||
$consoleDB = $this->getConsoleDB();
|
||||
|
||||
if ($projectId === 'console') {
|
||||
return $consoleDB;
|
||||
}
|
||||
|
||||
/** @var Document $project */
|
||||
$project = Authorization::skip(fn() => $consoleDB->getDocument('projects', $projectId));
|
||||
|
||||
return $this->getDB(self::DATABASE_PROJECT, $projectId, $project->getInternalId());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -177,7 +192,7 @@ abstract class Worker
|
|||
* @param string $projectId of internal or external DB
|
||||
* @return Database
|
||||
*/
|
||||
private function getDB($type, $projectId = ''): Database
|
||||
private function getDB(string $type, string $projectId = '', string $projectInternalId = ''): Database
|
||||
{
|
||||
global $register;
|
||||
|
||||
|
@ -189,7 +204,7 @@ abstract class Worker
|
|||
if (!$projectId) {
|
||||
throw new \Exception('ProjectID not provided - cannot get database');
|
||||
}
|
||||
$namespace = "_{$projectId}";
|
||||
$namespace = "_{$projectInternalId}";
|
||||
break;
|
||||
case self::DATABASE_CONSOLE:
|
||||
$namespace = "_console";
|
||||
|
|
|
@ -180,7 +180,10 @@ class Usage
|
|||
private function createOrUpdateMetric(string $projectId, int $time, string $period, string $metric, int $value, int $type): void
|
||||
{
|
||||
$id = \md5("{$time}_{$period}_{$metric}");
|
||||
$this->database->setNamespace('_' . $projectId);
|
||||
$this->database->setNamespace('_console');
|
||||
$project = $this->database->getDocument('projects', $projectId);
|
||||
$this->database->setNamespace('_' . $project->getInternalId());
|
||||
|
||||
try {
|
||||
$document = $this->database->getDocument('stats', $id);
|
||||
if ($document->isEmpty()) {
|
||||
|
|
|
@ -28,7 +28,10 @@ class UsageDB extends Usage
|
|||
$period = $options['key'];
|
||||
$time = (int) (floor(time() / $options['multiplier']) * $options['multiplier']);
|
||||
$id = \md5("{$time}_{$period}_{$metric}");
|
||||
$this->database->setNamespace('_' . $projectId);
|
||||
$this->database->setNamespace('_console');
|
||||
$project = $this->database->getDocument('projects', $projectId);
|
||||
$this->database->setNamespace('_' . $project->getInternalId());
|
||||
|
||||
try {
|
||||
$document = $this->database->getDocument('stats', $id);
|
||||
if ($document->isEmpty()) {
|
||||
|
@ -70,15 +73,21 @@ class UsageDB extends Usage
|
|||
*/
|
||||
private function foreachDocument(string $projectId, string $collection, array $queries, callable $callback): void
|
||||
{
|
||||
if ($projectId === 'console') {
|
||||
return;
|
||||
}
|
||||
|
||||
$limit = 50;
|
||||
$results = [];
|
||||
$sum = $limit;
|
||||
$latestDocument = null;
|
||||
$this->database->setNamespace('_' . $projectId);
|
||||
$this->database->setNamespace('_console');
|
||||
$project = $this->database->getDocument('projects', $projectId);
|
||||
$this->database->setNamespace('_' . $project->getInternalId());
|
||||
|
||||
while ($sum === $limit) {
|
||||
try {
|
||||
$results = $this->database->find($collection, $queries, $limit, cursor:$latestDocument);
|
||||
$results = $this->database->find($collection, $queries, $limit, cursor: $latestDocument);
|
||||
} catch (\Exception $e) {
|
||||
if (is_callable($this->errorHandler)) {
|
||||
call_user_func($this->errorHandler, $e, "fetch_documents_project_{$projectId}_collection_{$collection}");
|
||||
|
@ -115,7 +124,10 @@ class UsageDB extends Usage
|
|||
*/
|
||||
private function sum(string $projectId, string $collection, string $attribute, string $metric): int
|
||||
{
|
||||
$this->database->setNamespace('_' . $projectId);
|
||||
$this->database->setNamespace('_console');
|
||||
$project = $this->database->getDocument('projects', $projectId);
|
||||
$this->database->setNamespace('_' . $project->getInternalId());
|
||||
|
||||
try {
|
||||
$sum = (int) $this->database->sum($collection, $attribute);
|
||||
$this->createOrUpdateMetric($projectId, $metric, $sum);
|
||||
|
@ -141,7 +153,10 @@ class UsageDB extends Usage
|
|||
*/
|
||||
private function count(string $projectId, string $collection, string $metric): int
|
||||
{
|
||||
$this->database->setNamespace("_{$projectId}");
|
||||
$this->database->setNamespace('_console');
|
||||
$project = $this->database->getDocument('projects', $projectId);
|
||||
$this->database->setNamespace('_' . $project->getInternalId());
|
||||
|
||||
try {
|
||||
$count = $this->database->count($collection);
|
||||
$this->createOrUpdateMetric($projectId, $metric, $count);
|
||||
|
@ -252,11 +267,12 @@ class UsageDB extends Usage
|
|||
*/
|
||||
public function collect(): void
|
||||
{
|
||||
$this->foreachDocument('console', 'projects', [], function ($project) {
|
||||
$projectId = $project->getId();
|
||||
$this->usersStats($projectId);
|
||||
$this->databaseStats($projectId);
|
||||
$this->storageStats($projectId);
|
||||
$this->foreachDocument('console', 'projects', [], function (Document $project) {
|
||||
$projectId = $project->getId();
|
||||
|
||||
$this->usersStats($projectId);
|
||||
$this->databaseStats($projectId);
|
||||
$this->storageStats($projectId);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -789,7 +789,7 @@ class DatabaseCustomServerTest extends Scope
|
|||
$this->assertEquals('available', $attribute['status'], 'attribute: ' . $attribute['key']);
|
||||
}
|
||||
|
||||
// testing for indexLimit = 64
|
||||
// Test indexLimit = 64
|
||||
// MariaDB, MySQL, and MongoDB create 5 indexes per new collection
|
||||
// Add up to the limit, then check if the next index throws IndexLimitException
|
||||
for ($i = 0; $i < 59; $i++) {
|
||||
|
|
|
@ -587,6 +587,7 @@ class FunctionsCustomServerTest extends Scope
|
|||
/**
|
||||
* Test for SUCCESS
|
||||
*/
|
||||
|
||||
$execution = $this->client->call(Client::METHOD_POST, '/functions/' . $data['functionId'] . '/executions', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
|
|
|
@ -75,14 +75,10 @@ class RealtimeConsoleClientTest extends Scope
|
|||
$this->assertArrayHasKey('timestamp', $response['data']);
|
||||
$this->assertCount(1, $response['data']['channels']);
|
||||
$this->assertContains('console', $response['data']['channels']);
|
||||
$this->assertContains("collections.{$actorsId}.attributes.{$actorsId}_{$attributeKey}.create", $response['data']['events']);
|
||||
$this->assertContains("collections.{$actorsId}.attributes.*.create", $response['data']['events']);
|
||||
$this->assertContains("collections.{$actorsId}.attributes.{$actorsId}_{$attributeKey}", $response['data']['events']);
|
||||
$this->assertContains("collections.{$actorsId}.attributes.*", $response['data']['events']);
|
||||
$this->assertContains("collections.{$actorsId}", $response['data']['events']);
|
||||
$this->assertContains("collections.*.attributes.{$actorsId}_{$attributeKey}.create", $response['data']['events']);
|
||||
$this->assertContains("collections.*.attributes.*.create", $response['data']['events']);
|
||||
$this->assertContains("collections.*.attributes.{$actorsId}_{$attributeKey}", $response['data']['events']);
|
||||
$this->assertContains("collections.*.attributes.*", $response['data']['events']);
|
||||
$this->assertContains("collections.*", $response['data']['events']);
|
||||
$this->assertNotEmpty($response['data']['payload']);
|
||||
|
@ -97,14 +93,10 @@ class RealtimeConsoleClientTest extends Scope
|
|||
$this->assertArrayHasKey('timestamp', $response['data']);
|
||||
$this->assertCount(1, $response['data']['channels']);
|
||||
$this->assertContains('console', $response['data']['channels']);
|
||||
$this->assertContains("collections.{$actorsId}.attributes.{$actorsId}_{$attributeKey}.update", $response['data']['events']);
|
||||
$this->assertContains("collections.{$actorsId}.attributes.*.update", $response['data']['events']);
|
||||
$this->assertContains("collections.{$actorsId}.attributes.{$actorsId}_{$attributeKey}", $response['data']['events']);
|
||||
$this->assertContains("collections.{$actorsId}.attributes.*", $response['data']['events']);
|
||||
$this->assertContains("collections.{$actorsId}", $response['data']['events']);
|
||||
$this->assertContains("collections.*.attributes.{$actorsId}_{$attributeKey}.update", $response['data']['events']);
|
||||
$this->assertContains("collections.*.attributes.*.update", $response['data']['events']);
|
||||
$this->assertContains("collections.*.attributes.{$actorsId}_{$attributeKey}", $response['data']['events']);
|
||||
$this->assertContains("collections.*.attributes.*", $response['data']['events']);
|
||||
$this->assertContains("collections.*", $response['data']['events']);
|
||||
$this->assertNotEmpty($response['data']['payload']);
|
||||
|
@ -165,14 +157,10 @@ class RealtimeConsoleClientTest extends Scope
|
|||
$this->assertArrayHasKey('timestamp', $response['data']);
|
||||
$this->assertCount(1, $response['data']['channels']);
|
||||
$this->assertContains('console', $response['data']['channels']);
|
||||
$this->assertContains("collections.{$actorsId}.indexes.{$actorsId}_{$indexKey}.create", $response['data']['events']);
|
||||
$this->assertContains("collections.{$actorsId}.indexes.*.create", $response['data']['events']);
|
||||
$this->assertContains("collections.{$actorsId}.indexes.{$actorsId}_{$indexKey}", $response['data']['events']);
|
||||
$this->assertContains("collections.{$actorsId}.indexes.*", $response['data']['events']);
|
||||
$this->assertContains("collections.{$actorsId}", $response['data']['events']);
|
||||
$this->assertContains("collections.*.indexes.{$actorsId}_{$indexKey}.create", $response['data']['events']);
|
||||
$this->assertContains("collections.*.indexes.*.create", $response['data']['events']);
|
||||
$this->assertContains("collections.*.indexes.{$actorsId}_{$indexKey}", $response['data']['events']);
|
||||
$this->assertContains("collections.*.indexes.*", $response['data']['events']);
|
||||
$this->assertContains("collections.*", $response['data']['events']);
|
||||
$this->assertNotEmpty($response['data']['payload']);
|
||||
|
@ -187,14 +175,10 @@ class RealtimeConsoleClientTest extends Scope
|
|||
$this->assertArrayHasKey('timestamp', $response['data']);
|
||||
$this->assertCount(1, $response['data']['channels']);
|
||||
$this->assertContains('console', $response['data']['channels']);
|
||||
$this->assertContains("collections.{$actorsId}.indexes.{$actorsId}_{$indexKey}.update", $response['data']['events']);
|
||||
$this->assertContains("collections.{$actorsId}.indexes.*.update", $response['data']['events']);
|
||||
$this->assertContains("collections.{$actorsId}.indexes.{$actorsId}_{$indexKey}", $response['data']['events']);
|
||||
$this->assertContains("collections.{$actorsId}.indexes.*", $response['data']['events']);
|
||||
$this->assertContains("collections.{$actorsId}", $response['data']['events']);
|
||||
$this->assertContains("collections.*.indexes.{$actorsId}_{$indexKey}.update", $response['data']['events']);
|
||||
$this->assertContains("collections.*.indexes.*.update", $response['data']['events']);
|
||||
$this->assertContains("collections.*.indexes.{$actorsId}_{$indexKey}", $response['data']['events']);
|
||||
$this->assertContains("collections.*.indexes.*", $response['data']['events']);
|
||||
$this->assertContains("collections.*", $response['data']['events']);
|
||||
$this->assertNotEmpty($response['data']['payload']);
|
||||
|
@ -247,14 +231,10 @@ class RealtimeConsoleClientTest extends Scope
|
|||
$this->assertArrayHasKey('timestamp', $response['data']);
|
||||
$this->assertCount(1, $response['data']['channels']);
|
||||
$this->assertContains('console', $response['data']['channels']);
|
||||
$this->assertContains("collections.{$actorsId}.indexes.{$actorsId}_{$indexKey}.delete", $response['data']['events']);
|
||||
$this->assertContains("collections.{$actorsId}.indexes.*.delete", $response['data']['events']);
|
||||
$this->assertContains("collections.{$actorsId}.indexes.{$actorsId}_{$indexKey}", $response['data']['events']);
|
||||
$this->assertContains("collections.{$actorsId}.indexes.*", $response['data']['events']);
|
||||
$this->assertContains("collections.{$actorsId}", $response['data']['events']);
|
||||
$this->assertContains("collections.*.indexes.{$actorsId}_{$indexKey}.delete", $response['data']['events']);
|
||||
$this->assertContains("collections.*.indexes.*.delete", $response['data']['events']);
|
||||
$this->assertContains("collections.*.indexes.{$actorsId}_{$indexKey}", $response['data']['events']);
|
||||
$this->assertContains("collections.*.indexes.*", $response['data']['events']);
|
||||
$this->assertContains("collections.*", $response['data']['events']);
|
||||
$this->assertNotEmpty($response['data']['payload']);
|
||||
|
@ -306,14 +286,10 @@ class RealtimeConsoleClientTest extends Scope
|
|||
$this->assertArrayHasKey('timestamp', $response['data']);
|
||||
$this->assertCount(1, $response['data']['channels']);
|
||||
$this->assertContains('console', $response['data']['channels']);
|
||||
$this->assertContains("collections.{$actorsId}.attributes.{$actorsId}_{$attributeKey}.delete", $response['data']['events']);
|
||||
$this->assertContains("collections.{$actorsId}.attributes.*.delete", $response['data']['events']);
|
||||
$this->assertContains("collections.{$actorsId}.attributes.{$actorsId}_{$attributeKey}", $response['data']['events']);
|
||||
$this->assertContains("collections.{$actorsId}.attributes.*", $response['data']['events']);
|
||||
$this->assertContains("collections.{$actorsId}", $response['data']['events']);
|
||||
$this->assertContains("collections.*.attributes.{$actorsId}_{$attributeKey}.delete", $response['data']['events']);
|
||||
$this->assertContains("collections.*.attributes.*.delete", $response['data']['events']);
|
||||
$this->assertContains("collections.*.attributes.{$actorsId}_{$attributeKey}", $response['data']['events']);
|
||||
$this->assertContains("collections.*.attributes.*", $response['data']['events']);
|
||||
$this->assertContains("collections.*", $response['data']['events']);
|
||||
$this->assertNotEmpty($response['data']['payload']);
|
||||
|
|
|
@ -119,13 +119,9 @@ trait WebhooksBase
|
|||
$this->assertStringContainsString('collections.*', $webhook['headers']['X-Appwrite-Webhook-Events']);
|
||||
$this->assertStringContainsString('collections.*.attributes.*', $webhook['headers']['X-Appwrite-Webhook-Events']);
|
||||
$this->assertStringContainsString('collections.*.attributes.*.create', $webhook['headers']['X-Appwrite-Webhook-Events']);
|
||||
$this->assertStringContainsString("collections.*.attributes.{$actorsId}_{$attributeId}", $webhook['headers']['X-Appwrite-Webhook-Events']);
|
||||
$this->assertStringContainsString("collections.*.attributes.{$actorsId}_{$attributeId}.create", $webhook['headers']['X-Appwrite-Webhook-Events']);
|
||||
$this->assertStringContainsString("collections.{$actorsId}", $webhook['headers']['X-Appwrite-Webhook-Events']);
|
||||
$this->assertStringContainsString("collections.{$actorsId}.attributes.*", $webhook['headers']['X-Appwrite-Webhook-Events']);
|
||||
$this->assertStringContainsString("collections.{$actorsId}.attributes.*.create", $webhook['headers']['X-Appwrite-Webhook-Events']);
|
||||
$this->assertStringContainsString("collections.{$actorsId}.attributes.{$actorsId}_{$attributeId}", $webhook['headers']['X-Appwrite-Webhook-Events']);
|
||||
$this->assertStringContainsString("collections.{$actorsId}.attributes.{$actorsId}_{$attributeId}.create", $webhook['headers']['X-Appwrite-Webhook-Events']);
|
||||
$this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Signature'], $signatureExpected);
|
||||
$this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Id'] ?? '', $this->getProject()['webhookId']);
|
||||
$this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Project-Id'] ?? '', $this->getProject()['$id']);
|
||||
|
@ -149,13 +145,9 @@ trait WebhooksBase
|
|||
$this->assertStringContainsString('collections.*', $webhook['headers']['X-Appwrite-Webhook-Events']);
|
||||
$this->assertStringContainsString('collections.*.attributes.*', $webhook['headers']['X-Appwrite-Webhook-Events']);
|
||||
$this->assertStringContainsString('collections.*.attributes.*.delete', $webhook['headers']['X-Appwrite-Webhook-Events']);
|
||||
$this->assertStringContainsString("collections.*.attributes.{$actorsId}_{$attributeId}", $webhook['headers']['X-Appwrite-Webhook-Events']);
|
||||
$this->assertStringContainsString("collections.*.attributes.{$actorsId}_{$attributeId}.delete", $webhook['headers']['X-Appwrite-Webhook-Events']);
|
||||
$this->assertStringContainsString("collections.{$actorsId}", $webhook['headers']['X-Appwrite-Webhook-Events']);
|
||||
$this->assertStringContainsString("collections.{$actorsId}.attributes.*", $webhook['headers']['X-Appwrite-Webhook-Events']);
|
||||
$this->assertStringContainsString("collections.{$actorsId}.attributes.*.delete", $webhook['headers']['X-Appwrite-Webhook-Events']);
|
||||
$this->assertStringContainsString("collections.{$actorsId}.attributes.{$actorsId}_{$attributeId}", $webhook['headers']['X-Appwrite-Webhook-Events']);
|
||||
$this->assertStringContainsString("collections.{$actorsId}.attributes.{$actorsId}_{$attributeId}.delete", $webhook['headers']['X-Appwrite-Webhook-Events']);
|
||||
$this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Signature'], $signatureExpected);
|
||||
$this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Id'] ?? '', $this->getProject()['webhookId']);
|
||||
$this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Project-Id'] ?? '', $this->getProject()['$id']);
|
||||
|
|
|
@ -95,13 +95,9 @@ class WebhooksCustomServerTest extends Scope
|
|||
$this->assertStringContainsString('collections.*', $webhook['headers']['X-Appwrite-Webhook-Events']);
|
||||
$this->assertStringContainsString('collections.*.indexes.*', $webhook['headers']['X-Appwrite-Webhook-Events']);
|
||||
$this->assertStringContainsString('collections.*.indexes.*.create', $webhook['headers']['X-Appwrite-Webhook-Events']);
|
||||
$this->assertStringContainsString("collections.*.indexes.{$actorsId}_{$indexKey}", $webhook['headers']['X-Appwrite-Webhook-Events']);
|
||||
$this->assertStringContainsString("collections.*.indexes.{$actorsId}_{$indexKey}.create", $webhook['headers']['X-Appwrite-Webhook-Events']);
|
||||
$this->assertStringContainsString("collections.{$actorsId}", $webhook['headers']['X-Appwrite-Webhook-Events']);
|
||||
$this->assertStringContainsString("collections.{$actorsId}.indexes.*", $webhook['headers']['X-Appwrite-Webhook-Events']);
|
||||
$this->assertStringContainsString("collections.{$actorsId}.indexes.*.create", $webhook['headers']['X-Appwrite-Webhook-Events']);
|
||||
$this->assertStringContainsString("collections.{$actorsId}.indexes.{$actorsId}_{$indexKey}", $webhook['headers']['X-Appwrite-Webhook-Events']);
|
||||
$this->assertStringContainsString("collections.{$actorsId}.indexes.{$actorsId}_{$indexKey}.create", $webhook['headers']['X-Appwrite-Webhook-Events']);
|
||||
$this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Signature'], $signatureExpected);
|
||||
$this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Id'] ?? '', $this->getProject()['webhookId']);
|
||||
$this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Project-Id'] ?? '', $this->getProject()['$id']);
|
||||
|
@ -124,13 +120,9 @@ class WebhooksCustomServerTest extends Scope
|
|||
$this->assertStringContainsString('collections.*', $webhook['headers']['X-Appwrite-Webhook-Events']);
|
||||
$this->assertStringContainsString('collections.*.indexes.*', $webhook['headers']['X-Appwrite-Webhook-Events']);
|
||||
$this->assertStringContainsString('collections.*.indexes.*.delete', $webhook['headers']['X-Appwrite-Webhook-Events']);
|
||||
$this->assertStringContainsString("collections.*.indexes.{$actorsId}_{$indexKey}", $webhook['headers']['X-Appwrite-Webhook-Events']);
|
||||
$this->assertStringContainsString("collections.*.indexes.{$actorsId}_{$indexKey}.delete", $webhook['headers']['X-Appwrite-Webhook-Events']);
|
||||
$this->assertStringContainsString("collections.{$actorsId}", $webhook['headers']['X-Appwrite-Webhook-Events']);
|
||||
$this->assertStringContainsString("collections.{$actorsId}.indexes.*", $webhook['headers']['X-Appwrite-Webhook-Events']);
|
||||
$this->assertStringContainsString("collections.{$actorsId}.indexes.*.delete", $webhook['headers']['X-Appwrite-Webhook-Events']);
|
||||
$this->assertStringContainsString("collections.{$actorsId}.indexes.{$actorsId}_{$indexKey}", $webhook['headers']['X-Appwrite-Webhook-Events']);
|
||||
$this->assertStringContainsString("collections.{$actorsId}.indexes.{$actorsId}_{$indexKey}.delete", $webhook['headers']['X-Appwrite-Webhook-Events']);
|
||||
$this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Signature'], $signatureExpected);
|
||||
$this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Id'] ?? '', $this->getProject()['webhookId']);
|
||||
$this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Project-Id'] ?? '', $this->getProject()['$id']);
|
||||
|
|
Loading…
Reference in a new issue