Revert "Merge pull request #10682 from appwrite/refactor-auth-single-instance"

This reverts commit 919b01a1b1, reversing
changes made to deb5039352.
This commit is contained in:
Jake Barnby
2025-11-19 16:21:06 +13:00
parent e6039cf65e
commit 8765d5650a
180 changed files with 868 additions and 1248 deletions
+25 -28
View File
@@ -29,7 +29,6 @@ use Utopia\Database\DateTime;
use Utopia\Database\Document;
use Utopia\Database\Helpers\Role;
use Utopia\Database\Validator\Authorization;
use Utopia\Database\Validator\Authorization\Input;
use Utopia\Queue\Publisher;
use Utopia\System\System;
use Utopia\Telemetry\Adapter as Telemetry;
@@ -233,8 +232,7 @@ App::init()
->inject('mode')
->inject('team')
->inject('apiKey')
->inject('authorization')
->action(function (App $utopia, Request $request, Database $dbForPlatform, Database $dbForProject, Audit $queueForAudits, Document $project, Document $user, ?Document $session, array $servers, string $mode, Document $team, ?Key $apiKey, Authorization $authorization) {
->action(function (App $utopia, Request $request, Database $dbForPlatform, Database $dbForProject, Audit $queueForAudits, Document $project, Document $user, ?Document $session, array $servers, string $mode, Document $team, ?Key $apiKey) {
$route = $utopia->getRoute();
if (System::getEnv('_APP_EDITION', 'self-hosted') === 'self-hosted' && str_starts_with($route->getPath(), '/v1/backups')) {
throw new Exception(Exception::GENERAL_BAD_REQUEST, 'Database Backups are available on Appwrite Cloud');
@@ -266,7 +264,7 @@ App::init()
if ($apiKey->getRole() === Auth::USER_ROLE_APPS) {
// Disable authorization checks for API keys
$authorization->setDefaultStatus(false);
Authorization::setDefaultStatus(false);
$user = new Document([
'$id' => '',
@@ -339,14 +337,14 @@ App::init()
$scopes = \array_merge($scopes, $roles[$role]['scopes']);
}
$authorization->setDefaultStatus(false); // Cancel security segmentation for admin users.
Authorization::setDefaultStatus(false); // Cancel security segmentation for admin users.
}
$scopes = \array_unique($scopes);
$authorization->addRole($role);
foreach (Auth::getRoles($user, $authorization) as $authRole) {
$authorization->addRole($authRole);
Authorization::setRole($role);
foreach (Auth::getRoles($user) as $authRole) {
Authorization::setRole($authRole);
}
// Update project last activity
@@ -354,7 +352,7 @@ App::init()
$accessedAt = $project->getAttribute('accessedAt', 0);
if (DateTime::formatTz(DateTime::addSeconds(new \DateTime(), -APP_PROJECT_ACCESS)) > $accessedAt) {
$project->setAttribute('accessedAt', DateTime::now());
$authorization->skip(fn () => $dbForPlatform->updateDocument('projects', $project->getId(), $project));
Authorization::skip(fn () => $dbForPlatform->updateDocument('projects', $project->getId(), $project));
}
}
@@ -389,7 +387,7 @@ App::init()
if (
array_key_exists($namespace, $project->getAttribute('services', []))
&& !$project->getAttribute('services', [])[$namespace]
&& !(Auth::isPrivilegedUser($authorization->getRoles()) || Auth::isAppUser($authorization->getRoles()))
&& !(Auth::isPrivilegedUser(Authorization::getRoles()) || Auth::isAppUser(Authorization::getRoles()))
) {
throw new Exception(Exception::GENERAL_SERVICE_DISABLED);
}
@@ -449,15 +447,14 @@ App::init()
->inject('plan')
->inject('devKey')
->inject('telemetry')
->inject('authorization')
->action(function (App $utopia, Request $request, Response $response, Document $project, Document $user, Publisher $publisher, Publisher $publisherFunctions, Publisher $publisherWebhooks, Event $queueForEvents, Messaging $queueForMessaging, Audit $queueForAudits, Delete $queueForDeletes, EventDatabase $queueForDatabase, Build $queueForBuilds, StatsUsage $queueForStatsUsage, Database $dbForProject, callable $timelimit, Document $resourceToken, string $mode, ?Key $apiKey, array $plan, Document $devKey, Telemetry $telemetry, Authorization $authorization) use ($usageDatabaseListener, $eventDatabaseListener) {
->action(function (App $utopia, Request $request, Response $response, Document $project, Document $user, Publisher $publisher, Publisher $publisherFunctions, Publisher $publisherWebhooks, Event $queueForEvents, Messaging $queueForMessaging, Audit $queueForAudits, Delete $queueForDeletes, EventDatabase $queueForDatabase, Build $queueForBuilds, StatsUsage $queueForStatsUsage, Database $dbForProject, callable $timelimit, Document $resourceToken, string $mode, ?Key $apiKey, array $plan, Document $devKey, Telemetry $telemetry) use ($usageDatabaseListener, $eventDatabaseListener) {
$route = $utopia->getRoute();
if (
array_key_exists('rest', $project->getAttribute('apis', []))
&& !$project->getAttribute('apis', [])['rest']
&& !(Auth::isPrivilegedUser($authorization->getRoles()) || Auth::isAppUser($authorization->getRoles()))
&& !(Auth::isPrivilegedUser(Authorization::getRoles()) || Auth::isAppUser(Authorization::getRoles()))
) {
throw new AppwriteException(AppwriteException::GENERAL_API_DISABLED);
}
@@ -487,7 +484,7 @@ App::init()
$closestLimit = null;
$roles = $authorization->getRoles();
$roles = Authorization::getRoles();
$isPrivilegedUser = Auth::isPrivilegedUser($roles);
$isAppUser = Auth::isAppUser($roles);
@@ -587,10 +584,10 @@ App::init()
if ($useCache) {
$route = $utopia->match($request);
$isImageTransformation = $route->getPath() === '/v1/storage/buckets/:bucketId/files/:fileId/preview';
$isDisabled = isset($plan['imageTransformations']) && $plan['imageTransformations'] === -1 && !Auth::isPrivilegedUser($authorization->getRoles());
$isDisabled = isset($plan['imageTransformations']) && $plan['imageTransformations'] === -1 && !Auth::isPrivilegedUser(Authorization::getRoles());
$key = $request->cacheIdentifier();
$cacheLog = $authorization->skip(fn () => $dbForProject->getDocument('cache', $key));
$cacheLog = Authorization::skip(fn () => $dbForProject->getDocument('cache', $key));
$cache = new Cache(
new Filesystem(APP_STORAGE_CACHE . DIRECTORY_SEPARATOR . 'app-' . $project->getId())
);
@@ -607,10 +604,10 @@ App::init()
if ($type === 'bucket' && (!$isImageTransformation || !$isDisabled)) {
$bucketId = $parts[1] ?? null;
$bucket = $authorization->skip(fn () => $dbForProject->getDocument('buckets', $bucketId));
$bucket = Authorization::skip(fn () => $dbForProject->getDocument('buckets', $bucketId));
$isToken = !$resourceToken->isEmpty() && $resourceToken->getAttribute('bucketInternalId') === $bucket->getSequence();
$isPrivilegedUser = Auth::isPrivilegedUser($authorization->getRoles());
$isPrivilegedUser = Auth::isPrivilegedUser(Authorization::getRoles());
if ($bucket->isEmpty() || (!$bucket->getAttribute('enabled') && !$isAppUser && !$isPrivilegedUser)) {
throw new Exception(Exception::STORAGE_BUCKET_NOT_FOUND);
@@ -621,7 +618,8 @@ App::init()
}
$fileSecurity = $bucket->getAttribute('fileSecurity', false);
$valid = $authorization->isValid(new Input(Database::PERMISSION_READ, $bucket->getRead()));
$validator = new Authorization(Database::PERMISSION_READ);
$valid = $validator->isValid($bucket->getRead());
if (!$fileSecurity && !$valid && !$isToken) {
throw new Exception(Exception::USER_UNAUTHORIZED);
}
@@ -632,7 +630,7 @@ App::init()
if ($fileSecurity && !$valid && !$isToken) {
$file = $dbForProject->getDocument('bucket_' . $bucket->getSequence(), $fileId);
} else {
$file = $authorization->skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getSequence(), $fileId));
$file = Authorization::skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getSequence(), $fileId));
}
if (!$resourceToken->isEmpty() && $resourceToken->getAttribute('fileInternalId') !== $file->getSequence()) {
@@ -643,11 +641,11 @@ App::init()
throw new Exception(Exception::STORAGE_FILE_NOT_FOUND);
}
//Do not update transformedAt if it's a console user
if (!Auth::isPrivilegedUser($authorization->getRoles())) {
if (!Auth::isPrivilegedUser(Authorization::getRoles())) {
$transformedAt = $file->getAttribute('transformedAt', '');
if (DateTime::formatTz(DateTime::addSeconds(new \DateTime(), -APP_PROJECT_ACCESS)) > $transformedAt) {
$file->setAttribute('transformedAt', DateTime::now());
$authorization->skip(fn () => $dbForProject->updateDocument('bucket_' . $file->getAttribute('bucketInternalId'), $file->getId(), $file));
Authorization::skip(fn () => $dbForProject->updateDocument('bucket_' . $file->getAttribute('bucketInternalId'), $file->getId(), $file));
}
}
}
@@ -743,8 +741,7 @@ App::shutdown()
->inject('queueForWebhooks')
->inject('queueForRealtime')
->inject('dbForProject')
->inject('authorization')
->action(function (App $utopia, Request $request, Response $response, Document $project, Document $user, Event $queueForEvents, Audit $queueForAudits, StatsUsage $queueForStatsUsage, Delete $queueForDeletes, EventDatabase $queueForDatabase, Build $queueForBuilds, Messaging $queueForMessaging, Func $queueForFunctions, Event $queueForWebhooks, Realtime $queueForRealtime, Database $dbForProject, Authorization $authorization) use ($parseLabel) {
->action(function (App $utopia, Request $request, Response $response, Document $project, Document $user, Event $queueForEvents, Audit $queueForAudits, StatsUsage $queueForStatsUsage, Delete $queueForDeletes, EventDatabase $queueForDatabase, Build $queueForBuilds, Messaging $queueForMessaging, Func $queueForFunctions, Event $queueForWebhooks, Realtime $queueForRealtime, Database $dbForProject) use ($parseLabel) {
$responsePayload = $response->getPayload();
@@ -870,11 +867,11 @@ App::shutdown()
$key = $request->cacheIdentifier();
$signature = md5($data['payload']);
$cacheLog = $authorization->skip(fn () => $dbForProject->getDocument('cache', $key));
$cacheLog = Authorization::skip(fn () => $dbForProject->getDocument('cache', $key));
$accessedAt = $cacheLog->getAttribute('accessedAt', 0);
$now = DateTime::now();
if ($cacheLog->isEmpty()) {
$authorization->skip(fn () => $dbForProject->createDocument('cache', new Document([
Authorization::skip(fn () => $dbForProject->createDocument('cache', new Document([
'$id' => $key,
'resource' => $resource,
'resourceType' => $resourceType,
@@ -884,7 +881,7 @@ App::shutdown()
])));
} elseif (DateTime::formatTz(DateTime::addSeconds(new \DateTime(), -APP_CACHE_UPDATE)) > $accessedAt) {
$cacheLog->setAttribute('accessedAt', $now);
$authorization->skip(fn () => $dbForProject->updateDocument('cache', $cacheLog->getId(), $cacheLog));
Authorization::skip(fn () => $dbForProject->updateDocument('cache', $cacheLog->getId(), $cacheLog));
// Overwrite the file every APP_CACHE_UPDATE seconds to update the file modified time that is used in the TTL checks in cache->load()
$cache->save($key, $data['payload']);
}
@@ -896,7 +893,7 @@ App::shutdown()
}
if ($project->getId() !== 'console') {
if (!Auth::isPrivilegedUser($authorization->getRoles())) {
if (!Auth::isPrivilegedUser(Authorization::getRoles())) {
$fileSize = 0;
$file = $request->getFiles('file');
if (!empty($file)) {