From d422b7abdcb887976b2dd7640d1fdce5c638b718 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Fri, 15 May 2026 11:44:47 +0200 Subject: [PATCH] Final reverts --- app/controllers/shared/api.php | 7 ++- app/init/resources/request.php | 96 +++++++++------------------------- 2 files changed, 29 insertions(+), 74 deletions(-) diff --git a/app/controllers/shared/api.php b/app/controllers/shared/api.php index 5bcb51355b..6e5167660a 100644 --- a/app/controllers/shared/api.php +++ b/app/controllers/shared/api.php @@ -313,10 +313,9 @@ Http::init() } $projectId = $project->getId(); - if ($projectId === 'console' && (str_starts_with($route->getPath(), '/v1/projects/:projectId') || str_starts_with($route->getPath(), '/v1/organization/projects'))) { + if ($projectId === 'console' && str_starts_with($route->getPath(), '/v1/projects/:projectId')) { $uri = $request->getURI(); - $parts = explode('/', $uri); - $projectId = str_starts_with($route->getPath(), '/v1/organization/projects') ? $parts[4] : $parts[3]; + $projectId = explode('/', $uri)[3]; } // Base scopes for admin users to allow listing teams and projects. @@ -341,7 +340,7 @@ Http::init() * For console projects resource, we use platform DB. * Enabling authorization restricts admin user to the projects they have access to. */ - if ($project->getId() === 'console' && ($route->getPath() === '/v1/projects' || $route->getPath() === '/v1/projects/:projectId' || $route->getPath() === '/v1/organization/projects')) { + if ($project->getId() === 'console' && ($route->getPath() === '/v1/projects' || $route->getPath() === '/v1/projects/:projectId')) { $authorization->setDefaultStatus(true); } else { // Otherwise, disable authorization checks. diff --git a/app/init/resources/request.php b/app/init/resources/request.php index e6382be032..85d8db3698 100644 --- a/app/init/resources/request.php +++ b/app/init/resources/request.php @@ -1,6 +1,5 @@ set('team', function (Document $project, Database $dbForPlatform, Http $utopia, Request $request, Authorization $authorization, Document $user) { - $teamId = ''; + $context->set('team', function (Document $project, Database $dbForPlatform, Http $utopia, Request $request, Authorization $authorization) { + $teamInternalId = ''; if ($project->getId() !== 'console') { - $teamId = $project->getAttribute('teamId', ''); + $teamInternalId = $project->getAttribute('teamInternalId', ''); } else { $route = $utopia->match($request); $path = ! empty($route) ? $route->getPath() : $request->getURI(); $orgHeader = $request->getHeader('x-appwrite-organization', ''); - - // Prioritx #1: If org ID header present, respect it - if (!empty($orgHeader)) { - $teamId = $orgHeader; - } elseif (\str_starts_with($path, '/v1/organization/projects')) { - // Backwards compatibility: /v1/organitation/projects acting as /v1/projects - - // Backwards compatibility: Take from payload param - // organizationId not required, but easy to use by mistake in future unknowingly - $teamId = $request->getParam('organizationId', $request->getParam('teamId', '')); - - // Backawrds compatibility: Get from URL param project ID - if (empty($teamId)) { - $projectId = \explode('/', $request->getURI())[4] ?? ''; - if (!empty($projectId)) { - $urlProject = $authorization->skip(fn () => $dbForPlatform->getDocument('projects', $projectId)); - $teamId = $urlProject->getAttribute('teamId', ''); - } - } - - // Backwards compatibility: Get from queries param - if (empty($teamId)) { - $queries = $request->getParam('queries', []); - $queries = \is_array($queries) ? $queries : [$queries]; - - try { - $queries = Query::parseQueries($queries); - $queries = Query::getByType($queries, [Query::TYPE_EQUAL]); - - foreach ($queries as $query) { - if ($query->getAttribute() === 'teamId') { - $teamId = $query->getValues()[0] ?? ''; - break; - } - } - } catch (QueryException $e) { - // Ignore, do not parse from queries - } - } - } elseif (str_starts_with($path, '/v1/projects/:projectId')) { + if (str_starts_with($path, '/v1/projects/:projectId')) { $uri = $request->getURI(); - $projectId = explode('/', $uri)[3]; - $project = $authorization->skip(fn () => $dbForPlatform->getDocument('projects', $projectId)); - $teamId = $project->getAttribute('teamId', ''); + $pid = explode('/', $uri)[3]; + $p = $authorization->skip(fn () => $dbForPlatform->getDocument('projects', $pid)); + $teamInternalId = $p->getAttribute('teamInternalId', ''); } elseif ($path === '/v1/projects') { $teamId = $request->getParam('teamId', ''); + + if (empty($teamId)) { + return new Document([]); + } + + $team = $authorization->skip(fn () => $dbForPlatform->getDocument('teams', $teamId)); + + return $team; + } elseif (! empty($orgHeader)) { + return $authorization->skip(fn () => $dbForPlatform->getDocument('teams', $orgHeader)); } } - // No team scenario - if (empty($teamId)) { + // if teamInternalId is empty, return an empty document + + if (empty($teamInternalId)) { return new Document([]); } - $team = $authorization->skip(function () use ($dbForPlatform, $teamId) { - return $dbForPlatform->getDocument('teams', $teamId); + $team = $authorization->skip(function () use ($dbForPlatform, $teamInternalId) { + return $dbForPlatform->findOne('teams', [ + Query::equal('$sequence', [$teamInternalId]), + ]); }); - // Unauthorized team scenario - // Ensure $user has membership in team - $memberships = $user->getAttribute('memberships', []); - foreach ($memberships as $membership) { - if ($membership->getAttribute('teamId', '') === $teamId) { - return $team; - } - } - - // API key auth bypasses membership check; key validity is verified later - if (!empty($request->getHeader('x-appwrite-key', ''))) { - return $team; - } - - // Unauthorized, do not allow the team - return new Document([]); - }, ['project', 'dbForPlatform', 'utopia', 'request', 'authorization', 'user']); + return $team; + }, ['project', 'dbForPlatform', 'utopia', 'request', 'authorization']); $context->set('previewHostname', function (Request $request, ?Key $apiKey) { $allowed = false;