Avatars tests are green!
This commit is contained in:
parent
6cade89369
commit
766b2ba13e
|
@ -58,13 +58,13 @@ use Utopia\System\System;
|
|||
$oauthDefaultSuccess = '/auth/oauth2/success';
|
||||
$oauthDefaultFailure = '/auth/oauth2/failure';
|
||||
|
||||
$createSession = function (string $userId, string $secret, Request $request, Response $response, Document $user, Database $dbForProject, Document $project, Locale $locale, Reader $geodb, Event $queueForEvents, Authorization $auth) {
|
||||
$roles = $auth->getRoles();
|
||||
$createSession = function (string $userId, string $secret, Request $request, Response $response, Document $user, Database $dbForProject, Document $project, Locale $locale, Reader $geodb, Event $queueForEvents, Authorization $authorization) {
|
||||
$roles = $authorization->getRoles();
|
||||
$isPrivilegedUser = Auth::isPrivilegedUser($roles);
|
||||
$isAppUser = Auth::isAppUser($roles);
|
||||
|
||||
/** @var Utopia\Database\Document $user */
|
||||
$userFromRequest = $auth->skip(fn () => $dbForProject->getDocument('users', $userId));
|
||||
$userFromRequest = $authorization->skip(fn () => $dbForProject->getDocument('users', $userId));
|
||||
|
||||
if ($userFromRequest->isEmpty()) {
|
||||
throw new Exception(Exception::USER_INVALID_TOKEN);
|
||||
|
@ -110,7 +110,7 @@ $createSession = function (string $userId, string $secret, Request $request, Res
|
|||
$detector->getDevice()
|
||||
));
|
||||
|
||||
$auth->addRole(Role::user($user->getId())->toString());
|
||||
$authorization->addRole(Role::user($user->getId())->toString());
|
||||
|
||||
$session = $dbForProject->createDocument('sessions', $session
|
||||
->setAttribute('$permissions', [
|
||||
|
@ -120,7 +120,7 @@ $createSession = function (string $userId, string $secret, Request $request, Res
|
|||
]));
|
||||
|
||||
$dbForProject->purgeCachedDocument('users', $user->getId());
|
||||
$auth->skip(fn () => $dbForProject->deleteDocument('tokens', $verifiedToken->getId()));
|
||||
$authorization->skip(fn () => $dbForProject->deleteDocument('tokens', $verifiedToken->getId()));
|
||||
$dbForProject->purgeCachedDocument('users', $user->getId());
|
||||
|
||||
if ($verifiedToken->getAttribute('type') === Auth::TOKEN_TYPE_MAGIC_URL) {
|
||||
|
@ -193,8 +193,8 @@ Http::post('/v1/account')
|
|||
->inject('dbForProject')
|
||||
->inject('queueForEvents')
|
||||
->inject('hooks')
|
||||
->inject('auth')
|
||||
->action(function (string $userId, string $email, string $password, string $name, Request $request, Response $response, Document $user, Document $project, Database $dbForProject, Event $queueForEvents, Hooks $hooks, Authorization $auth) {
|
||||
->inject('authorization')
|
||||
->action(function (string $userId, string $email, string $password, string $name, Request $request, Response $response, Document $user, Document $project, Database $dbForProject, Event $queueForEvents, Hooks $hooks, Authorization $authorization) {
|
||||
|
||||
$email = \strtolower($email);
|
||||
if ('console' === $project->getId()) {
|
||||
|
@ -269,9 +269,9 @@ Http::post('/v1/account')
|
|||
'accessedAt' => DateTime::now(),
|
||||
]);
|
||||
$user->removeAttribute('$internalId');
|
||||
$user = $auth->skip(fn () => $dbForProject->createDocument('users', $user));
|
||||
$user = $authorization->skip(fn () => $dbForProject->createDocument('users', $user));
|
||||
try {
|
||||
$target = $auth->skip(fn () => $dbForProject->createDocument('targets', new Document([
|
||||
$target = $authorization->skip(fn () => $dbForProject->createDocument('targets', new Document([
|
||||
'$permissions' => [
|
||||
Permission::read(Role::user($user->getId())),
|
||||
Permission::update(Role::user($user->getId())),
|
||||
|
@ -295,9 +295,9 @@ Http::post('/v1/account')
|
|||
throw new Exception(Exception::USER_ALREADY_EXISTS);
|
||||
}
|
||||
|
||||
$auth->removeRole(Role::guests()->toString());
|
||||
$auth->addRole(Role::user($user->getId())->toString());
|
||||
$auth->addRole(Role::users()->toString());
|
||||
$authorization->removeRole(Role::guests()->toString());
|
||||
$authorization->addRole(Role::user($user->getId())->toString());
|
||||
$authorization->addRole(Role::users()->toString());
|
||||
|
||||
$queueForEvents->setParam('userId', $user->getId());
|
||||
|
||||
|
@ -392,10 +392,10 @@ Http::get('/v1/account/sessions')
|
|||
->inject('response')
|
||||
->inject('user')
|
||||
->inject('locale')
|
||||
->inject('auth')
|
||||
->action(function (Response $response, Document $user, Locale $locale, Authorization $auth) {
|
||||
->inject('authorization')
|
||||
->action(function (Response $response, Document $user, Locale $locale, Authorization $authorization) {
|
||||
|
||||
$roles = $auth->getRoles();
|
||||
$roles = $authorization->getRoles();
|
||||
$isPrivilegedUser = Auth::isPrivilegedUser($roles);
|
||||
$isAppUser = Auth::isAppUser($roles);
|
||||
|
||||
|
@ -500,10 +500,10 @@ Http::get('/v1/account/sessions/:sessionId')
|
|||
->inject('response')
|
||||
->inject('user')
|
||||
->inject('locale')
|
||||
->inject('auth')
|
||||
->action(function (?string $sessionId, Response $response, Document $user, Locale $locale, Authorization $auth) {
|
||||
->inject('authorization')
|
||||
->action(function (?string $sessionId, Response $response, Document $user, Locale $locale, Authorization $authorization) {
|
||||
|
||||
$roles = $auth->getRoles();
|
||||
$roles = $authorization->getRoles();
|
||||
$isPrivilegedUser = Auth::isPrivilegedUser($roles);
|
||||
$isAppUser = Auth::isAppUser($roles);
|
||||
|
||||
|
@ -714,8 +714,8 @@ Http::post('/v1/account/sessions/email')
|
|||
->inject('geodb')
|
||||
->inject('queueForEvents')
|
||||
->inject('hooks')
|
||||
->inject('auth')
|
||||
->action(function (string $email, string $password, Request $request, Response $response, Document $user, Database $dbForProject, Document $project, Locale $locale, Reader $geodb, Event $queueForEvents, Hooks $hooks, Authorization $auth) {
|
||||
->inject('authorization')
|
||||
->action(function (string $email, string $password, Request $request, Response $response, Document $user, Database $dbForProject, Document $project, Locale $locale, Reader $geodb, Event $queueForEvents, Hooks $hooks, Authorization $authorization) {
|
||||
$email = \strtolower($email);
|
||||
$protocol = $request->getProtocol();
|
||||
|
||||
|
@ -731,7 +731,7 @@ Http::post('/v1/account/sessions/email')
|
|||
throw new Exception(Exception::USER_BLOCKED); // User is in status blocked
|
||||
}
|
||||
|
||||
$roles = $auth->getRoles();
|
||||
$roles = $authorization->getRoles();
|
||||
$isPrivilegedUser = Auth::isPrivilegedUser($roles);
|
||||
$isAppUser = Auth::isAppUser($roles);
|
||||
|
||||
|
@ -762,7 +762,7 @@ Http::post('/v1/account/sessions/email')
|
|||
$detector->getDevice()
|
||||
));
|
||||
|
||||
$auth->addRole(Role::user($user->getId())->toString());
|
||||
$authorization->addRole(Role::user($user->getId())->toString());
|
||||
|
||||
// Re-hash if not using recommended algo
|
||||
if ($user->getAttribute('hash') !== Auth::DEFAULT_ALGO) {
|
||||
|
@ -837,10 +837,10 @@ Http::post('/v1/account/sessions/anonymous')
|
|||
->inject('dbForProject')
|
||||
->inject('geodb')
|
||||
->inject('queueForEvents')
|
||||
->inject('auth')
|
||||
->action(function (Request $request, Response $response, Locale $locale, Document $user, Document $project, Database $dbForProject, Reader $geodb, Event $queueForEvents, Authorization $auth) {
|
||||
->inject('authorization')
|
||||
->action(function (Request $request, Response $response, Locale $locale, Document $user, Document $project, Database $dbForProject, Reader $geodb, Event $queueForEvents, Authorization $authorization) {
|
||||
$protocol = $request->getProtocol();
|
||||
$roles = $auth->getRoles();
|
||||
$roles = $authorization->getRoles();
|
||||
$isPrivilegedUser = Auth::isPrivilegedUser($roles);
|
||||
$isAppUser = Auth::isAppUser($roles);
|
||||
|
||||
|
@ -886,7 +886,7 @@ Http::post('/v1/account/sessions/anonymous')
|
|||
'accessedAt' => DateTime::now(),
|
||||
]);
|
||||
$user->removeAttribute('$internalId');
|
||||
$auth->skip(fn () => $dbForProject->createDocument('users', $user));
|
||||
$authorization->skip(fn () => $dbForProject->createDocument('users', $user));
|
||||
|
||||
// Create session token
|
||||
$duration = $project->getAttribute('auths', [])['duration'] ?? Auth::TOKEN_EXPIRATION_LOGIN_LONG;
|
||||
|
@ -912,7 +912,7 @@ Http::post('/v1/account/sessions/anonymous')
|
|||
$detector->getDevice()
|
||||
));
|
||||
|
||||
$auth->addRole(Role::user($user->getId())->toString());
|
||||
$authorization->addRole(Role::user($user->getId())->toString());
|
||||
|
||||
$session = $dbForProject->createDocument('sessions', $session-> setAttribute('$permissions', [
|
||||
Permission::read(Role::user($user->getId())),
|
||||
|
@ -1138,8 +1138,8 @@ Http::get('/v1/account/sessions/oauth2/:provider/redirect')
|
|||
->inject('dbForProject')
|
||||
->inject('geodb')
|
||||
->inject('queueForEvents')
|
||||
->inject('auth')
|
||||
->action(function (string $provider, string $code, string $state, string $error, string $error_description, Request $request, Response $response, Document $project, Document $user, Database $dbForProject, Reader $geodb, Event $queueForEvents, Authorization $auth) use ($oauthDefaultSuccess) {
|
||||
->inject('authorization')
|
||||
->action(function (string $provider, string $code, string $state, string $error, string $error_description, Request $request, Response $response, Document $project, Document $user, Database $dbForProject, Reader $geodb, Event $queueForEvents, Authorization $authorization) use ($oauthDefaultSuccess) {
|
||||
$protocol = $request->getProtocol();
|
||||
$callback = $protocol . '://' . $request->getHostname() . '/v1/account/sessions/oauth2/callback/' . $provider . '/' . $project->getId();
|
||||
$defaultState = ['success' => $project->getAttribute('url', ''), 'failure' => ''];
|
||||
|
@ -1363,7 +1363,7 @@ Http::get('/v1/account/sessions/oauth2/:provider/redirect')
|
|||
'accessedAt' => DateTime::now(),
|
||||
]);
|
||||
$user->removeAttribute('$internalId');
|
||||
$user = $auth->skip(fn () => $dbForProject->createDocument('users', $user));
|
||||
$user = $authorization->skip(fn () => $dbForProject->createDocument('users', $user));
|
||||
|
||||
$dbForProject->createDocument('targets', new Document([
|
||||
'$permissions' => [
|
||||
|
@ -1382,8 +1382,8 @@ Http::get('/v1/account/sessions/oauth2/:provider/redirect')
|
|||
}
|
||||
}
|
||||
|
||||
$auth->addRole(Role::user($user->getId())->toString());
|
||||
$auth->addRole(Role::users()->toString());
|
||||
$authorization->addRole(Role::user($user->getId())->toString());
|
||||
$authorization->addRole(Role::users()->toString());
|
||||
|
||||
if (false === $user->getAttribute('status')) { // Account is blocked
|
||||
$failureRedirect(Exception::USER_BLOCKED); // User is in status blocked
|
||||
|
@ -1442,7 +1442,7 @@ Http::get('/v1/account/sessions/oauth2/:provider/redirect')
|
|||
|
||||
$dbForProject->updateDocument('users', $user->getId(), $user);
|
||||
|
||||
$auth->addRole(Role::user($user->getId())->toString());
|
||||
$authorization->addRole(Role::user($user->getId())->toString());
|
||||
|
||||
$state['success'] = URLParser::parse($state['success']);
|
||||
$query = URLParser::parseQuery($state['success']['query']);
|
||||
|
@ -1464,7 +1464,7 @@ Http::get('/v1/account/sessions/oauth2/:provider/redirect')
|
|||
'ip' => $request->getIP(),
|
||||
]);
|
||||
|
||||
$auth->addRole(Role::user($user->getId())->toString());
|
||||
$authorization->addRole(Role::user($user->getId())->toString());
|
||||
|
||||
$token = $dbForProject->createDocument('tokens', $token
|
||||
->setAttribute('$permissions', [
|
||||
|
@ -1663,8 +1663,8 @@ Http::post('/v1/account/tokens/magic-url')
|
|||
->inject('locale')
|
||||
->inject('queueForEvents')
|
||||
->inject('queueForMails')
|
||||
->inject('Auth')
|
||||
->action(function (string $userId, string $email, string $url, bool $phrase, Request $request, Response $response, Document $user, Document $project, Database $dbForProject, Locale $locale, Event $queueForEvents, Mail $queueForMails, Authorization $auth) {
|
||||
->inject('authorization')
|
||||
->action(function (string $userId, string $email, string $url, bool $phrase, Request $request, Response $response, Document $user, Document $project, Database $dbForProject, Locale $locale, Event $queueForEvents, Mail $queueForMails, Authorization $authorization) {
|
||||
|
||||
if (empty(System::getEnv('_APP_SMTP_HOST'))) {
|
||||
throw new Exception(Exception::GENERAL_SMTP_DISABLED, 'SMTP disabled');
|
||||
|
@ -1674,7 +1674,7 @@ Http::post('/v1/account/tokens/magic-url')
|
|||
$phrase = Phrase::generate();
|
||||
}
|
||||
|
||||
$roles = $auth->getRoles();
|
||||
$roles = $authorization->getRoles();
|
||||
$isPrivilegedUser = Auth::isPrivilegedUser($roles);
|
||||
$isAppUser = Auth::isAppUser($roles);
|
||||
|
||||
|
@ -1729,7 +1729,7 @@ Http::post('/v1/account/tokens/magic-url')
|
|||
]);
|
||||
|
||||
$user->removeAttribute('$internalId');
|
||||
$user = $auth->skip(fn () => $dbForProject->createDocument('users', $user));
|
||||
$user = $authorization->skip(fn () => $dbForProject->createDocument('users', $user));
|
||||
}
|
||||
|
||||
$tokenSecret = Auth::tokenGenerator(Auth::TOKEN_LENGTH_MAGIC_URL);
|
||||
|
@ -1746,7 +1746,7 @@ Http::post('/v1/account/tokens/magic-url')
|
|||
'ip' => $request->getIP(),
|
||||
]);
|
||||
|
||||
$auth->addRole(Role::user($user->getId())->toString());
|
||||
$authorization->addRole(Role::user($user->getId())->toString());
|
||||
|
||||
$token = $dbForProject->createDocument('tokens', $token
|
||||
->setAttribute('$permissions', [
|
||||
|
@ -1906,8 +1906,8 @@ Http::post('/v1/account/tokens/email')
|
|||
->inject('locale')
|
||||
->inject('queueForEvents')
|
||||
->inject('queueForMails')
|
||||
->inject('auth')
|
||||
->action(function (string $userId, string $email, bool $phrase, Request $request, Response $response, Document $user, Document $project, Database $dbForProject, Locale $locale, Event $queueForEvents, Mail $queueForMails, Authorization $auth) {
|
||||
->inject('authorization')
|
||||
->action(function (string $userId, string $email, bool $phrase, Request $request, Response $response, Document $user, Document $project, Database $dbForProject, Locale $locale, Event $queueForEvents, Mail $queueForMails, Authorization $authorization) {
|
||||
if (empty(System::getEnv('_APP_SMTP_HOST'))) {
|
||||
throw new Exception(Exception::GENERAL_SMTP_DISABLED, 'SMTP disabled');
|
||||
}
|
||||
|
@ -1916,7 +1916,7 @@ Http::post('/v1/account/tokens/email')
|
|||
$phrase = Phrase::generate();
|
||||
}
|
||||
|
||||
$roles = $auth->getRoles();
|
||||
$roles = $authorization->getRoles();
|
||||
$isPrivilegedUser = Auth::isPrivilegedUser($roles);
|
||||
$isAppUser = Auth::isAppUser($roles);
|
||||
|
||||
|
@ -1969,7 +1969,7 @@ Http::post('/v1/account/tokens/email')
|
|||
]);
|
||||
|
||||
$user->removeAttribute('$internalId');
|
||||
$user = $auth->skip(fn () => $dbForProject->createDocument('users', $user));
|
||||
$user = $authorization->skip(fn () => $dbForProject->createDocument('users', $user));
|
||||
}
|
||||
|
||||
$tokenSecret = Auth::codeGenerator(6);
|
||||
|
@ -1986,7 +1986,7 @@ Http::post('/v1/account/tokens/email')
|
|||
'ip' => $request->getIP(),
|
||||
]);
|
||||
|
||||
$auth->addRole(Role::user($user->getId())->toString());
|
||||
$authorization->addRole(Role::user($user->getId())->toString());
|
||||
|
||||
$token = $dbForProject->createDocument('tokens', $token
|
||||
->setAttribute('$permissions', [
|
||||
|
@ -2136,7 +2136,7 @@ Http::put('/v1/account/sessions/magic-url')
|
|||
->inject('locale')
|
||||
->inject('geodb')
|
||||
->inject('queueForEvents')
|
||||
->inject('auth')
|
||||
->inject('authorization')
|
||||
->action($createSession);
|
||||
|
||||
Http::put('/v1/account/sessions/phone')
|
||||
|
@ -2167,7 +2167,7 @@ Http::put('/v1/account/sessions/phone')
|
|||
->inject('locale')
|
||||
->inject('geodb')
|
||||
->inject('queueForEvents')
|
||||
->inject('auth')
|
||||
->inject('authorization')
|
||||
->action($createSession);
|
||||
|
||||
Http::post('/v1/account/tokens/phone')
|
||||
|
@ -2198,13 +2198,13 @@ Http::post('/v1/account/tokens/phone')
|
|||
->inject('queueForEvents')
|
||||
->inject('queueForMessaging')
|
||||
->inject('locale')
|
||||
->inject('auth')
|
||||
->action(function (string $userId, string $phone, Request $request, Response $response, Document $user, Document $project, Database $dbForProject, Event $queueForEvents, Messaging $queueForMessaging, Locale $locale, Authorization $auth) {
|
||||
->inject('authorization')
|
||||
->action(function (string $userId, string $phone, Request $request, Response $response, Document $user, Document $project, Database $dbForProject, Event $queueForEvents, Messaging $queueForMessaging, Locale $locale, Authorization $authorization) {
|
||||
if (empty(System::getEnv('_APP_SMS_PROVIDER'))) {
|
||||
throw new Exception(Exception::GENERAL_PHONE_DISABLED, 'Phone provider not configured');
|
||||
}
|
||||
|
||||
$roles = $auth->getRoles();
|
||||
$roles = $authorization->getRoles();
|
||||
$isPrivilegedUser = Auth::isPrivilegedUser($roles);
|
||||
$isAppUser = Auth::isAppUser($roles);
|
||||
|
||||
|
@ -2248,9 +2248,9 @@ Http::post('/v1/account/tokens/phone')
|
|||
]);
|
||||
|
||||
$user->removeAttribute('$internalId');
|
||||
$user = $auth->skip(fn () => $dbForProject->createDocument('users', $user));
|
||||
$user = $authorization->skip(fn () => $dbForProject->createDocument('users', $user));
|
||||
try {
|
||||
$target = $auth->skip(fn () => $dbForProject->createDocument('targets', new Document([
|
||||
$target = $authorization->skip(fn () => $dbForProject->createDocument('targets', new Document([
|
||||
'$permissions' => [
|
||||
Permission::read(Role::user($user->getId())),
|
||||
Permission::update(Role::user($user->getId())),
|
||||
|
@ -2285,7 +2285,7 @@ Http::post('/v1/account/tokens/phone')
|
|||
'ip' => $request->getIP(),
|
||||
]);
|
||||
|
||||
$auth->addRole(Role::user($user->getId())->toString());
|
||||
$authorization->addRole(Role::user($user->getId())->toString());
|
||||
|
||||
$token = $dbForProject->createDocument('tokens', $token
|
||||
->setAttribute('$permissions', [
|
||||
|
@ -2427,8 +2427,8 @@ Http::get('/v1/account/logs')
|
|||
->inject('locale')
|
||||
->inject('geodb')
|
||||
->inject('dbForProject')
|
||||
->inject('auth')
|
||||
->action(function (array $queries, Response $response, Document $user, Locale $locale, Reader $geodb, Database $dbForProject, Authorization $auth) {
|
||||
->inject('authorization')
|
||||
->action(function (array $queries, Response $response, Document $user, Locale $locale, Reader $geodb, Database $dbForProject, Authorization $authorization) {
|
||||
|
||||
try {
|
||||
$queries = Query::parseQueries($queries);
|
||||
|
@ -2440,7 +2440,7 @@ Http::get('/v1/account/logs')
|
|||
$limit = $grouped['limit'] ?? APP_LIMIT_COUNT;
|
||||
$offset = $grouped['offset'] ?? 0;
|
||||
|
||||
$audit = new EventAudit($dbForProject, $auth);
|
||||
$audit = new EventAudit($dbForProject, $authorization);
|
||||
|
||||
$logs = $audit->getLogsByUser($user->getInternalId(), $limit, $offset);
|
||||
|
||||
|
@ -2603,8 +2603,8 @@ Http::patch('/v1/account/email')
|
|||
->inject('queueForEvents')
|
||||
->inject('project')
|
||||
->inject('hooks')
|
||||
->inject('auth')
|
||||
->action(function (string $email, string $password, ?\DateTime $requestTimestamp, Response $response, Document $user, Database $dbForProject, Event $queueForEvents, Document $project, Hooks $hooks, Authorization $auth) {
|
||||
->inject('authorization')
|
||||
->action(function (string $email, string $password, ?\DateTime $requestTimestamp, Response $response, Document $user, Database $dbForProject, Event $queueForEvents, Document $project, Hooks $hooks, Authorization $authorization) {
|
||||
// passwordUpdate will be empty if the user has never set a password
|
||||
$passwordUpdate = $user->getAttribute('passwordUpdate');
|
||||
|
||||
|
@ -2643,7 +2643,7 @@ Http::patch('/v1/account/email')
|
|||
->setAttribute('passwordUpdate', DateTime::now());
|
||||
}
|
||||
|
||||
$target = $auth->skip(fn () => $dbForProject->findOne('targets', [
|
||||
$target = $authorization->skip(fn () => $dbForProject->findOne('targets', [
|
||||
Query::equal('identifier', [$email]),
|
||||
]));
|
||||
|
||||
|
@ -2659,7 +2659,7 @@ Http::patch('/v1/account/email')
|
|||
$oldTarget = $user->find('identifier', $oldEmail, 'targets');
|
||||
|
||||
if ($oldTarget instanceof Document && !$oldTarget->isEmpty()) {
|
||||
$auth->skip(fn () => $dbForProject->updateDocument('targets', $oldTarget->getId(), $oldTarget->setAttribute('identifier', $email)));
|
||||
$authorization->skip(fn () => $dbForProject->updateDocument('targets', $oldTarget->getId(), $oldTarget->setAttribute('identifier', $email)));
|
||||
}
|
||||
$dbForProject->purgeCachedDocument('users', $user->getId());
|
||||
} catch (Duplicate) {
|
||||
|
@ -2696,8 +2696,8 @@ Http::patch('/v1/account/phone')
|
|||
->inject('queueForEvents')
|
||||
->inject('project')
|
||||
->inject('hooks')
|
||||
->inject('auth')
|
||||
->action(function (string $phone, string $password, ?\DateTime $requestTimestamp, Response $response, Document $user, Database $dbForProject, Event $queueForEvents, Document $project, Hooks $hooks, Authorization $auth) {
|
||||
->inject('authorization')
|
||||
->action(function (string $phone, string $password, ?\DateTime $requestTimestamp, Response $response, Document $user, Database $dbForProject, Event $queueForEvents, Document $project, Hooks $hooks, Authorization $authorization) {
|
||||
// passwordUpdate will be empty if the user has never set a password
|
||||
$passwordUpdate = $user->getAttribute('passwordUpdate');
|
||||
|
||||
|
@ -2710,7 +2710,7 @@ Http::patch('/v1/account/phone')
|
|||
|
||||
$hooks->trigger('passwordValidator', [$dbForProject, $project, $password, &$user, false]);
|
||||
|
||||
$target = $auth->skip(fn () => $dbForProject->findOne('targets', [
|
||||
$target = $authorization->skip(fn () => $dbForProject->findOne('targets', [
|
||||
Query::equal('identifier', [$phone]),
|
||||
]));
|
||||
|
||||
|
@ -2741,7 +2741,7 @@ Http::patch('/v1/account/phone')
|
|||
$oldTarget = $user->find('identifier', $oldPhone, 'targets');
|
||||
|
||||
if ($oldTarget instanceof Document && !$oldTarget->isEmpty()) {
|
||||
$auth->skip(fn () => $dbForProject->updateDocument('targets', $oldTarget->getId(), $oldTarget->setAttribute('identifier', $phone)));
|
||||
$authorization->skip(fn () => $dbForProject->updateDocument('targets', $oldTarget->getId(), $oldTarget->setAttribute('identifier', $phone)));
|
||||
}
|
||||
$dbForProject->purgeCachedDocument('users', $user->getId());
|
||||
} catch (Duplicate $th) {
|
||||
|
@ -2856,14 +2856,14 @@ Http::post('/v1/account/recovery')
|
|||
->inject('locale')
|
||||
->inject('queueForMails')
|
||||
->inject('queueForEvents')
|
||||
->inject('auth')
|
||||
->action(function (string $email, string $url, Request $request, Response $response, Document $user, Database $dbForProject, Document $project, Locale $locale, Mail $queueForMails, Event $queueForEvents, Authorization $auth) {
|
||||
->inject('authorization')
|
||||
->action(function (string $email, string $url, Request $request, Response $response, Document $user, Database $dbForProject, Document $project, Locale $locale, Mail $queueForMails, Event $queueForEvents, Authorization $authorization) {
|
||||
|
||||
if (empty(System::getEnv('_APP_SMTP_HOST'))) {
|
||||
throw new Exception(Exception::GENERAL_SMTP_DISABLED, 'SMTP Disabled');
|
||||
}
|
||||
|
||||
$roles = $auth->getRoles();
|
||||
$roles = $authorization->getRoles();
|
||||
$isPrivilegedUser = Auth::isPrivilegedUser($roles);
|
||||
$isAppUser = Auth::isAppUser($roles);
|
||||
|
||||
|
@ -2897,7 +2897,7 @@ Http::post('/v1/account/recovery')
|
|||
'ip' => $request->getIP(),
|
||||
]);
|
||||
|
||||
$auth->addRole(Role::user($profile->getId())->toString());
|
||||
$authorization->addRole(Role::user($profile->getId())->toString());
|
||||
|
||||
$recovery = $dbForProject->createDocument('tokens', $recovery
|
||||
->setAttribute('$permissions', [
|
||||
|
@ -3034,8 +3034,8 @@ Http::put('/v1/account/recovery')
|
|||
->inject('project')
|
||||
->inject('queueForEvents')
|
||||
->inject('hooks')
|
||||
->inject('auth')
|
||||
->action(function (string $userId, string $secret, string $password, Response $response, Document $user, Database $dbForProject, Document $project, Event $queueForEvents, Hooks $hooks, Authorization $auth) {
|
||||
->inject('authorization')
|
||||
->action(function (string $userId, string $secret, string $password, Response $response, Document $user, Database $dbForProject, Document $project, Event $queueForEvents, Hooks $hooks, Authorization $authorization) {
|
||||
$profile = $dbForProject->getDocument('users', $userId);
|
||||
|
||||
if ($profile->isEmpty()) {
|
||||
|
@ -3049,7 +3049,7 @@ Http::put('/v1/account/recovery')
|
|||
throw new Exception(Exception::USER_INVALID_TOKEN);
|
||||
}
|
||||
|
||||
$auth->addRole(Role::user($profile->getId())->toString());
|
||||
$authorization->addRole(Role::user($profile->getId())->toString());
|
||||
|
||||
$newPassword = Auth::passwordHash($password, Auth::DEFAULT_ALGO, Auth::DEFAULT_ALGO_OPTIONS);
|
||||
|
||||
|
@ -3119,8 +3119,8 @@ Http::post('/v1/account/verification')
|
|||
->inject('locale')
|
||||
->inject('queueForEvents')
|
||||
->inject('queueForMails')
|
||||
->inject('auth')
|
||||
->action(function (string $url, Request $request, Response $response, Document $project, Document $user, Database $dbForProject, Locale $locale, Event $queueForEvents, Mail $queueForMails, Authorization $auth) {
|
||||
->inject('authorization')
|
||||
->action(function (string $url, Request $request, Response $response, Document $project, Document $user, Database $dbForProject, Locale $locale, Event $queueForEvents, Mail $queueForMails, Authorization $authorization) {
|
||||
|
||||
if (empty(System::getEnv('_APP_SMTP_HOST'))) {
|
||||
throw new Exception(Exception::GENERAL_SMTP_DISABLED, 'SMTP Disabled');
|
||||
|
@ -3130,7 +3130,7 @@ Http::post('/v1/account/verification')
|
|||
throw new Exception(Exception::USER_EMAIL_ALREADY_VERIFIED);
|
||||
}
|
||||
|
||||
$roles = $auth->getRoles();
|
||||
$roles = $authorization->getRoles();
|
||||
$isPrivilegedUser = Auth::isPrivilegedUser($roles);
|
||||
$isAppUser = Auth::isAppUser($roles);
|
||||
$verificationSecret = Auth::tokenGenerator(Auth::TOKEN_LENGTH_VERIFICATION);
|
||||
|
@ -3147,7 +3147,7 @@ Http::post('/v1/account/verification')
|
|||
'ip' => $request->getIP(),
|
||||
]);
|
||||
|
||||
$auth->addRole(Role::user($user->getId())->toString());
|
||||
$authorization->addRole(Role::user($user->getId())->toString());
|
||||
|
||||
$verification = $dbForProject->createDocument('tokens', $verification
|
||||
->setAttribute('$permissions', [
|
||||
|
@ -3278,10 +3278,10 @@ Http::put('/v1/account/verification')
|
|||
->inject('user')
|
||||
->inject('dbForProject')
|
||||
->inject('queueForEvents')
|
||||
->inject('auth')
|
||||
->action(function (string $userId, string $secret, Response $response, Document $user, Database $dbForProject, Event $queueForEvents, Authorization $auth) {
|
||||
->inject('authorization')
|
||||
->action(function (string $userId, string $secret, Response $response, Document $user, Database $dbForProject, Event $queueForEvents, Authorization $authorization) {
|
||||
|
||||
$profile = $auth->skip(fn () => $dbForProject->getDocument('users', $userId));
|
||||
$profile = $authorization->skip(fn () => $dbForProject->getDocument('users', $userId));
|
||||
|
||||
if ($profile->isEmpty()) {
|
||||
throw new Exception(Exception::USER_NOT_FOUND);
|
||||
|
@ -3294,7 +3294,7 @@ Http::put('/v1/account/verification')
|
|||
throw new Exception(Exception::USER_INVALID_TOKEN);
|
||||
}
|
||||
|
||||
$auth->addRole(Role::user($profile->getId())->toString());
|
||||
$authorization->addRole(Role::user($profile->getId())->toString());
|
||||
|
||||
$profile = $dbForProject->updateDocument('users', $profile->getId(), $profile->setAttribute('emailVerification', true));
|
||||
|
||||
|
@ -3342,8 +3342,8 @@ Http::post('/v1/account/verification/phone')
|
|||
->inject('queueForMessaging')
|
||||
->inject('project')
|
||||
->inject('locale')
|
||||
->inject('auth')
|
||||
->action(function (Request $request, Response $response, Document $user, Database $dbForProject, Event $queueForEvents, Messaging $queueForMessaging, Document $project, Locale $locale, Authorization $auth) {
|
||||
->inject('authorization')
|
||||
->action(function (Request $request, Response $response, Document $user, Database $dbForProject, Event $queueForEvents, Messaging $queueForMessaging, Document $project, Locale $locale, Authorization $authorization) {
|
||||
if (empty(System::getEnv('_APP_SMS_PROVIDER'))) {
|
||||
throw new Exception(Exception::GENERAL_PHONE_DISABLED, 'Phone provider not configured');
|
||||
}
|
||||
|
@ -3356,7 +3356,7 @@ Http::post('/v1/account/verification/phone')
|
|||
throw new Exception(Exception::USER_PHONE_ALREADY_VERIFIED);
|
||||
}
|
||||
|
||||
$roles = $auth->getRoles();
|
||||
$roles = $authorization->getRoles();
|
||||
$isPrivilegedUser = Auth::isPrivilegedUser($roles);
|
||||
$isAppUser = Auth::isAppUser($roles);
|
||||
$secret = Auth::codeGenerator();
|
||||
|
@ -3373,7 +3373,7 @@ Http::post('/v1/account/verification/phone')
|
|||
'ip' => $request->getIP(),
|
||||
]);
|
||||
|
||||
$auth->addRole(Role::user($user->getId())->toString());
|
||||
$authorization->addRole(Role::user($user->getId())->toString());
|
||||
|
||||
$verification = $dbForProject->createDocument('tokens', $verification
|
||||
->setAttribute('$permissions', [
|
||||
|
@ -3452,10 +3452,10 @@ Http::put('/v1/account/verification/phone')
|
|||
->inject('user')
|
||||
->inject('dbForProject')
|
||||
->inject('queueForEvents')
|
||||
->inject('auth')
|
||||
->action(function (string $userId, string $secret, Response $response, Document $user, Database $dbForProject, Event $queueForEvents, Authorization $auth) {
|
||||
->inject('authorization')
|
||||
->action(function (string $userId, string $secret, Response $response, Document $user, Database $dbForProject, Event $queueForEvents, Authorization $authorization) {
|
||||
|
||||
$profile = $auth->skip(fn () => $dbForProject->getDocument('users', $userId));
|
||||
$profile = $authorization->skip(fn () => $dbForProject->getDocument('users', $userId));
|
||||
|
||||
if ($profile->isEmpty()) {
|
||||
throw new Exception(Exception::USER_NOT_FOUND);
|
||||
|
@ -3467,7 +3467,7 @@ Http::put('/v1/account/verification/phone')
|
|||
throw new Exception(Exception::USER_INVALID_TOKEN);
|
||||
}
|
||||
|
||||
$auth->addRole(Role::user($profile->getId())->toString());
|
||||
$authorization->addRole(Role::user($profile->getId())->toString());
|
||||
|
||||
$profile = $dbForProject->updateDocument('users', $profile->getId(), $profile->setAttribute('phoneVerification', true));
|
||||
|
||||
|
@ -4153,13 +4153,13 @@ Http::post('/v1/account/targets/push')
|
|||
->inject('request')
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->inject('auth')
|
||||
->action(function (string $targetId, string $identifier, string $providerId, Event $queueForEvents, Document $user, Request $request, Response $response, Database $dbForProject, Authorization $auth) {
|
||||
->inject('authorization')
|
||||
->action(function (string $targetId, string $identifier, string $providerId, Event $queueForEvents, Document $user, Request $request, Response $response, Database $dbForProject, Authorization $authorization) {
|
||||
$targetId = $targetId == 'unique()' ? ID::unique() : $targetId;
|
||||
|
||||
$provider = $auth->skip(fn () => $dbForProject->getDocument('providers', $providerId));
|
||||
$provider = $authorization->skip(fn () => $dbForProject->getDocument('providers', $providerId));
|
||||
|
||||
$target = $auth->skip(fn () => $dbForProject->getDocument('targets', $targetId));
|
||||
$target = $authorization->skip(fn () => $dbForProject->getDocument('targets', $targetId));
|
||||
|
||||
if (!$target->isEmpty()) {
|
||||
throw new Exception(Exception::USER_TARGET_ALREADY_EXISTS);
|
||||
|
@ -4226,10 +4226,10 @@ Http::put('/v1/account/targets/:targetId/push')
|
|||
->inject('request')
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->inject('auth')
|
||||
->action(function (string $targetId, string $identifier, Event $queueForEvents, Document $user, Request $request, Response $response, Database $dbForProject, Authorization $auth) {
|
||||
->inject('authorization')
|
||||
->action(function (string $targetId, string $identifier, Event $queueForEvents, Document $user, Request $request, Response $response, Database $dbForProject, Authorization $authorization) {
|
||||
|
||||
$target = $auth->skip(fn () => $dbForProject->getDocument('targets', $targetId));
|
||||
$target = $authorization->skip(fn () => $dbForProject->getDocument('targets', $targetId));
|
||||
|
||||
if ($target->isEmpty()) {
|
||||
throw new Exception(Exception::USER_TARGET_NOT_FOUND);
|
||||
|
@ -4282,9 +4282,9 @@ Http::delete('/v1/account/targets/:targetId/push')
|
|||
->inject('request')
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->inject('auth')
|
||||
->action(function (string $targetId, Event $queueForEvents, Delete $queueForDeletes, Document $user, Request $request, Response $response, Database $dbForProject, Authorization $auth) {
|
||||
$target = $auth->skip(fn () => $dbForProject->getDocument('targets', $targetId));
|
||||
->inject('authorization')
|
||||
->action(function (string $targetId, Event $queueForEvents, Delete $queueForDeletes, Document $user, Request $request, Response $response, Database $dbForProject, Authorization $authorization) {
|
||||
$target = $authorization->skip(fn () => $dbForProject->getDocument('targets', $targetId));
|
||||
|
||||
if ($target->isEmpty()) {
|
||||
throw new Exception(Exception::USER_TARGET_NOT_FOUND);
|
||||
|
|
|
@ -17,6 +17,8 @@ use Utopia\Abuse\Adapters\TimeLimit;
|
|||
use Utopia\Audit\Audit;
|
||||
use Utopia\Cache\Cache;
|
||||
use Utopia\Config\Config;
|
||||
use Utopia\Database\Adapter\MariaDB;
|
||||
use Utopia\Database\Adapter\MySQL;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Database\Exception\Duplicate;
|
||||
|
@ -79,9 +81,9 @@ Http::post('/v1/projects')
|
|||
->inject('dbForConsole')
|
||||
->inject('cache')
|
||||
->inject('pools')
|
||||
->inject('auth')
|
||||
->inject('authorization')
|
||||
->inject('connections')
|
||||
->action(function (string $projectId, string $name, string $teamId, string $region, string $description, string $logo, string $url, string $legalName, string $legalCountry, string $legalState, string $legalCity, string $legalAddress, string $legalTaxId, Response $response, Database $dbForConsole, Cache $cache, Group $pools, Authorization $auth, Connections $connections) {
|
||||
->action(function (string $projectId, string $name, string $teamId, string $region, string $description, string $logo, string $url, string $legalName, string $legalCountry, string $legalState, string $legalCity, string $legalAddress, string $legalTaxId, Response $response, Database $dbForConsole, Cache $cache, array $pools, Authorization $authorization, Connections $connections) {
|
||||
|
||||
$team = $dbForConsole->getDocument('teams', $teamId);
|
||||
|
||||
|
@ -181,19 +183,27 @@ Http::post('/v1/projects')
|
|||
throw new Exception(Exception::PROJECT_ALREADY_EXISTS);
|
||||
}
|
||||
|
||||
$connection = $pools->get($database)->pop();
|
||||
$connections->add($connection);
|
||||
$dbForProject = new Database($connection->getResource(), $cache);
|
||||
$dbForProject->setAuthorization($auth);
|
||||
$pool = $pools['pools-database-'.$project->getAttribute('database')]['pool'];
|
||||
$dsn = $pools['pools-database-'.$project->getAttribute('database')]['dsn'];
|
||||
$connection = $pool->get();
|
||||
$connections->add($connection, $pool);
|
||||
$adapter = match ($dsn->getScheme()) {
|
||||
'mariadb' => new MariaDB($connection),
|
||||
'mysql' => new MySQL($connection),
|
||||
default => null
|
||||
};
|
||||
|
||||
$adapter->setDatabase($dsn->getPath());
|
||||
|
||||
$dbForProject = new Database($adapter, $cache);
|
||||
$dbForProject->setAuthorization($authorization);
|
||||
$dbForProject->setNamespace("_{$project->getInternalId()}");
|
||||
$dbForProject->create();
|
||||
|
||||
$audit = new Audit($dbForProject, $auth);
|
||||
|
||||
$audit = new Audit($dbForProject, $authorization);
|
||||
$audit->setup();
|
||||
|
||||
$adapter = new TimeLimit('', 0, 1, $dbForProject, $auth);
|
||||
$adapter = new TimeLimit('', 0, 1, $dbForProject, $authorization);
|
||||
$adapter->setup();
|
||||
|
||||
/** @var array $collections */
|
||||
$collections = Config::getParam('collections', [])['projects'] ?? [];
|
||||
|
||||
|
|
|
@ -64,16 +64,16 @@ Http::post('/v1/teams')
|
|||
->inject('user')
|
||||
->inject('dbForProject')
|
||||
->inject('queueForEvents')
|
||||
->inject('auth')
|
||||
->action(function (string $teamId, string $name, array $roles, Response $response, Document $user, Database $dbForProject, Event $queueForEvents, Authorization $auth) {
|
||||
->inject('authorization')
|
||||
->action(function (string $teamId, string $name, array $roles, Response $response, Document $user, Database $dbForProject, Event $queueForEvents, Authorization $authorization) {
|
||||
|
||||
$isPrivilegedUser = Auth::isPrivilegedUser($auth->getRoles());
|
||||
$isAppUser = Auth::isAppUser($auth->getRoles());
|
||||
$isPrivilegedUser = Auth::isPrivilegedUser($authorization->getRoles());
|
||||
$isAppUser = Auth::isAppUser($authorization->getRoles());
|
||||
|
||||
$teamId = $teamId == 'unique()' ? ID::unique() : $teamId;
|
||||
|
||||
try {
|
||||
$team = $auth->skip(fn () => $dbForProject->createDocument('teams', new Document([
|
||||
$team = $authorization->skip(fn () => $dbForProject->createDocument('teams', new Document([
|
||||
'$id' => $teamId,
|
||||
'$permissions' => [
|
||||
Permission::read(Role::team($teamId)),
|
||||
|
@ -398,10 +398,10 @@ Http::post('/v1/teams/:teamId/memberships')
|
|||
->inject('queueForMails')
|
||||
->inject('queueForMessaging')
|
||||
->inject('queueForEvents')
|
||||
->inject('auth')
|
||||
->action(function (string $teamId, string $email, string $userId, string $phone, array $roles, string $url, string $name, Response $response, Document $project, Document $user, Database $dbForProject, Locale $locale, Mail $queueForMails, Messaging $queueForMessaging, Event $queueForEvents, Authorization $auth) {
|
||||
$isAPIKey = Auth::isAppUser($auth->getRoles());
|
||||
$isPrivilegedUser = Auth::isPrivilegedUser($auth->getRoles());
|
||||
->inject('authorization')
|
||||
->action(function (string $teamId, string $email, string $userId, string $phone, array $roles, string $url, string $name, Response $response, Document $project, Document $user, Database $dbForProject, Locale $locale, Mail $queueForMails, Messaging $queueForMessaging, Event $queueForEvents, Authorization $authorization) {
|
||||
$isAPIKey = Auth::isAppUser($authorization->getRoles());
|
||||
$isPrivilegedUser = Auth::isPrivilegedUser($authorization->getRoles());
|
||||
|
||||
if (empty($url)) {
|
||||
if (!$isAPIKey && !$isPrivilegedUser) {
|
||||
|
@ -412,8 +412,8 @@ Http::post('/v1/teams/:teamId/memberships')
|
|||
if (empty($userId) && empty($email) && empty($phone)) {
|
||||
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'At least one of userId, email, or phone is required');
|
||||
}
|
||||
$isPrivilegedUser = Auth::isPrivilegedUser($auth->getRoles());
|
||||
$isAppUser = Auth::isAppUser($auth->getRoles());
|
||||
$isPrivilegedUser = Auth::isPrivilegedUser($authorization->getRoles());
|
||||
$isAppUser = Auth::isAppUser($authorization->getRoles());
|
||||
|
||||
if (!$isPrivilegedUser && !$isAppUser && empty(System::getEnv('_APP_SMTP_HOST'))) {
|
||||
throw new Exception(Exception::GENERAL_SMTP_DISABLED);
|
||||
|
@ -473,7 +473,7 @@ Http::post('/v1/teams/:teamId/memberships')
|
|||
|
||||
try {
|
||||
$userId = ID::unique();
|
||||
$invitee = $auth->skip(fn () => $dbForProject->createDocument('users', new Document([
|
||||
$invitee = $authorization->skip(fn () => $dbForProject->createDocument('users', new Document([
|
||||
'$id' => $userId,
|
||||
'$permissions' => [
|
||||
Permission::read(Role::any()),
|
||||
|
@ -509,7 +509,7 @@ Http::post('/v1/teams/:teamId/memberships')
|
|||
}
|
||||
}
|
||||
|
||||
$isOwner = $auth->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(Exception::USER_UNAUTHORIZED, 'User is not allowed to send invitations for this team');
|
||||
|
@ -541,12 +541,12 @@ Http::post('/v1/teams/:teamId/memberships')
|
|||
|
||||
if ($isPrivilegedUser || $isAppUser) { // Allow admin to create membership
|
||||
try {
|
||||
$membership = $auth->skip(fn () => $dbForProject->createDocument('memberships', $membership));
|
||||
$membership = $authorization->skip(fn () => $dbForProject->createDocument('memberships', $membership));
|
||||
} catch (Duplicate $th) {
|
||||
throw new Exception(Exception::TEAM_INVITE_ALREADY_EXISTS);
|
||||
}
|
||||
|
||||
$auth->skip(fn () => $dbForProject->increaseDocumentAttribute('teams', $team->getId(), 'total', 1));
|
||||
$authorization->skip(fn () => $dbForProject->increaseDocumentAttribute('teams', $team->getId(), 'total', 1));
|
||||
|
||||
$dbForProject->purgeCachedDocument('users', $invitee->getId());
|
||||
} else {
|
||||
|
@ -866,8 +866,8 @@ Http::patch('/v1/teams/:teamId/memberships/:membershipId')
|
|||
->inject('user')
|
||||
->inject('dbForProject')
|
||||
->inject('queueForEvents')
|
||||
->inject('auth')
|
||||
->action(function (string $teamId, string $membershipId, array $roles, Request $request, Response $response, Document $user, Database $dbForProject, Event $queueForEvents, Authorization $auth) {
|
||||
->inject('authorization')
|
||||
->action(function (string $teamId, string $membershipId, array $roles, Request $request, Response $response, Document $user, Database $dbForProject, Event $queueForEvents, Authorization $authorization) {
|
||||
|
||||
$team = $dbForProject->getDocument('teams', $teamId);
|
||||
if ($team->isEmpty()) {
|
||||
|
@ -884,9 +884,9 @@ Http::patch('/v1/teams/:teamId/memberships/:membershipId')
|
|||
throw new Exception(Exception::USER_NOT_FOUND);
|
||||
}
|
||||
|
||||
$isPrivilegedUser = Auth::isPrivilegedUser($auth->getRoles());
|
||||
$isAppUser = Auth::isAppUser($auth->getRoles());
|
||||
$isOwner = $auth->isRole('team:' . $team->getId() . '/owner');
|
||||
$isPrivilegedUser = Auth::isPrivilegedUser($authorization->getRoles());
|
||||
$isAppUser = Auth::isAppUser($authorization->getRoles());
|
||||
$isOwner = $authorization->isRole('team:' . $team->getId() . '/owner');
|
||||
|
||||
if (!$isOwner && !$isPrivilegedUser && !$isAppUser) { // Not owner, not admin, not app (server)
|
||||
throw new Exception(Exception::USER_UNAUTHORIZED, 'User is not allowed to modify roles');
|
||||
|
@ -942,8 +942,8 @@ Http::patch('/v1/teams/:teamId/memberships/:membershipId/status')
|
|||
->inject('project')
|
||||
->inject('geodb')
|
||||
->inject('queueForEvents')
|
||||
->inject('auth')
|
||||
->action(function (string $teamId, string $membershipId, string $userId, string $secret, Request $request, Response $response, Document $user, Database $dbForProject, Document $project, Reader $geodb, Event $queueForEvents, Authorization $auth) {
|
||||
->inject('authorization')
|
||||
->action(function (string $teamId, string $membershipId, string $userId, string $secret, Request $request, Response $response, Document $user, Database $dbForProject, Document $project, Reader $geodb, Event $queueForEvents, Authorization $authorization) {
|
||||
$protocol = $request->getProtocol();
|
||||
|
||||
$membership = $dbForProject->getDocument('memberships', $membershipId);
|
||||
|
@ -952,7 +952,7 @@ Http::patch('/v1/teams/:teamId/memberships/:membershipId/status')
|
|||
throw new Exception(Exception::MEMBERSHIP_NOT_FOUND);
|
||||
}
|
||||
|
||||
$team = $auth->skip(fn () => $dbForProject->getDocument('teams', $teamId));
|
||||
$team = $authorization->skip(fn () => $dbForProject->getDocument('teams', $teamId));
|
||||
|
||||
if ($team->isEmpty()) {
|
||||
throw new Exception(Exception::TEAM_NOT_FOUND);
|
||||
|
@ -987,11 +987,11 @@ Http::patch('/v1/teams/:teamId/memberships/:membershipId/status')
|
|||
->setAttribute('confirm', true)
|
||||
;
|
||||
|
||||
$auth->skip(fn () => $dbForProject->updateDocument('users', $user->getId(), $user->setAttribute('emailVerification', true)));
|
||||
$authorization->skip(fn () => $dbForProject->updateDocument('users', $user->getId(), $user->setAttribute('emailVerification', true)));
|
||||
|
||||
// Log user in
|
||||
|
||||
$auth->addRole(Role::user($user->getId())->toString());
|
||||
$authorization->addRole(Role::user($user->getId())->toString());
|
||||
|
||||
$detector = new Detector($request->getUserAgent('UNKNOWN'));
|
||||
$record = $geodb->get($request->getIP());
|
||||
|
@ -1021,13 +1021,13 @@ Http::patch('/v1/teams/:teamId/memberships/:membershipId/status')
|
|||
|
||||
$dbForProject->purgeCachedDocument('users', $user->getId());
|
||||
|
||||
$auth->addRole(Role::user($userId)->toString());
|
||||
$authorization->addRole(Role::user($userId)->toString());
|
||||
|
||||
$membership = $dbForProject->updateDocument('memberships', $membership->getId(), $membership);
|
||||
|
||||
$dbForProject->purgeCachedDocument('users', $user->getId());
|
||||
|
||||
$auth->skip(fn () => $dbForProject->increaseDocumentAttribute('teams', $team->getId(), 'total', 1));
|
||||
$authorization->skip(fn () => $dbForProject->increaseDocumentAttribute('teams', $team->getId(), 'total', 1));
|
||||
|
||||
$queueForEvents
|
||||
->setParam('teamId', $team->getId())
|
||||
|
@ -1072,8 +1072,8 @@ Http::delete('/v1/teams/:teamId/memberships/:membershipId')
|
|||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->inject('queueForEvents')
|
||||
->inject('auth')
|
||||
->action(function (string $teamId, string $membershipId, Response $response, Database $dbForProject, Event $queueForEvents, Authorization $auth) {
|
||||
->inject('authorization')
|
||||
->action(function (string $teamId, string $membershipId, Response $response, Database $dbForProject, Event $queueForEvents, Authorization $authorization) {
|
||||
|
||||
$membership = $dbForProject->getDocument('memberships', $membershipId);
|
||||
|
||||
|
@ -1108,7 +1108,7 @@ Http::delete('/v1/teams/:teamId/memberships/:membershipId')
|
|||
$dbForProject->purgeCachedDocument('users', $user->getId());
|
||||
|
||||
if ($membership->getAttribute('confirm')) { // Count only confirmed members
|
||||
$auth->skip(fn () => $dbForProject->decreaseDocumentAttribute('teams', $team->getId(), 'total', 1, 0));
|
||||
$authorization->skip(fn () => $dbForProject->decreaseDocumentAttribute('teams', $team->getId(), 'total', 1, 0));
|
||||
}
|
||||
|
||||
$queueForEvents
|
||||
|
@ -1137,8 +1137,8 @@ Http::get('/v1/teams/:teamId/logs')
|
|||
->inject('dbForProject')
|
||||
->inject('locale')
|
||||
->inject('geodb')
|
||||
->inject('auth')
|
||||
->action(function (string $teamId, array $queries, Response $response, Database $dbForProject, Locale $locale, Reader $geodb, Authorization $auth) {
|
||||
->inject('authorization')
|
||||
->action(function (string $teamId, array $queries, Response $response, Database $dbForProject, Locale $locale, Reader $geodb, Authorization $authorization) {
|
||||
|
||||
$team = $dbForProject->getDocument('teams', $teamId);
|
||||
|
||||
|
@ -1156,7 +1156,7 @@ Http::get('/v1/teams/:teamId/logs')
|
|||
$limit = $grouped['limit'] ?? APP_LIMIT_COUNT;
|
||||
$offset = $grouped['offset'] ?? 0;
|
||||
|
||||
$audit = new Audit($dbForProject, $auth);
|
||||
$audit = new Audit($dbForProject, $authorization);
|
||||
$resource = 'team/' . $team->getId();
|
||||
$logs = $audit->getLogsByResource($resource, $limit, $offset);
|
||||
|
||||
|
|
|
@ -769,8 +769,8 @@ Http::get('/v1/users/:userId/logs')
|
|||
->inject('dbForProject')
|
||||
->inject('locale')
|
||||
->inject('geodb')
|
||||
->inject('auth')
|
||||
->action(function (string $userId, array $queries, Response $response, Database $dbForProject, Locale $locale, Reader $geodb, Authorization $auth) {
|
||||
->inject('authorization')
|
||||
->action(function (string $userId, array $queries, Response $response, Database $dbForProject, Locale $locale, Reader $geodb, Authorization $authorization) {
|
||||
|
||||
$user = $dbForProject->getDocument('users', $userId);
|
||||
|
||||
|
@ -788,7 +788,7 @@ Http::get('/v1/users/:userId/logs')
|
|||
$limit = $grouped['limit'] ?? APP_LIMIT_COUNT;
|
||||
$offset = $grouped['offset'] ?? 0;
|
||||
|
||||
$audit = new Audit($dbForProject, $auth);
|
||||
$audit = new Audit($dbForProject, $authorization);
|
||||
|
||||
$logs = $audit->getLogsByUser($user->getInternalId(), $limit, $offset);
|
||||
|
||||
|
@ -2105,8 +2105,8 @@ Http::get('/v1/users/usage')
|
|||
->param('range', '30d', new WhiteList(['24h', '30d', '90d'], true), 'Date range.', true)
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->inject('auth')
|
||||
->action(function (string $range, Response $response, Database $dbForProject, Authorization $auth) {
|
||||
->inject('authorization')
|
||||
->action(function (string $range, Response $response, Database $dbForProject, Authorization $authorization) {
|
||||
|
||||
$periods = Config::getParam('usage', []);
|
||||
$stats = $usage = [];
|
||||
|
@ -2116,7 +2116,7 @@ Http::get('/v1/users/usage')
|
|||
METRIC_SESSIONS,
|
||||
];
|
||||
|
||||
$auth->skip(function () use ($dbForProject, $days, $metrics, &$stats) {
|
||||
$authorization->skip(function () use ($dbForProject, $days, $metrics, &$stats) {
|
||||
foreach ($metrics as $count => $metric) {
|
||||
$result = $dbForProject->findOne('stats', [
|
||||
Query::equal('metric', [$metric]),
|
||||
|
|
|
@ -5,6 +5,7 @@ use Appwrite\Event\Event;
|
|||
use Appwrite\Event\Usage;
|
||||
use Appwrite\Extend\Exception as AppwriteException;
|
||||
use Appwrite\Network\Validator\Origin;
|
||||
use Appwrite\Utopia\Queue\Connections;
|
||||
use Appwrite\Utopia\Request;
|
||||
use Appwrite\Utopia\Request\Filters\V16 as RequestV16;
|
||||
use Appwrite\Utopia\Request\Filters\V17 as RequestV17;
|
||||
|
@ -635,7 +636,8 @@ Http::error()
|
|||
->inject('logger')
|
||||
->inject('log')
|
||||
->inject('authorization')
|
||||
->action(function (Throwable $error, Document $user, ?Route $route, Request $request, Response $response, Document $project, ?Logger $logger, Log $log, Authorization $authorization) {
|
||||
->inject('connections')
|
||||
->action(function (Throwable $error, Document $user, ?Route $route, Request $request, Response $response, Document $project, ?Logger $logger, Log $log, Authorization $authorization, Connections $connections) {
|
||||
$version = System::getEnv('_APP_VERSION', 'UNKNOWN');
|
||||
|
||||
if(is_null($route)) {
|
||||
|
@ -691,6 +693,7 @@ Http::error()
|
|||
$trace = $error->getTrace();
|
||||
|
||||
if (php_sapi_name() === 'cli') {
|
||||
Console::error('[Error] ------------------');
|
||||
Console::error('[Error] Timestamp: ' . date('c', time()));
|
||||
|
||||
if ($route) {
|
||||
|
@ -728,7 +731,7 @@ Http::error()
|
|||
|
||||
/** Wrap all exceptions inside Appwrite\Extend\Exception */
|
||||
if (!($error instanceof AppwriteException)) {
|
||||
$error = new AppwriteException(AppwriteException::GENERAL_UNKNOWN, $message, $code, $error);
|
||||
$error = new AppwriteException(AppwriteException::GENERAL_UNKNOWN, $message, (int)$code, $error);
|
||||
}
|
||||
|
||||
switch ($code) { // Don't show 500 errors!
|
||||
|
@ -748,7 +751,7 @@ Http::error()
|
|||
break;
|
||||
default:
|
||||
$code = 500; // All other errors get the generic 500 server error status code
|
||||
$message = 'Server Error';
|
||||
$message = (Http::getMode() === Http::MODE_TYPE_DEVELOPMENT) ? $message : 'Server Error';
|
||||
}
|
||||
|
||||
//$_SERVER = []; // Reset before reporting to error log to avoid keys being compromised
|
||||
|
@ -794,6 +797,8 @@ Http::error()
|
|||
$response->html($layout->render());
|
||||
}
|
||||
|
||||
$connections->reclaim();
|
||||
|
||||
$response->dynamic(
|
||||
new Document($output),
|
||||
Http::isDevelopment() ? Response::MODEL_ERROR_DEV : Response::MODEL_ERROR
|
||||
|
@ -884,4 +889,20 @@ foreach (Config::getParam('services', []) as $service) {
|
|||
//include_once $service['controller'];
|
||||
}
|
||||
|
||||
include_once 'shared/api.php';
|
||||
include_once 'shared/api/auth.php';
|
||||
include_once 'api/account.php';
|
||||
include_once 'api/avatars.php';
|
||||
//include_once 'api/database.php';
|
||||
//include_once 'api/functions.php';
|
||||
//include_once 'api/graphql.php';
|
||||
//include_once 'api/health.php';
|
||||
include_once 'api/locale.php';
|
||||
//include_once 'api/messaging.php';
|
||||
//include_once 'api/migrations.php';
|
||||
include_once 'api/projects.php';
|
||||
//include_once 'api/proxy.php';
|
||||
//include_once 'api/storage.php';
|
||||
include_once 'api/teams.php';
|
||||
include_once 'api/users.php';
|
||||
//include_once 'api/vcs.php';
|
||||
|
|
|
@ -29,6 +29,7 @@ use Utopia\Database\Validator\Authorization;
|
|||
use Utopia\Database\Validator\Authorization\Input;
|
||||
use Utopia\System\System;
|
||||
use Utopia\Http\Http;
|
||||
use Utopia\Http\Route;
|
||||
use Utopia\Http\Validator\WhiteList;
|
||||
|
||||
$parseLabel = function (string $label, array $responsePayload, array $requestParams, Document $user) {
|
||||
|
@ -152,7 +153,7 @@ $databaseListener = function (string $event, Document $document, Document $proje
|
|||
|
||||
Http::init()
|
||||
->groups(['api'])
|
||||
->inject('utopia')
|
||||
->inject('route')
|
||||
->inject('request')
|
||||
->inject('dbForConsole')
|
||||
->inject('project')
|
||||
|
@ -160,10 +161,8 @@ Http::init()
|
|||
->inject('session')
|
||||
->inject('servers')
|
||||
->inject('mode')
|
||||
->inject('auth')
|
||||
->action(function (Http $utopia, Request $request, Database $dbForConsole, Document $project, Document $user, ?Document $session, array $servers, string $mode, Authorization $auth) {
|
||||
$route = $utopia->getRoute();
|
||||
|
||||
->inject('authorization')
|
||||
->action(function (Route $route, Request $request, Database $dbForConsole, Document $project, Document $user, ?Document $session, array $servers, string $mode, Authorization $authorization) {
|
||||
if ($project->isEmpty()) {
|
||||
throw new Exception(Exception::PROJECT_NOT_FOUND);
|
||||
}
|
||||
|
@ -225,8 +224,8 @@ Http::init()
|
|||
throw new Exception(Exception::PROJECT_KEY_EXPIRED);
|
||||
}
|
||||
|
||||
$auth->addRole(Auth::USER_ROLE_APPS);
|
||||
$auth->setDefaultStatus(false); // Cancel security segmentation for API keys.
|
||||
$authorization->addRole(Auth::USER_ROLE_APPS);
|
||||
$authorization->setDefaultStatus(false); // Cancel security segmentation for API keys.
|
||||
|
||||
$accessedAt = $key->getAttribute('accessedAt', '');
|
||||
if (DateTime::formatTz(DateTime::addSeconds(new \DateTime(), -APP_KEY_ACCCESS)) > $accessedAt) {
|
||||
|
@ -252,10 +251,10 @@ Http::init()
|
|||
}
|
||||
}
|
||||
|
||||
$auth->addRole($role);
|
||||
$authorization->addRole($role);
|
||||
|
||||
foreach (Auth::getRoles($user, $auth) as $authRole) {
|
||||
$auth->addRole($authRole);
|
||||
foreach (Auth::getRoles($user, $authorization) as $authRole) {
|
||||
$authorization->addRole($authRole);
|
||||
}
|
||||
|
||||
$service = $route->getLabel('sdk.namespace', '');
|
||||
|
@ -263,7 +262,7 @@ Http::init()
|
|||
if (
|
||||
array_key_exists($service, $project->getAttribute('services', []))
|
||||
&& !$project->getAttribute('services', [])[$service]
|
||||
&& !(Auth::isPrivilegedUser($auth->getRoles()) || Auth::isAppUser($auth->getRoles()))
|
||||
&& !(Auth::isPrivilegedUser($authorization->getRoles()) || Auth::isAppUser($authorization->getRoles()))
|
||||
) {
|
||||
throw new Exception(Exception::GENERAL_SERVICE_DISABLED);
|
||||
}
|
||||
|
@ -302,7 +301,7 @@ Http::init()
|
|||
|
||||
Http::init()
|
||||
->groups(['api'])
|
||||
->inject('utopia')
|
||||
->inject('route')
|
||||
->inject('request')
|
||||
->inject('response')
|
||||
->inject('project')
|
||||
|
@ -316,15 +315,12 @@ Http::init()
|
|||
->inject('queueForUsage')
|
||||
->inject('dbForProject')
|
||||
->inject('mode')
|
||||
->inject('auth')
|
||||
->action(function (Http $utopia, Request $request, Response $response, Document $project, Document $user, Event $queueForEvents, Messaging $queueForMessaging, Audit $queueForAudits, Delete $queueForDeletes, EventDatabase $queueForDatabase, Build $queueForBuilds, Usage $queueForUsage, Database $dbForProject, string $mode, Authorization $auth) use ($databaseListener) {
|
||||
|
||||
$route = $utopia->getRoute();
|
||||
|
||||
->inject('authorization')
|
||||
->action(function (Route $route, Request $request, Response $response, Document $project, Document $user, Event $queueForEvents, Messaging $queueForMessaging, Audit $queueForAudits, Delete $queueForDeletes, EventDatabase $queueForDatabase, Build $queueForBuilds, Usage $queueForUsage, Database $dbForProject, string $mode, Authorization $authorization) use ($databaseListener) {
|
||||
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);
|
||||
}
|
||||
|
@ -340,7 +336,7 @@ Http::init()
|
|||
foreach ($abuseKeyLabel as $abuseKey) {
|
||||
$start = $request->getContentRangeStart();
|
||||
$end = $request->getContentRangeEnd();
|
||||
$timeLimit = new TimeLimit($abuseKey, $route->getLabel('abuse-limit', 0), $route->getLabel('abuse-time', 3600), $dbForProject, $auth);
|
||||
$timeLimit = new TimeLimit($abuseKey, $route->getLabel('abuse-limit', 0), $route->getLabel('abuse-time', 3600), $dbForProject, $authorization);
|
||||
$timeLimit
|
||||
->setParam('{projectId}', $project->getId())
|
||||
->setParam('{userId}', $user->getId())
|
||||
|
@ -354,7 +350,7 @@ Http::init()
|
|||
|
||||
$closestLimit = null;
|
||||
|
||||
$roles = $auth->getRoles();
|
||||
$roles = $authorization->getRoles();
|
||||
$isPrivilegedUser = Auth::isPrivilegedUser($roles);
|
||||
$isAppUser = Auth::isAppUser($roles);
|
||||
|
||||
|
@ -420,7 +416,7 @@ Http::init()
|
|||
$useCache = $route->getLabel('cache', false);
|
||||
if ($useCache) {
|
||||
$key = md5($request->getURI() . implode('*', $request->getParams()) . '*' . APP_CACHE_BUSTER);
|
||||
$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())
|
||||
);
|
||||
|
@ -434,17 +430,17 @@ Http::init()
|
|||
if ($type === 'bucket') {
|
||||
$bucketId = $parts[1] ?? null;
|
||||
|
||||
$bucket = $auth->skip(fn () => $dbForProject->getDocument('buckets', $bucketId));
|
||||
$bucket = $authorization->skip(fn () => $dbForProject->getDocument('buckets', $bucketId));
|
||||
|
||||
$isAPIKey = Auth::isAppUser($auth->getRoles());
|
||||
$isPrivilegedUser = Auth::isPrivilegedUser($auth->getRoles());
|
||||
$isAPIKey = Auth::isAppUser($authorization->getRoles());
|
||||
$isPrivilegedUser = Auth::isPrivilegedUser($authorization->getRoles());
|
||||
|
||||
if ($bucket->isEmpty() || (!$bucket->getAttribute('enabled') && !$isAPIKey && !$isPrivilegedUser)) {
|
||||
throw new Exception(Exception::STORAGE_BUCKET_NOT_FOUND);
|
||||
}
|
||||
|
||||
$fileSecurity = $bucket->getAttribute('fileSecurity', false);
|
||||
$valid = $auth->isValid(new Input(Database::PERMISSION_READ, $bucket->getRead()));
|
||||
$valid = $authorization->isValid(new Input(Database::PERMISSION_READ, $bucket->getRead()));
|
||||
if (!$fileSecurity && !$valid) {
|
||||
throw new Exception(Exception::USER_UNAUTHORIZED);
|
||||
}
|
||||
|
@ -455,7 +451,7 @@ Http::init()
|
|||
if ($fileSecurity && !$valid) {
|
||||
$file = $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId);
|
||||
} else {
|
||||
$file = $auth->skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId));
|
||||
$file = $authorization->skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId));
|
||||
}
|
||||
|
||||
if ($file->isEmpty()) {
|
||||
|
@ -529,7 +525,7 @@ Http::shutdown()
|
|||
|
||||
Http::shutdown()
|
||||
->groups(['api'])
|
||||
->inject('utopia')
|
||||
->inject('route')
|
||||
->inject('request')
|
||||
->inject('response')
|
||||
->inject('project')
|
||||
|
@ -545,9 +541,9 @@ Http::shutdown()
|
|||
->inject('queueForFunctions')
|
||||
->inject('mode')
|
||||
->inject('dbForConsole')
|
||||
->inject('auth')
|
||||
->inject('authorization')
|
||||
->action(function (
|
||||
Http $utopia,
|
||||
Route $route,
|
||||
Request $request,
|
||||
Response $response,
|
||||
Document $project,
|
||||
|
@ -563,10 +559,10 @@ Http::shutdown()
|
|||
Func $queueForFunctions,
|
||||
string $mode,
|
||||
Database $dbForConsole,
|
||||
Authorization $auth,
|
||||
Authorization $authorization,
|
||||
) use ($parseLabel) {
|
||||
if (!empty($user) && !$user->isEmpty() && empty($user->getInternalId())) {
|
||||
$user = $auth->skip(fn () => $dbForProject->getDocument('users', $user->getId()));
|
||||
$user = $authorization->skip(fn () => $dbForProject->getDocument('users', $user->getId()));
|
||||
}
|
||||
|
||||
$responsePayload = $response->getPayload();
|
||||
|
@ -626,7 +622,6 @@ Http::shutdown()
|
|||
}
|
||||
}
|
||||
|
||||
$route = $utopia->getRoute();
|
||||
$requestParams = $route->getParamsValues();
|
||||
|
||||
/**
|
||||
|
@ -696,11 +691,11 @@ Http::shutdown()
|
|||
|
||||
$key = md5($request->getURI() . '*' . implode('*', $request->getParams())) . '*' . APP_CACHE_BUSTER;
|
||||
$signature = md5($data['payload']);
|
||||
$cacheLog = $auth->skip(fn () => $dbForProject->getDocument('cache', $key));
|
||||
$cacheLog = $authorization->skip(fn () => $dbForProject->getDocument('cache', $key));
|
||||
$accessedAt = $cacheLog->getAttribute('accessedAt', '');
|
||||
$now = DateTime::now();
|
||||
if ($cacheLog->isEmpty()) {
|
||||
$auth->skip(fn () => $dbForProject->createDocument('cache', new Document([
|
||||
$authorization->skip(fn () => $dbForProject->createDocument('cache', new Document([
|
||||
'$id' => $key,
|
||||
'resource' => $resource,
|
||||
'resourceType' => $resourceType,
|
||||
|
@ -710,7 +705,7 @@ Http::shutdown()
|
|||
])));
|
||||
} elseif (DateTime::formatTz(DateTime::addSeconds(new \DateTime(), -APP_CACHE_UPDATE)) > $accessedAt) {
|
||||
$cacheLog->setAttribute('accessedAt', $now);
|
||||
$auth->skip(fn () => $dbForProject->updateDocument('cache', $cacheLog->getId(), $cacheLog));
|
||||
$authorization->skip(fn () => $dbForProject->updateDocument('cache', $cacheLog->getId(), $cacheLog));
|
||||
}
|
||||
|
||||
if ($signature !== $cacheLog->getAttribute('signature')) {
|
||||
|
|
|
@ -8,6 +8,7 @@ use Utopia\Database\DateTime;
|
|||
use Utopia\Database\Document;
|
||||
use Utopia\Database\Validator\Authorization;
|
||||
use Utopia\Http\Http;
|
||||
use Utopia\Http\Route;
|
||||
use Utopia\System\System;
|
||||
|
||||
Http::init()
|
||||
|
@ -31,12 +32,12 @@ Http::init()
|
|||
|
||||
Http::init()
|
||||
->groups(['auth'])
|
||||
->inject('utopia')
|
||||
->inject('route')
|
||||
->inject('request')
|
||||
->inject('project')
|
||||
->inject('geodb')
|
||||
->inject('auth')
|
||||
->action(function (Http $utopia, Request $request, Document $project, Reader $geodb, Authorization $auth) {
|
||||
->inject('authorization')
|
||||
->action(function (Route $route, Request $request, Document $project, Reader $geodb, Authorization $authorization) {
|
||||
$denylist = System::getEnv('_APP_CONSOLE_COUNTRIES_DENYLIST', '');
|
||||
if (!empty($denylist && $project->getId() === 'console')) {
|
||||
$countries = explode(',', $denylist);
|
||||
|
@ -47,10 +48,8 @@ Http::init()
|
|||
}
|
||||
}
|
||||
|
||||
$route = $utopia->match($request);
|
||||
|
||||
$isPrivilegedUser = Auth::isPrivilegedUser($auth->getRoles());
|
||||
$isAppUser = Auth::isAppUser($auth->getRoles());
|
||||
$isPrivilegedUser = Auth::isPrivilegedUser($authorization->getRoles());
|
||||
$isAppUser = Auth::isAppUser($authorization->getRoles());
|
||||
|
||||
if ($isAppUser || $isPrivilegedUser) { // Skip limits for app and console devs
|
||||
return;
|
||||
|
|
135
app/init2.php
135
app/init2.php
|
@ -78,39 +78,12 @@ use Utopia\System\System;
|
|||
use Utopia\VCS\Adapter\Git\GitHub as VcsGitHub;
|
||||
use Utopia\Cache\Adapter\None;
|
||||
|
||||
Http::setMode(System::getEnv('_APP_ENV', Http::MODE_TYPE_PRODUCTION));
|
||||
|
||||
function getAdapter($type, $scheme, $resource) {
|
||||
switch ($type) {
|
||||
case 'database':
|
||||
$adapter = match ($scheme) {
|
||||
'mariadb' => new MariaDB($resource),
|
||||
'mysql' => new MySQL($resource),
|
||||
default => null
|
||||
};
|
||||
|
||||
$adapter->setDatabase($scheme);
|
||||
break;
|
||||
case 'pubsub':
|
||||
$adapter = $resource();
|
||||
break;
|
||||
case 'queue':
|
||||
$adapter = match ($scheme) {
|
||||
//'redis' => new Queue\Connection\Redis($dsn->getHost(), $dsn->getPort()),
|
||||
default => null
|
||||
};
|
||||
break;
|
||||
case 'cache':
|
||||
$adapter = match ($scheme) {
|
||||
'redis' => new RedisCache($resource),
|
||||
default => null
|
||||
};
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new Exception(Exception::GENERAL_SERVER_ERROR, "Server error: Missing adapter implementation.");
|
||||
}
|
||||
|
||||
return $adapter;
|
||||
if (!Http::isProduction()) {
|
||||
// Allow specific domains to skip public domain validation in dev environment
|
||||
// Useful for existing tests involving webhooks
|
||||
PublicDomain::allow(['request-catcher']);
|
||||
}
|
||||
|
||||
$global = new Registry();
|
||||
|
@ -140,6 +113,10 @@ $global->set('geodb', function () {
|
|||
return new Reader(__DIR__ . '/assets/dbip/dbip-country-lite-2024-02.mmdb');
|
||||
});
|
||||
|
||||
$global->set('hooks', function () {
|
||||
return new Hooks();
|
||||
});
|
||||
|
||||
$global->set('pools', (function () {
|
||||
$fallbackForDB = 'db_main=' . URL::unparse([
|
||||
'scheme' => 'mariadb',
|
||||
|
@ -199,9 +176,12 @@ $global->set('pools', (function () {
|
|||
$multipe = $connection['multiple'] ?? false;
|
||||
$schemes = $connection['schemes'] ?? [];
|
||||
$dsns = explode(',', $connection['dsns'] ?? '');
|
||||
$config = [];
|
||||
|
||||
foreach ($dsns as &$dsn) {
|
||||
$dsn = explode('=', $dsn);
|
||||
$name = ($multipe) ? $dsn[0] : 'main';
|
||||
$config[] = $name;
|
||||
$dsn = $dsn[1] ?? '';
|
||||
|
||||
if (empty($dsn)) {
|
||||
|
@ -267,6 +247,8 @@ $global->set('pools', (function () {
|
|||
'dsn' => $dsn,
|
||||
];
|
||||
}
|
||||
|
||||
Config::setParam('pools-' . $key, $config);
|
||||
}
|
||||
|
||||
return function () use ($pools): array {
|
||||
|
@ -401,6 +383,34 @@ $user
|
|||
});
|
||||
$container->set($user);
|
||||
|
||||
$session = new Dependency();
|
||||
$session
|
||||
->setName('session')
|
||||
->inject('user')
|
||||
->inject('project')
|
||||
->setCallback(function (Document $user, Document $project) {
|
||||
if ($user->isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$sessions = $user->getAttribute('sessions', []);
|
||||
$authDuration = $project->getAttribute('auths', [])['duration'] ?? Auth::TOKEN_EXPIRATION_LOGIN_LONG;
|
||||
$sessionId = Auth::sessionVerify($user->getAttribute('sessions'), Auth::$secret, $authDuration);
|
||||
|
||||
if (!$sessionId) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($sessions as $session) {
|
||||
if ($sessionId === $session->getId()) {
|
||||
return $session;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
});
|
||||
$container->set($session);
|
||||
|
||||
$console = new Dependency();
|
||||
$console
|
||||
->setName('console')
|
||||
|
@ -498,6 +508,8 @@ $dbForProject
|
|||
'mysql' => new MySQL($connection),
|
||||
default => null
|
||||
};
|
||||
|
||||
$adapter->setDatabase($dsn->getPath());
|
||||
|
||||
$database = new Database($adapter, $cache);
|
||||
$database->setAuthorization($authorization);
|
||||
|
@ -531,7 +543,7 @@ $dbForConsole
|
|||
default => null
|
||||
};
|
||||
|
||||
$adapter->setDatabase('appwrite');
|
||||
$adapter->setDatabase($dsn->getPath());
|
||||
|
||||
$database = new Database($adapter, $cache);
|
||||
$database->setAuthorization($authorization);
|
||||
|
@ -788,6 +800,21 @@ $clients
|
|||
});
|
||||
$container->set($clients);
|
||||
|
||||
$servers = new Dependency();
|
||||
$servers
|
||||
->setName('servers')
|
||||
->setCallback(function () {
|
||||
$platforms = Config::getParam('platforms');
|
||||
$server = $platforms[APP_PLATFORM_SERVER];
|
||||
|
||||
$languages = array_map(function ($language) {
|
||||
return strtolower($language['name']);
|
||||
}, $server['sdks']);
|
||||
|
||||
return $languages;
|
||||
});
|
||||
$container->set($servers);
|
||||
|
||||
$geodb = new Dependency();
|
||||
$geodb
|
||||
->setName('geodb')
|
||||
|
@ -795,4 +822,44 @@ $geodb
|
|||
->setCallback(function (Registry $register) {
|
||||
return $register->get('geodb');
|
||||
});
|
||||
$container->set($geodb);
|
||||
$container->set($geodb);
|
||||
|
||||
$passwordsDictionary = new Dependency();
|
||||
$passwordsDictionary
|
||||
->setName('passwordsDictionary')
|
||||
->setCallback(function () {
|
||||
$content = file_get_contents(__DIR__ . '/assets/security/10k-common-passwords');
|
||||
$content = explode("\n", $content);
|
||||
$content = array_flip($content);
|
||||
return $content;
|
||||
});
|
||||
|
||||
$container->set($passwordsDictionary);
|
||||
|
||||
$hooks = new Dependency();
|
||||
$hooks
|
||||
->setName('hooks')
|
||||
->inject('registry')
|
||||
->setCallback(function (Registry $registry) {
|
||||
return $registry->get('hooks');
|
||||
});
|
||||
|
||||
$container->set($hooks);
|
||||
|
||||
$requestTimestamp = new Dependency();
|
||||
$requestTimestamp
|
||||
->setName('requestTimestamp')
|
||||
->inject('request')
|
||||
->setCallback(function ($request) {
|
||||
$timestampHeader = $request->getHeader('x-appwrite-timestamp');
|
||||
$requestTimestamp = null;
|
||||
if (!empty($timestampHeader)) {
|
||||
try {
|
||||
$requestTimestamp = new \DateTime($timestampHeader);
|
||||
} catch (\Throwable $e) {
|
||||
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'Invalid X-Appwrite-Timestamp header value');
|
||||
}
|
||||
}
|
||||
return $requestTimestamp;
|
||||
});
|
||||
$container->set($requestTimestamp);
|
||||
|
|
8
composer.lock
generated
8
composer.lock
generated
|
@ -1825,12 +1825,12 @@
|
|||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/http.git",
|
||||
"reference": "aef4e9a7bcb3ba21b993f2daad0364657c2fe1aa"
|
||||
"reference": "d600ae234780e083c600ab62a8348b7ea506cd1d"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/http/zipball/aef4e9a7bcb3ba21b993f2daad0364657c2fe1aa",
|
||||
"reference": "aef4e9a7bcb3ba21b993f2daad0364657c2fe1aa",
|
||||
"url": "https://api.github.com/repos/utopia-php/http/zipball/d600ae234780e083c600ab62a8348b7ea506cd1d",
|
||||
"reference": "d600ae234780e083c600ab62a8348b7ea506cd1d",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -1867,7 +1867,7 @@
|
|||
"issues": "https://github.com/utopia-php/http/issues",
|
||||
"source": "https://github.com/utopia-php/http/tree/feat-di-upgrade"
|
||||
},
|
||||
"time": "2024-04-13T17:20:36+00:00"
|
||||
"time": "2024-04-14T16:41:37+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/image",
|
||||
|
|
|
@ -2,41 +2,20 @@
|
|||
|
||||
namespace Appwrite\Utopia\Queue;
|
||||
|
||||
use Utopia\Pools\Connection;
|
||||
|
||||
class Connections
|
||||
{
|
||||
/**
|
||||
* @var Connection[]
|
||||
* @var array
|
||||
*/
|
||||
protected array $connections = [];
|
||||
|
||||
/**
|
||||
* @param Connection $pool
|
||||
* @param mixed $connection
|
||||
* @return self
|
||||
*/
|
||||
public function add(Connection $connection): self
|
||||
public function add(mixed $connection, $pool): self
|
||||
{
|
||||
$this->connections[$connection->getID()] = $connection;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $id
|
||||
* @return Connection
|
||||
*/
|
||||
public function get(string $id): Connection
|
||||
{
|
||||
return $this->connections[$id] ?? throw new \Exception("Connection '{$id}' not found");
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $id
|
||||
* @return self
|
||||
*/
|
||||
public function remove(string $id): self
|
||||
{
|
||||
unset($this->connections[$id]);
|
||||
$this->connections[] = ['connection' => $connection, 'pool' => $pool];
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
@ -45,8 +24,11 @@ class Connections
|
|||
*/
|
||||
public function reclaim(): self
|
||||
{
|
||||
foreach ($this->connections as $connection) {
|
||||
$connection->reclaim();
|
||||
foreach ($this->connections as $id => $resource) {
|
||||
$pool = $resource['pool'];
|
||||
$connection = $resource['connection'];
|
||||
$pool->put($connection);
|
||||
unset($this->connections[$id]);
|
||||
}
|
||||
|
||||
return $this;
|
||||
|
|
Loading…
Reference in a new issue