diff --git a/app/controllers/api/teams.php b/app/controllers/api/teams.php index ab5534edc6..de6df6f0e6 100644 --- a/app/controllers/api/teams.php +++ b/app/controllers/api/teams.php @@ -564,25 +564,40 @@ App::patch('/v1/teams/:teamId/memberships/:membershipId') $isPrivilegedUser = Auth::isPrivilegedUser(Authorization::getRoles()); $isAppUser = Auth::isAppUser(Authorization::getRoles()); - $isOwner = Authorization::isRole('team:'.$team->getId().'/owner');; + $isOwner = Authorization::isRole('team:' . $team->getId() . '/owner');; if (!$isOwner && !$isPrivilegedUser && !$isAppUser) { // Not owner, not admin, not app (server) throw new Exception('User is not allowed to modify roles', 401); } - // Update the roles + /** + * Update the roles + */ $membership->setAttribute('roles', $roles); $membership = $dbForProject->updateDocument('memberships', $membership->getId(), $membership); - // TODO sync updated membership in the user $profile object using TYPE_REPLACE + /** + * Replace membership on profile + */ + $memberships = array_filter($profile->getAttribute('memberships'), fn (Document $m) => $m->getId() !== $membership->getId()); + + $profile + ->setAttribute('memberships', $memberships) + ->setAttribute('memberships', $membership, Document::SET_TYPE_APPEND); + + Authorization::skip(fn () => $dbForProject->updateDocument('users', $profile->getId(), $profile)); $audits ->setParam('userId', $user->getId()) ->setParam('event', 'teams.memberships.update') - ->setParam('resource', 'team/'.$teamId) - ; + ->setParam('resource', 'team/' . $teamId); - $response->dynamic($membership, Response::MODEL_MEMBERSHIP); + $response->dynamic( + $membership + ->setAttribute('email', $profile->getAttribute('email')) + ->setAttribute('name', $profile->getAttribute('name')), + Response::MODEL_MEMBERSHIP + ); }); App::patch('/v1/teams/:teamId/memberships/:membershipId/status') diff --git a/src/Appwrite/Migration/Version/V11.php b/src/Appwrite/Migration/Version/V11.php index 896dce8f32..2812b73b9b 100644 --- a/src/Appwrite/Migration/Version/V11.php +++ b/src/Appwrite/Migration/Version/V11.php @@ -449,9 +449,9 @@ class V11 extends Migration */ $document->removeAttribute('tasks'); - /* - * Add enabled OAuth2 providers to default data rules - */ + /** + * Add enabled OAuth2 providers to default data rules + */ foreach ($providers as $index => $provider) { $appId = $document->getAttribute('usersOauth2' . \ucfirst($index) . 'Appid'); $appSecret = $document->getAttribute('usersOauth2' . \ucfirst($index) . 'Secret'); @@ -467,9 +467,14 @@ class V11 extends Migration $document->setAttribute('providers', $newProviders); - /* - * Migrate User providers settings - */ + /** + * Populate search string + */ + $document->setAttribute('search', $this->buildSearchAttribute(['$id', 'name'], $document)); + + /** + * Migrate User providers settings + */ $oldAuths = [ 'email-password' => 'usersAuthEmailPassword', 'magic-url' => 'usersAuthMagicURL', @@ -594,7 +599,29 @@ class V11 extends Migration case OldDatabase::SYSTEM_COLLECTION_FUNCTIONS: $document->setAttribute('events', $document->getAttribute('events', [])); + /** + * Populate search string + */ + $document->setAttribute('search', $this->buildSearchAttribute(['$id', 'name', 'runtime'], $document)); + break; + + case OldDatabase::SYSTEM_COLLECTION_TAGS: + /** + * Populate search string + */ + $document->setAttribute('search', $this->buildSearchAttribute(['$id', 'command'], $document)); + + break; + + case OldDatabase::SYSTEM_COLLECTION_EXECUTIONS: + /** + * Populate search string + */ + $document->setAttribute('search', $this->buildSearchAttribute(['$id', 'functionId'], $document)); + + break; + case OldDatabase::SYSTEM_COLLECTION_WEBHOOKS: $projectId = $this->getProjectIdFromReadPermissions($document); @@ -656,18 +683,28 @@ class V11 extends Migration $write = $document->getWrite(); $document->setAttribute('$write', str_replace('user:{self}', "user:{$document->getId()}", $write)); + /** + * Populate search string + */ + $document->setAttribute('search', $this->buildSearchAttribute(['$id', 'email', 'name'], $document)); + break; case OldDatabase::SYSTEM_COLLECTION_TEAMS: /** * Replace team:{self} with team:TEAM_ID */ - $read = $document->getWrite(); + $read = $document->getRead(); $write = $document->getWrite(); $document->setAttribute('$read', str_replace('team:{self}', "team:{$document->getId()}", $read)); $document->setAttribute('$write', str_replace('team:{self}', "team:{$document->getId()}", $write)); + /** + * Populate search string + */ + $document->setAttribute('search', $this->buildSearchAttribute(['$id', 'name'], $document)); + break; case OldDatabase::SYSTEM_COLLECTION_FILES: /** @@ -699,6 +736,12 @@ class V11 extends Migration */ $document->removeAttribute('folderId'); $document->removeAttribute('token'); + + /** + * Populate search string + */ + $document->setAttribute('search', $this->buildSearchAttribute(['$id', 'name'], $document)); + break; } @@ -818,4 +861,18 @@ class V11 extends Migration return $project->getId(); } + + /** + * Builds a search string for a fulltext index. + * + * @param array $values + * @param Document $document + * @return string + */ + private function buildSearchAttribute(array $values, Document $document): string + { + $values = array_filter(array_map(fn (string $value) => $document->getAttribute($value) ?? '', $values)); + + return implode(' ', $values); + } }