diff --git a/app/config/collections/common.php b/app/config/collections/common.php index f68400e226..866d7b6d5b 100644 --- a/app/config/collections/common.php +++ b/app/config/collections/common.php @@ -1417,6 +1417,13 @@ return [ 'lengths' => [], 'orders' => [Database::ORDER_ASC], ], + [ + '$id' => ID::custom('_key_roles'), + 'type' => Database::INDEX_KEY, + 'attributes' => ['roles'], + 'lengths' => [128], + 'orders' => [], + ], ], ], diff --git a/app/controllers/api/users.php b/app/controllers/api/users.php index 4a551b7478..17096731fa 100644 --- a/app/controllers/api/users.php +++ b/app/controllers/api/users.php @@ -21,6 +21,7 @@ use Appwrite\SDK\Method; use Appwrite\SDK\Response as SDKResponse; use Appwrite\Utopia\Database\Validator\CustomId; use Appwrite\Utopia\Database\Validator\Queries\Identities; +use Appwrite\Utopia\Database\Validator\Queries\Memberships; use Appwrite\Utopia\Database\Validator\Queries\Targets; use Appwrite\Utopia\Database\Validator\Queries\Users; use Appwrite\Utopia\Request; @@ -799,9 +800,11 @@ App::get('/v1/users/:userId/memberships') ] )) ->param('userId', '', new UID(), 'User ID.') + ->param('queries', [], new Memberships(), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' queries are allowed, each ' . APP_LIMIT_ARRAY_ELEMENT_SIZE . ' characters long. You may filter on the following attributes: ' . implode(', ', Memberships::ALLOWED_ATTRIBUTES), true) + ->param('search', '', new Text(256), 'Search term to filter your list results. Max length: 256 chars.', true) ->inject('response') ->inject('dbForProject') - ->action(function (string $userId, Response $response, Database $dbForProject) { + ->action(function (string $userId, array $queries, string $search, Response $response, Database $dbForProject) { $user = $dbForProject->getDocument('users', $userId); @@ -809,6 +812,19 @@ App::get('/v1/users/:userId/memberships') throw new Exception(Exception::USER_NOT_FOUND); } + try { + $queries = Query::parseQueries($queries); + } catch (QueryException $e) { + throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage()); + } + + if (!empty($search)) { + $queries[] = Query::search('search', $search); + } + + // Set internal queries + $queries[] = Query::equal('userInternalId', [$user->getInternalId()]); + $memberships = array_map(function ($membership) use ($dbForProject, $user) { $team = $dbForProject->getDocument('teams', $membership->getAttribute('teamId')); @@ -818,7 +834,7 @@ App::get('/v1/users/:userId/memberships') ->setAttribute('userEmail', $user->getAttribute('email')); return $membership; - }, $user->getAttribute('memberships', [])); + }, $dbForProject->find('memberships', $queries)); $response->dynamic(new Document([ 'memberships' => $memberships, diff --git a/src/Appwrite/Migration/Version/V22.php b/src/Appwrite/Migration/Version/V22.php index 4d15662112..c5fdfc9ed6 100644 --- a/src/Appwrite/Migration/Version/V22.php +++ b/src/Appwrite/Migration/Version/V22.php @@ -75,6 +75,14 @@ class V22 extends Migration Console::warning("'personalRefreshToken' from {$id}: {$th->getMessage()}"); } break; + case 'memberships': + // Create roles index + try { + $this->createIndexFromCollection($this->projectDB, $id, '_key_roles'); + } catch (Throwable $th) { + Console::warning("'_key_roles' from {$id}: {$th->getMessage()}"); + } + break; } usleep(50000); diff --git a/src/Appwrite/Utopia/Database/Validator/Queries/Memberships.php b/src/Appwrite/Utopia/Database/Validator/Queries/Memberships.php index 5ff0098662..cef562ba2c 100644 --- a/src/Appwrite/Utopia/Database/Validator/Queries/Memberships.php +++ b/src/Appwrite/Utopia/Database/Validator/Queries/Memberships.php @@ -9,12 +9,12 @@ class Memberships extends Base 'teamId', 'invited', 'joined', - 'confirm' + 'confirm', + 'roles', ]; /** * Expression constructor - * */ public function __construct() {