1
0
Fork 0
mirror of synced 2024-06-26 18:20:43 +12:00

Merge remote-tracking branch 'origin/origin/datetime-attributes' into refactor-permissions-inc-console-fix

# Conflicts:
#	app/controllers/api/databases.php
#	app/controllers/api/storage.php
#	src/Appwrite/Extend/Exception.php
This commit is contained in:
Jake Barnby 2022-08-16 20:30:00 +12:00
commit bbf7f8d8c3
17 changed files with 489 additions and 444 deletions

View file

@ -107,7 +107,7 @@ return [
],
Exception::USER_ALREADY_EXISTS => [
'name' => Exception::USER_ALREADY_EXISTS,
'description' => 'A user with the same email ID already exists in your project.',
'description' => 'A user with the same email already exists in your project.',
'code' => 409,
],
Exception::USER_BLOCKED => [
@ -127,12 +127,12 @@ return [
],
Exception::USER_EMAIL_NOT_WHITELISTED => [
'name' => Exception::USER_EMAIL_NOT_WHITELISTED,
'description' => 'The user\'s email is not part of the whitelist. Please check the _APP_CONSOLE_WHITELIST_EMAILS environment variable of your Appwrite server.',
'description' => 'Console registration is restricted to specific emails. Contact your administrator for more information.',
'code' => 401,
],
Exception::USER_IP_NOT_WHITELISTED => [
'name' => Exception::USER_IP_NOT_WHITELISTED,
'description' => 'The user\'s IP address is not part of the whitelist. Please check the _APP_CONSOLE_WHITELIST_IPS environment variable of your Appwrite server.',
'description' => 'Console registration is restricted to specific IPs. Contact your administrator for more information.',
'code' => 401,
],
Exception::USER_INVALID_CREDENTIALS => [
@ -157,7 +157,7 @@ return [
],
Exception::USER_EMAIL_ALREADY_EXISTS => [
'name' => Exception::USER_EMAIL_ALREADY_EXISTS,
'description' => 'Another user with the same email already exists in the current project.',
'description' => 'A user with the same email already exists in the current project.',
'code' => 409,
],
Exception::USER_PASSWORD_MISMATCH => [
@ -190,6 +190,11 @@ return [
'description' => 'The current user does not have a phone number associated with their account.',
'code' => 400,
],
Exception::USER_MISSING_ID => [
'name' => Exception::USER_MISSING_ID,
'description' => 'Missing ID from OAuth2 provider.',
'code' => 400,
],
/** Teams */
Exception::TEAM_NOT_FOUND => [
@ -199,7 +204,7 @@ return [
],
Exception::TEAM_INVITE_ALREADY_EXISTS => [
'name' => Exception::TEAM_INVITE_ALREADY_EXISTS,
'description' => 'The current user has already received an invitation to join the team.',
'description' => 'User has already been invited or is already a member of this team',
'code' => 409,
],
Exception::TEAM_INVITE_NOT_FOUND => [
@ -223,13 +228,17 @@ return [
'code' => 401,
],
/** Membership */
Exception::MEMBERSHIP_NOT_FOUND => [
'name' => Exception::MEMBERSHIP_NOT_FOUND,
'description' => 'Membership with the requested ID could not be found.',
'code' => 404,
],
Exception::MEMBERSHIP_ALREADY_CONFIRMED => [
'name' => Exception::MEMBERSHIP_ALREADY_CONFIRMED,
'description' => 'Membership already confirmed',
'code' => 409,
],
/** Avatars */
Exception::AVATAR_SET_NOT_FOUND => [
@ -276,7 +285,7 @@ return [
],
Exception::STORAGE_FILE_TYPE_UNSUPPORTED => [
'name' => Exception::STORAGE_FILE_TYPE_UNSUPPORTED,
'description' => 'The file type is not supported.',
'description' => 'The given file extension is not supported.',
'code' => 400,
],
Exception::STORAGE_INVALID_FILE_SIZE => [
@ -330,7 +339,7 @@ return [
],
Exception::BUILD_NOT_READY => [
'name' => Exception::BUILD_NOT_READY,
'description' => 'Build with the requested ID is builing and not ready for execution.',
'description' => 'Build with the requested ID is building and not ready for execution.',
'code' => 400,
],
Exception::BUILD_IN_PROGRESS => [
@ -353,6 +362,19 @@ return [
'code' => 404,
],
/** Databases */
Exception::DATABASE_NOT_FOUND => [
'name' => Exception::DATABASE_NOT_FOUND,
'description' => 'Database not found',
'code' => 404
],
Exception::DATABASE_ALREADY_EXISTS => [
'name' => Exception::DATABASE_ALREADY_EXISTS,
'description' => 'Database already exists',
'code' => 409
],
/** Collections */
Exception::COLLECTION_NOT_FOUND => [
'name' => Exception::COLLECTION_NOT_FOUND,
@ -474,19 +496,24 @@ return [
],
Exception::PROJECT_INVALID_SUCCESS_URL => [
'name' => Exception::PROJECT_INVALID_SUCCESS_URL,
'description' => 'Invalid URL received for OAuth success redirect.',
'description' => 'Invalid redirect URL for OAuth success.',
'code' => 400,
],
Exception::PROJECT_INVALID_FAILURE_URL => [
'name' => Exception::PROJECT_INVALID_FAILURE_URL,
'description' => 'Invalid URL received for OAuth failure redirect.',
'description' => 'Invalid redirect URL for OAuth failure.',
'code' => 400,
],
Exception::PROJECT_MISSING_USER_ID => [
'name' => Exception::PROJECT_MISSING_USER_ID,
'description' => 'Failed to obtain user ID from the OAuth provider.',
Exception::PROJECT_RESERVED_PROJECT => [
'name' => Exception::PROJECT_RESERVED_PROJECT,
'description' => 'The project ID is reserved. Please choose another project ID.',
'code' => 400,
],
Exception::PROJECT_KEY_EXPIRED => [
'name' => Exception::PROJECT_KEY_EXPIRED,
'description' => 'The project key has expired. Please generate a new key using the Appwrite console.',
'code' => 401,
],
Exception::WEBHOOK_NOT_FOUND => [
'name' => Exception::WEBHOOK_NOT_FOUND,
'description' => 'Webhook with the requested ID could not be found.',
@ -516,5 +543,5 @@ return [
'name' => Exception::DOMAIN_VERIFICATION_FAILED,
'description' => 'Domain verification for the requested domain has failed.',
'code' => 401,
]
],
];

View file

@ -78,11 +78,11 @@ App::post('/v1/account')
$whitelistIPs = $project->getAttribute('authWhitelistIPs');
if (!empty($whitelistEmails) && !\in_array($email, $whitelistEmails)) {
throw new Exception('Console registration is restricted to specific emails. Contact your administrator for more information.', 401, Exception::USER_EMAIL_NOT_WHITELISTED);
throw new Exception(Exception::USER_EMAIL_NOT_WHITELISTED);
}
if (!empty($whitelistIPs) && !\in_array($request->getIP(), $whitelistIPs)) {
throw new Exception('Console registration is restricted to specific IPs. Contact your administrator for more information.', 401, Exception::USER_IP_NOT_WHITELISTED);
throw new Exception(Exception::USER_IP_NOT_WHITELISTED);
}
}
@ -92,7 +92,7 @@ App::post('/v1/account')
$total = $dbForProject->count('users', max: APP_LIMIT_USERS);
if ($total >= $limit) {
throw new Exception('Project registration is restricted. Contact your administrator for more information.', 501, Exception::USER_COUNT_EXCEEDED);
throw new Exception(Exception::USER_COUNT_EXCEEDED);
}
}
@ -120,7 +120,7 @@ App::post('/v1/account')
'search' => implode(' ', [$userId, $email, $name])
])));
} catch (Duplicate $th) {
throw new Exception('Account already exists', 409, Exception::USER_ALREADY_EXISTS);
throw new Exception(Exception::USER_ALREADY_EXISTS);
}
Authorization::unsetRole(Auth::USER_ROLE_GUESTS);
@ -175,11 +175,11 @@ App::post('/v1/account/sessions/email')
]);
if (!$profile || !Auth::passwordVerify($password, $profile->getAttribute('password'))) {
throw new Exception('Invalid credentials', 401, Exception::USER_INVALID_CREDENTIALS); // Wrong password or username
throw new Exception(Exception::USER_INVALID_CREDENTIALS); // Wrong password or username
}
if (false === $profile->getAttribute('status')) { // Account is blocked
throw new Exception('Invalid credentials. User is blocked', 401, Exception::USER_BLOCKED); // User is in status blocked
throw new Exception(Exception::USER_BLOCKED); // User is in status blocked
}
$detector = new Detector($request->getUserAgent('UNKNOWN'));
@ -286,13 +286,13 @@ App::get('/v1/account/sessions/oauth2/:provider')
}
if (empty($appId) || empty($appSecret)) {
throw new Exception('This provider is disabled. Please configure the provider app ID and app secret key from your ' . APP_NAME . ' console to continue.', 412, Exception::PROJECT_PROVIDER_DISABLED);
throw new Exception(Exception::PROJECT_PROVIDER_DISABLED, 'This provider is disabled. Please configure the provider app ID and app secret key from your ' . APP_NAME . ' console to continue.');
}
$className = 'Appwrite\\Auth\\OAuth2\\' . \ucfirst($provider);
if (!\class_exists($className)) {
throw new Exception('Provider is not supported', 501, Exception::PROJECT_PROVIDER_UNSUPPORTED);
throw new Exception(Exception::PROJECT_PROVIDER_UNSUPPORTED);
}
if (empty($success)) {
@ -398,7 +398,7 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect')
$className = 'Appwrite\\Auth\\OAuth2\\' . \ucfirst($provider);
if (!\class_exists($className)) {
throw new Exception('Provider is not supported', 501, Exception::PROJECT_PROVIDER_UNSUPPORTED);
throw new Exception(Exception::PROJECT_PROVIDER_UNSUPPORTED);
}
$oauth2 = new $className($appId, $appSecret, $callback);
@ -407,18 +407,18 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect')
try {
$state = \array_merge($defaultState, $oauth2->parseState($state));
} catch (\Exception$exception) {
throw new Exception('Failed to parse login state params as passed from OAuth2 provider', 500, Exception::GENERAL_SERVER_ERROR);
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Failed to parse login state params as passed from OAuth2 provider');
}
} else {
$state = $defaultState;
}
if (!$validateURL->isValid($state['success'])) {
throw new Exception('Invalid redirect URL for success login', 400, Exception::PROJECT_INVALID_SUCCESS_URL);
throw new Exception(Exception::PROJECT_INVALID_SUCCESS_URL);
}
if (!empty($state['failure']) && !$validateURL->isValid($state['failure'])) {
throw new Exception('Invalid redirect URL for failure login', 400, Exception::PROJECT_INVALID_FAILURE_URL);
throw new Exception(Exception::PROJECT_INVALID_FAILURE_URL);
}
$state['failure'] = null;
@ -432,7 +432,7 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect')
$response->redirect($state['failure'], 301, 0);
}
throw new Exception('Failed to obtain access token', 500, Exception::GENERAL_SERVER_ERROR);
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Failed to obtain access token');
}
$oauth2ID = $oauth2->getUserID($accessToken);
@ -442,7 +442,7 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect')
$response->redirect($state['failure'], 301, 0);
}
throw new Exception('Missing ID from OAuth2 provider', 400, Exception::PROJECT_MISSING_USER_ID);
throw new Exception(Exception::USER_MISSING_ID);
}
$sessions = $user->getAttribute('sessions', []);
@ -481,7 +481,7 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect')
$total = $dbForProject->count('users', max: APP_LIMIT_USERS);
if ($total >= $limit) {
throw new Exception('Project registration is restricted. Contact your administrator for more information.', 501, Exception::USER_COUNT_EXCEEDED);
throw new Exception(Exception::USER_COUNT_EXCEEDED);
}
}
@ -509,13 +509,13 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect')
'search' => implode(' ', [$userId, $email, $name])
])));
} catch (Duplicate $th) {
throw new Exception('Account already exists', 409, Exception::USER_ALREADY_EXISTS);
throw new Exception(Exception::USER_ALREADY_EXISTS);
}
}
}
if (false === $user->getAttribute('status')) { // Account is blocked
throw new Exception('Invalid credentials. User is blocked', 401, Exception::USER_BLOCKED); // User is in status blocked
throw new Exception(Exception::USER_BLOCKED); // User is in status blocked
}
// Create session token, verify user account and update OAuth2 ID and Access Token
@ -636,7 +636,7 @@ App::post('/v1/account/sessions/magic-url')
->action(function (string $userId, string $email, string $url, Request $request, Response $response, Document $project, Database $dbForProject, Locale $locale, Audit $audits, Event $events, Mail $mails) {
if (empty(App::getEnv('_APP_SMTP_HOST'))) {
throw new Exception('SMTP Disabled', 503, Exception::GENERAL_SMTP_DISABLED);
throw new Exception(Exception::GENERAL_SMTP_DISABLED, 'SMTP disabled');
}
$roles = Authorization::getRoles();
@ -652,7 +652,7 @@ App::post('/v1/account/sessions/magic-url')
$total = $dbForProject->count('users', max: APP_LIMIT_USERS);
if ($total >= $limit) {
throw new Exception('Project registration is restricted. Contact your administrator for more information.', 501, Exception::USER_COUNT_EXCEEDED);
throw new Exception(Exception::USER_COUNT_EXCEEDED);
}
}
@ -772,13 +772,13 @@ App::put('/v1/account/sessions/magic-url')
$user = Authorization::skip(fn() => $dbForProject->getDocument('users', $userId));
if ($user->isEmpty()) {
throw new Exception('User not found', 404, Exception::USER_NOT_FOUND);
throw new Exception(Exception::USER_NOT_FOUND);
}
$token = Auth::tokenVerify($user->getAttribute('tokens', []), Auth::TOKEN_TYPE_MAGIC_URL, $secret);
if (!$token) {
throw new Exception('Invalid login token', 401, Exception::USER_INVALID_TOKEN);
throw new Exception(Exception::USER_INVALID_TOKEN);
}
$detector = new Detector($request->getUserAgent('UNKNOWN'));
@ -828,7 +828,7 @@ App::put('/v1/account/sessions/magic-url')
$user = $dbForProject->updateDocument('users', $user->getId(), $user);
if (false === $user) {
throw new Exception('Failed saving user to DB', 500, Exception::GENERAL_SERVER_ERROR);
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Failed saving user to DB');
}
$audits->setResource('user/' . $user->getId());
@ -886,7 +886,7 @@ App::post('/v1/account/sessions/phone')
->inject('phone')
->action(function (string $userId, string $number, Request $request, Response $response, Document $project, Database $dbForProject, Audit $audits, Event $events, EventPhone $messaging, Phone $phone) {
if (empty(App::getEnv('_APP_PHONE_PROVIDER'))) {
throw new Exception('Phone provider not configured', 503, Exception::GENERAL_PHONE_DISABLED);
throw new Exception(Exception::GENERAL_PHONE_DISABLED, 'Phone provider not configured');
}
$roles = Authorization::getRoles();
@ -902,7 +902,7 @@ App::post('/v1/account/sessions/phone')
$total = $dbForProject->count('users', max: APP_LIMIT_USERS);
if ($total >= $limit) {
throw new Exception('Project registration is restricted. Contact your administrator for more information.', 501, Exception::USER_COUNT_EXCEEDED);
throw new Exception(Exception::USER_COUNT_EXCEEDED);
}
}
@ -1011,13 +1011,13 @@ App::put('/v1/account/sessions/phone')
$user = Authorization::skip(fn() => $dbForProject->getDocument('users', $userId));
if ($user->isEmpty()) {
throw new Exception('User not found', 404, Exception::USER_NOT_FOUND);
throw new Exception(Exception::USER_NOT_FOUND);
}
$token = Auth::phoneTokenVerify($user->getAttribute('tokens', []), $secret);
if (!$token) {
throw new Exception('Invalid login token', 401, Exception::USER_INVALID_TOKEN);
throw new Exception(Exception::USER_INVALID_TOKEN);
}
$detector = new Detector($request->getUserAgent('UNKNOWN'));
@ -1065,7 +1065,7 @@ App::put('/v1/account/sessions/phone')
$user = $dbForProject->updateDocument('users', $user->getId(), $user);
if (false === $user) {
throw new Exception('Failed saving user to DB', 500, Exception::GENERAL_SERVER_ERROR);
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Failed saving user to DB');
}
$audits->setResource('user/' . $user->getId());
@ -1127,11 +1127,11 @@ App::post('/v1/account/sessions/anonymous')
$protocol = $request->getProtocol();
if ('console' === $project->getId()) {
throw new Exception('Failed to create anonymous user.', 401, Exception::USER_ANONYMOUS_CONSOLE_PROHIBITED);
throw new Exception(Exception::USER_ANONYMOUS_CONSOLE_PROHIBITED, 'Failed to create anonymous user');
}
if (!$user->isEmpty()) {
throw new Exception('Cannot create an anonymous user when logged in.', 401, Exception::USER_SESSION_ALREADY_EXISTS);
throw new Exception(Exception::USER_SESSION_ALREADY_EXISTS, 'Cannot create an anonymous user when logged in');
}
$limit = $project->getAttribute('auths', [])['limit'] ?? 0;
@ -1140,7 +1140,7 @@ App::post('/v1/account/sessions/anonymous')
$total = $dbForProject->count('users', max: APP_LIMIT_USERS);
if ($total >= $limit) {
throw new Exception('Project registration is restricted. Contact your administrator for more information.', 501, Exception::USER_COUNT_EXCEEDED);
throw new Exception(Exception::USER_COUNT_EXCEEDED);
}
}
@ -1263,7 +1263,7 @@ App::post('/v1/account/jwt')
}
if ($current->isEmpty()) {
throw new Exception('No valid session found', 404, Exception::USER_SESSION_NOT_FOUND);
throw new Exception(Exception::USER_SESSION_NOT_FOUND);
}
$jwt = new JWT(App::getEnv('_APP_OPENSSL_KEY_V1'), 'HS256', 900, 10); // Instantiate with key, algo, maxAge and leeway.
@ -1458,7 +1458,7 @@ App::get('/v1/account/sessions/:sessionId')
}
}
throw new Exception('Session not found', 404, Exception::USER_SESSION_NOT_FOUND);
throw new Exception(Exception::USER_SESSION_NOT_FOUND);
});
App::patch('/v1/account/name')
@ -1520,8 +1520,8 @@ App::patch('/v1/account/password')
->action(function (string $password, string $oldPassword, Response $response, Document $user, Database $dbForProject, Audit $audits, Stats $usage, Event $events) {
// Check old password only if its an existing user.
if ($user->getAttribute('passwordUpdate') !== null && !Auth::passwordVerify($oldPassword, $user->getAttribute('password'))) { // Double check user password
throw new Exception('Invalid credentials', 401, Exception::USER_INVALID_CREDENTIALS);
if ($user->getAttribute('passwordUpdate') !== 0 && !Auth::passwordVerify($oldPassword, $user->getAttribute('password'))) { // Double check user password
throw new Exception(Exception::USER_INVALID_CREDENTIALS);
}
$user = $dbForProject->updateDocument(
@ -1571,7 +1571,7 @@ App::patch('/v1/account/email')
!$isAnonymousUser &&
!Auth::passwordVerify($password, $user->getAttribute('password'))
) { // Double check user password
throw new Exception('Invalid credentials', 401, Exception::USER_INVALID_CREDENTIALS);
throw new Exception(Exception::USER_INVALID_CREDENTIALS);
}
$email = \strtolower($email);
@ -1585,7 +1585,7 @@ App::patch('/v1/account/email')
try {
$user = $dbForProject->updateDocument('users', $user->getId(), $user);
} catch (Duplicate $th) {
throw new Exception('Email already exists', 409, Exception::USER_EMAIL_ALREADY_EXISTS);
throw new Exception(Exception::USER_EMAIL_ALREADY_EXISTS);
}
$audits
@ -1627,7 +1627,7 @@ App::patch('/v1/account/phone')
!$isAnonymousUser &&
!Auth::passwordVerify($password, $user->getAttribute('password'))
) { // Double check user password
throw new Exception('Invalid credentials', 401, Exception::USER_INVALID_CREDENTIALS);
throw new Exception(Exception::USER_INVALID_CREDENTIALS);
}
$user
@ -1638,7 +1638,7 @@ App::patch('/v1/account/phone')
try {
$user = $dbForProject->updateDocument('users', $user->getId(), $user);
} catch (Duplicate $th) {
throw new Exception('Phone number already exists', 409, Exception::USER_PHONE_ALREADY_EXISTS);
throw new Exception(Exception::USER_PHONE_ALREADY_EXISTS);
}
$audits
@ -1796,7 +1796,7 @@ App::delete('/v1/account/sessions/:sessionId')
}
}
throw new Exception('Session not found', 404, Exception::USER_SESSION_NOT_FOUND);
throw new Exception(Exception::USER_SESSION_NOT_FOUND);
});
App::patch('/v1/account/sessions/:sessionId')
@ -1850,7 +1850,7 @@ App::patch('/v1/account/sessions/:sessionId')
$className = 'Appwrite\\Auth\\OAuth2\\' . \ucfirst($provider);
if (!\class_exists($className)) {
throw new Exception('Provider is not supported', 501, Exception::PROJECT_PROVIDER_UNSUPPORTED);
throw new Exception(Exception::PROJECT_PROVIDER_UNSUPPORTED);
}
$oauth2 = new $className($appId, $appSecret, '', [], []);
@ -1883,7 +1883,7 @@ App::patch('/v1/account/sessions/:sessionId')
}
}
throw new Exception('Session not found', 404, Exception::USER_SESSION_NOT_FOUND);
throw new Exception(Exception::USER_SESSION_NOT_FOUND);
});
App::delete('/v1/account/sessions')
@ -1982,7 +1982,7 @@ App::post('/v1/account/recovery')
->action(function (string $email, string $url, Request $request, Response $response, Database $dbForProject, Document $project, Locale $locale, Mail $mails, Audit $audits, Event $events, Stats $usage) {
if (empty(App::getEnv('_APP_SMTP_HOST'))) {
throw new Exception('SMTP Disabled', 503, Exception::GENERAL_SMTP_DISABLED);
throw new Exception(Exception::GENERAL_SMTP_DISABLED, 'SMTP Disabled');
}
$roles = Authorization::getRoles();
@ -1996,11 +1996,11 @@ App::post('/v1/account/recovery')
]);
if (!$profile) {
throw new Exception('User not found', 404, Exception::USER_NOT_FOUND);
throw new Exception(Exception::USER_NOT_FOUND);
}
if (false === $profile->getAttribute('status')) { // Account is blocked
throw new Exception('Invalid credentials. User is blocked', 401, Exception::USER_BLOCKED);
throw new Exception(Exception::USER_BLOCKED);
}
$expire = DateTime::addSeconds(new \DateTime(), Auth::TOKEN_EXPIRATION_RECOVERY);
@ -2087,20 +2087,20 @@ App::put('/v1/account/recovery')
->action(function (string $userId, string $secret, string $password, string $passwordAgain, Response $response, Database $dbForProject, Audit $audits, Stats $usage, Event $events) {
if ($password !== $passwordAgain) {
throw new Exception('Passwords must match', 400, Exception::USER_PASSWORD_MISMATCH);
throw new Exception(Exception::USER_PASSWORD_MISMATCH);
}
$profile = $dbForProject->getDocument('users', $userId);
if ($profile->isEmpty()) {
throw new Exception('User not found', 404, Exception::USER_NOT_FOUND);
throw new Exception(Exception::USER_NOT_FOUND);
}
$tokens = $profile->getAttribute('tokens', []);
$recovery = Auth::tokenVerify($tokens, Auth::TOKEN_TYPE_RECOVERY, $secret);
if (!$recovery) {
throw new Exception('Invalid recovery token', 401, Exception::USER_INVALID_TOKEN);
throw new Exception(Exception::USER_INVALID_TOKEN);
}
Authorization::setRole('user:' . $profile->getId());
@ -2159,7 +2159,7 @@ App::post('/v1/account/verification')
->action(function (string $url, Request $request, Response $response, Document $project, Document $user, Database $dbForProject, Locale $locale, Audit $audits, Event $events, Mail $mails, Stats $usage) {
if (empty(App::getEnv('_APP_SMTP_HOST'))) {
throw new Exception('SMTP Disabled', 503, Exception::GENERAL_SMTP_DISABLED);
throw new Exception(Exception::GENERAL_SMTP_DISABLED, 'SMTP Disabled');
}
$roles = Authorization::getRoles();
@ -2249,14 +2249,14 @@ App::put('/v1/account/verification')
$profile = Authorization::skip(fn() => $dbForProject->getDocument('users', $userId));
if ($profile->isEmpty()) {
throw new Exception('User not found', 404, Exception::USER_NOT_FOUND);
throw new Exception(Exception::USER_NOT_FOUND);
}
$tokens = $profile->getAttribute('tokens', []);
$verification = Auth::tokenVerify($tokens, Auth::TOKEN_TYPE_VERIFICATION, $secret);
if (!$verification) {
throw new Exception('Invalid verification token', 401, Exception::USER_INVALID_TOKEN);
throw new Exception(Exception::USER_INVALID_TOKEN);
}
Authorization::setRole('user:' . $profile->getId());
@ -2310,11 +2310,11 @@ App::post('/v1/account/verification/phone')
->action(function (Request $request, Response $response, Phone $phone, Document $user, Database $dbForProject, Audit $audits, Event $events, Stats $usage, EventPhone $messaging) {
if (empty(App::getEnv('_APP_PHONE_PROVIDER'))) {
throw new Exception('Phone provider not configured', 503, Exception::GENERAL_PHONE_DISABLED);
throw new Exception(Exception::GENERAL_PHONE_DISABLED, 'Phone provider not configured');
}
if (empty($user->getAttribute('phone'))) {
throw new Exception('User has no phone number.', 400, Exception::USER_PHONE_NOT_FOUND);
throw new Exception(Exception::USER_PHONE_NOT_FOUND);
}
$roles = Authorization::getRoles();
@ -2398,13 +2398,13 @@ App::put('/v1/account/verification/phone')
$profile = Authorization::skip(fn() => $dbForProject->getDocument('users', $userId));
if ($profile->isEmpty()) {
throw new Exception('User not found', 404, Exception::USER_NOT_FOUND);
throw new Exception(Exception::USER_NOT_FOUND);
}
$verification = Auth::phoneTokenVerify($user->getAttribute('tokens', []), $secret);
if (!$verification) {
throw new Exception('Invalid verification token', 401, Exception::USER_INVALID_TOKEN);
throw new Exception(Exception::USER_INVALID_TOKEN);
}
Authorization::setRole('user:' . $profile->getId());

View file

@ -25,15 +25,15 @@ $avatarCallback = function (string $type, string $code, int $width, int $height,
$set = Config::getParam('avatar-' . $type, []);
if (empty($set)) {
throw new Exception('Avatar set not found', 404, Exception::AVATAR_SET_NOT_FOUND);
throw new Exception(Exception::AVATAR_SET_NOT_FOUND);
}
if (!\array_key_exists($code, $set)) {
throw new Exception('Avatar not found', 404, Exception::AVATAR_NOT_FOUND);
throw new Exception(Exception::AVATAR_NOT_FOUND);
}
if (!\extension_loaded('imagick')) {
throw new Exception('Imagick extension is missing', 500, Exception::GENERAL_SERVER_ERROR);
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Imagick extension is missing');
}
$output = 'png';
@ -43,7 +43,7 @@ $avatarCallback = function (string $type, string $code, int $width, int $height,
$type = 'png';
if (!\is_readable($path)) {
throw new Exception('File not readable in ' . $path, 500, Exception::GENERAL_SERVER_ERROR);
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'File not readable in ' . $path);
}
$cache = new Cache(new Filesystem(APP_STORAGE_CACHE . '/app-0')); // Limit file number or size
@ -166,19 +166,19 @@ App::get('/v1/avatars/image')
}
if (!\extension_loaded('imagick')) {
throw new Exception('Imagick extension is missing', 500, Exception::GENERAL_SERVER_ERROR);
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Imagick extension is missing');
}
$fetch = @\file_get_contents($url, false);
if (!$fetch) {
throw new Exception('Image not found', 404, Exception::AVATAR_IMAGE_NOT_FOUND);
throw new Exception(Exception::AVATAR_IMAGE_NOT_FOUND);
}
try {
$image = new Image($fetch);
} catch (\Exception $exception) {
throw new Exception('Unable to parse image', 500, Exception::GENERAL_SERVER_ERROR);
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Unable to parse image');
}
$image->crop((int) $width, (int) $height);
@ -232,7 +232,7 @@ App::get('/v1/avatars/favicon')
}
if (!\extension_loaded('imagick')) {
throw new Exception('Imagick extension is missing', 500, Exception::GENERAL_SERVER_ERROR);
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Imagick extension is missing');
}
$curl = \curl_init();
@ -254,7 +254,7 @@ App::get('/v1/avatars/favicon')
\curl_close($curl);
if (!$html) {
throw new Exception('Failed to fetch remote URL', 404, Exception::AVATAR_REMOTE_URL_FAILED);
throw new Exception(Exception::AVATAR_REMOTE_URL_FAILED);
}
$doc = new DOMDocument();
@ -312,7 +312,7 @@ App::get('/v1/avatars/favicon')
$data = @\file_get_contents($outputHref, false);
if (empty($data) || (\mb_substr($data, 0, 5) === '<html') || \mb_substr($data, 0, 5) === '<!doc') {
throw new Exception('Favicon not found', 404, Exception::AVATAR_ICON_NOT_FOUND);
throw new Exception(Exception::AVATAR_ICON_NOT_FOUND, 'Favicon not found');
}
$cache->save($key, $data);
@ -327,7 +327,7 @@ App::get('/v1/avatars/favicon')
$fetch = @\file_get_contents($outputHref, false);
if (!$fetch) {
throw new Exception('Icon not found', 404, Exception::AVATAR_ICON_NOT_FOUND);
throw new Exception(Exception::AVATAR_ICON_NOT_FOUND);
}
$image = new Image($fetch);

View file

@ -72,28 +72,28 @@ function createAttribute(string $databaseId, string $collectionId, Document $att
$db = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
if ($db->isEmpty()) {
throw new Exception('Database not found', 404, Exception::DATABASE_NOT_FOUND);
throw new Exception(Exception::DATABASE_NOT_FOUND);
}
$collection = $dbForProject->getDocument('database_' . $db->getInternalId(), $collectionId);
if ($collection->isEmpty()) {
throw new Exception('Collection not found', 404, Exception::COLLECTION_NOT_FOUND);
throw new Exception(Exception::COLLECTION_NOT_FOUND);
}
if (!empty($format)) {
if (!Structure::hasFormat($format, $type)) {
throw new Exception("Format {$format} not available for {$type} attributes.", 400, Exception::ATTRIBUTE_FORMAT_UNSUPPORTED);
throw new Exception(Exception::ATTRIBUTE_FORMAT_UNSUPPORTED, "Format {$format} not available for {$type} attributes.");
}
}
// Must throw here since dbForProject->createAttribute is performed by db worker
if ($required && $default) {
throw new Exception('Cannot set default value for required attribute', 400, Exception::ATTRIBUTE_DEFAULT_UNSUPPORTED);
throw new Exception(Exception::ATTRIBUTE_DEFAULT_UNSUPPORTED, 'Cannot set default value for required attribute');
}
if ($array && $default) {
throw new Exception('Cannot set default value for array attributes', 400, Exception::ATTRIBUTE_DEFAULT_UNSUPPORTED);
throw new Exception(Exception::ATTRIBUTE_DEFAULT_UNSUPPORTED, 'Cannot set default value for array attributes');
}
try {
@ -119,9 +119,9 @@ function createAttribute(string $databaseId, string $collectionId, Document $att
$dbForProject->checkAttribute($collection, $attribute);
$attribute = $dbForProject->createDocument('attributes', $attribute);
} catch (DuplicateException $exception) {
throw new Exception('Attribute already exists', 409, Exception::ATTRIBUTE_ALREADY_EXISTS);
throw new Exception(Exception::ATTRIBUTE_ALREADY_EXISTS);
} catch (LimitException $exception) {
throw new Exception('Attribute limit exceeded', 400, Exception::ATTRIBUTE_LIMIT_EXCEEDED);
throw new Exception(Exception::ATTRIBUTE_LIMIT_EXCEEDED, 'Attribute limit exceeded');
}
$dbForProject->deleteCachedDocument('database_' . $db->getInternalId(), $collectionId);
@ -189,7 +189,7 @@ App::post('/v1/databases')
$collections = Config::getParam('collections', [])['collections'] ?? [];
if (empty($collections)) {
throw new Exception('Collections collection is not configured.', 500, Exception::GENERAL_SERVER_ERROR);
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'The "collections" collection is not configured.');
}
$attributes = [];
@ -220,7 +220,7 @@ App::post('/v1/databases')
}
$dbForProject->createCollection('database_' . $database->getInternalId(), $attributes, $indexes);
} catch (DuplicateException $th) {
throw new Exception('Database already exists', 409, Exception::DATABASE_ALREADY_EXISTS);
throw new Exception(Exception::DATABASE_ALREADY_EXISTS);
}
$audits
@ -271,7 +271,7 @@ App::get('/v1/databases')
$cursorDocument = $dbForProject->getDocument('databases', $cursor);
if ($cursorDocument->isEmpty()) {
throw new Exception("Collection '{$cursor}' for the 'cursor' value not found.", 400, Exception::GENERAL_CURSOR_NOT_FOUND);
throw new Exception(Exception::GENERAL_CURSOR_NOT_FOUND, "Collection '{$cursor}' for the 'cursor' value not found.");
}
$queries[] = $cursorDirection === Database::CURSOR_AFTER ? Query::cursorAfter($cursorDocument) : Query::cursorBefore($cursorDocument);
@ -305,7 +305,7 @@ App::get('/v1/databases/:databaseId')
$database = $dbForProject->getDocument('databases', $databaseId);
if ($database->isEmpty()) {
throw new Exception('Database not found', 404, Exception::DATABASE_NOT_FOUND);
throw new Exception(Exception::DATABASE_NOT_FOUND);
}
$usage->setParam('databases.read', 1);
@ -336,7 +336,7 @@ App::get('/v1/databases/:databaseId/logs')
$database = $dbForProject->getDocument('databases', $databaseId);
if ($database->isEmpty()) {
throw new Exception('Database not found', 404, Exception::DATABASE_NOT_FOUND);
throw new Exception(Exception::DATABASE_NOT_FOUND);
}
$audit = new Audit($dbForProject);
@ -416,7 +416,7 @@ App::put('/v1/databases/:databaseId')
$database = $dbForProject->getDocument('databases', $databaseId);
if ($database->isEmpty()) {
throw new Exception('Database not found', 404, Exception::DATABASE_NOT_FOUND);
throw new Exception(Exception::DATABASE_NOT_FOUND);
}
try {
@ -424,9 +424,9 @@ App::put('/v1/databases/:databaseId')
->setAttribute('name', $name)
->setAttribute('search', implode(' ', [$databaseId, $name])));
} catch (AuthorizationException $exception) {
throw new Exception('Unauthorized permissions', 401, Exception::USER_UNAUTHORIZED);
throw new Exception(Exception::USER_UNAUTHORIZED);
} catch (StructureException $exception) {
throw new Exception('Bad structure. ' . $exception->getMessage(), 400, Exception::DOCUMENT_INVALID_STRUCTURE);
throw new Exception(Exception::DOCUMENT_INVALID_STRUCTURE, 'Bad structure. ' . $exception->getMessage());
}
$audits
@ -463,11 +463,11 @@ App::delete('/v1/databases/:databaseId')
$database = $dbForProject->getDocument('databases', $databaseId);
if ($database->isEmpty()) {
throw new Exception('Database not found', 404, Exception::DATABASE_NOT_FOUND);
throw new Exception(Exception::DATABASE_NOT_FOUND);
}
if (!$dbForProject->deleteDocument('databases', $databaseId)) {
throw new Exception('Failed to remove collection from DB', 500, Exception::GENERAL_SERVER_ERROR);
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Failed to remove collection from DB');
}
$dbForProject->deleteCachedCollection('databases' . $database->getInternalId());
@ -520,7 +520,7 @@ App::post('/v1/databases/:databaseId/collections')
$database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
if ($database->isEmpty()) {
throw new Exception('Database not found', 404, Exception::DATABASE_NOT_FOUND);
throw new Exception(Exception::DATABASE_NOT_FOUND);
}
$collectionId = $collectionId == 'unique()' ? ID::unique() : $collectionId;
@ -546,9 +546,9 @@ App::post('/v1/databases/:databaseId/collections')
$dbForProject->createCollection('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId());
} catch (DuplicateException $th) {
throw new Exception('Collection already exists', 409, Exception::COLLECTION_ALREADY_EXISTS);
throw new Exception(Exception::COLLECTION_ALREADY_EXISTS);
} catch (LimitException $th) {
throw new Exception('Collection limit exceeded', 400, Exception::COLLECTION_LIMIT_EXCEEDED);
throw new Exception(Exception::COLLECTION_LIMIT_EXCEEDED);
}
$audits
@ -596,7 +596,7 @@ App::get('/v1/databases/:databaseId/collections')
$database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
if ($database->isEmpty()) {
throw new Exception('Database not found', 404, Exception::DATABASE_NOT_FOUND);
throw new Exception(Exception::DATABASE_NOT_FOUND);
}
$filterQueries = [];
@ -613,7 +613,7 @@ App::get('/v1/databases/:databaseId/collections')
$cursorDocument = $dbForProject->getDocument('database_' . $database->getInternalId(), $cursor);
if ($cursorDocument->isEmpty()) {
throw new Exception("Collection '{$cursor}' for the 'cursor' value not found.", 400, Exception::GENERAL_CURSOR_NOT_FOUND);
throw new Exception(Exception::GENERAL_CURSOR_NOT_FOUND, "Collection '{$cursor}' for the 'cursor' value not found.");
}
$queries[] = $cursorDirection === Database::CURSOR_AFTER
@ -653,13 +653,13 @@ App::get('/v1/databases/:databaseId/collections/:collectionId')
$database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
if ($database->isEmpty()) {
throw new Exception('Database not found', 404, Exception::DATABASE_NOT_FOUND);
throw new Exception(Exception::DATABASE_NOT_FOUND);
}
$collection = $dbForProject->getDocument('database_' . $database->getInternalId(), $collectionId);
if ($collection->isEmpty()) {
throw new Exception('Collection not found', 404, Exception::COLLECTION_NOT_FOUND);
throw new Exception(Exception::COLLECTION_NOT_FOUND);
}
$usage
@ -694,13 +694,13 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/logs')
$database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
if ($database->isEmpty()) {
throw new Exception('Database not found', 404, Exception::DATABASE_NOT_FOUND);
throw new Exception(Exception::DATABASE_NOT_FOUND);
}
$collectionDocument = $dbForProject->getDocument('database_' . $database->getInternalId(), $collectionId);
$collection = $dbForProject->getCollection('database_' . $database->getInternalId() . '_collection_' . $collectionDocument->getInternalId());
if ($collection->isEmpty()) {
throw new Exception('Collection not found', 404, Exception::COLLECTION_NOT_FOUND);
throw new Exception(Exception::COLLECTION_NOT_FOUND);
}
$audit = new Audit($dbForProject);
@ -788,13 +788,13 @@ App::put('/v1/databases/:databaseId/collections/:collectionId')
$database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
if ($database->isEmpty()) {
throw new Exception('Database not found', 404, Exception::DATABASE_NOT_FOUND);
throw new Exception(Exception::DATABASE_NOT_FOUND);
}
$collection = $dbForProject->getDocument('database_' . $database->getInternalId(), $collectionId);
if ($collection->isEmpty()) {
throw new Exception('Collection not found', 404, Exception::COLLECTION_NOT_FOUND);
throw new Exception(Exception::COLLECTION_NOT_FOUND);
}
$permissions ??= $collection->getPermissions() ?? [];
@ -814,9 +814,9 @@ App::put('/v1/databases/:databaseId/collections/:collectionId')
->setAttribute('enabled', $enabled)
->setAttribute('search', implode(' ', [$collectionId, $name])));
} catch (AuthorizationException) {
throw new Exception('Unauthorized permissions', 401, Exception::USER_UNAUTHORIZED);
throw new Exception(Exception::USER_UNAUTHORIZED);
} catch (StructureException $exception) {
throw new Exception('Bad structure. ' . $exception->getMessage(), 400, Exception::DOCUMENT_INVALID_STRUCTURE);
throw new Exception(Exception::DOCUMENT_INVALID_STRUCTURE, 'Bad structure. ' . $exception->getMessage());
}
$audits
@ -861,17 +861,17 @@ App::delete('/v1/databases/:databaseId/collections/:collectionId')
$database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
if ($database->isEmpty()) {
throw new Exception('Database not found', 404, Exception::DATABASE_NOT_FOUND);
throw new Exception(Exception::DATABASE_NOT_FOUND);
}
$collection = $dbForProject->getDocument('database_' . $database->getInternalId(), $collectionId);
if ($collection->isEmpty()) {
throw new Exception('Collection not found', 404, Exception::COLLECTION_NOT_FOUND);
throw new Exception(Exception::COLLECTION_NOT_FOUND);
}
if (!$dbForProject->deleteDocument('database_' . $database->getInternalId(), $collectionId)) {
throw new Exception('Failed to remove collection from DB', 500, Exception::GENERAL_SERVER_ERROR);
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Failed to remove collection from DB');
}
$dbForProject->deleteCachedCollection('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId());
@ -931,7 +931,7 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/attributes/string
// Ensure attribute default is within required size
$validator = new Text($size);
if (!is_null($default) && !$validator->isValid($default)) {
throw new Exception($validator->getDescription(), 400, Exception::ATTRIBUTE_VALUE_INVALID);
throw new Exception(Exception::ATTRIBUTE_VALUE_INVALID, $validator->getDescription());
}
$attribute = createAttribute($databaseId, $collectionId, new Document([
@ -1021,13 +1021,13 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/attributes/enum')
foreach ($elements as $element) {
$length = \strlen($element);
if ($length === 0) {
throw new Exception('Each enum element must not be empty', 400, Exception::ATTRIBUTE_VALUE_INVALID);
throw new Exception(Exception::ATTRIBUTE_VALUE_INVALID, 'Each enum element must not be empty');
}
$size = ($length > $size) ? $length : $size;
}
if (!is_null($default) && !in_array($default, $elements)) {
throw new Exception('Default value not found in elements', 400, Exception::ATTRIBUTE_VALUE_INVALID);
throw new Exception(Exception::ATTRIBUTE_VALUE_INVALID, 'Default value not found in elements');
}
$attribute = createAttribute($databaseId, $collectionId, new Document([
@ -1161,13 +1161,13 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/attributes/intege
$max = (is_null($max)) ? PHP_INT_MAX : \intval($max);
if ($min > $max) {
throw new Exception('Minimum value must be lesser than maximum value', 400, Exception::ATTRIBUTE_VALUE_INVALID);
throw new Exception(Exception::ATTRIBUTE_VALUE_INVALID, 'Minimum value must be lesser than maximum value');
}
$validator = new Range($min, $max, Database::VAR_INTEGER);
if (!is_null($default) && !$validator->isValid($default)) {
throw new Exception($validator->getDescription(), 400, Exception::ATTRIBUTE_VALUE_INVALID);
throw new Exception(Exception::ATTRIBUTE_VALUE_INVALID, $validator->getDescription());
}
$size = $max > 2147483647 ? 8 : 4; // Automatically create BigInt depending on max value
@ -1231,7 +1231,7 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/attributes/float'
$max = (is_null($max)) ? PHP_FLOAT_MAX : \floatval($max);
if ($min > $max) {
throw new Exception('Minimum value must be lesser than maximum value', 400, Exception::ATTRIBUTE_VALUE_INVALID);
throw new Exception(Exception::ATTRIBUTE_VALUE_INVALID, 'Minimum value must be lesser than maximum value');
}
// Ensure default value is a float
@ -1242,7 +1242,7 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/attributes/float'
$validator = new Range($min, $max, Database::VAR_FLOAT);
if (!is_null($default) && !$validator->isValid($default)) {
throw new Exception($validator->getDescription(), 400, Exception::ATTRIBUTE_VALUE_INVALID);
throw new Exception(Exception::ATTRIBUTE_VALUE_INVALID, $validator->getDescription());
}
$attribute = createAttribute($databaseId, $collectionId, new Document([
@ -1375,12 +1375,12 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/attributes')
$database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
if ($database->isEmpty()) {
throw new Exception('Database not found', 404, Exception::DATABASE_NOT_FOUND);
throw new Exception(Exception::DATABASE_NOT_FOUND);
}
$collection = $dbForProject->getDocument('database_' . $database->getInternalId(), $collectionId);
if ($collection->isEmpty()) {
throw new Exception('Collection not found', 404, Exception::COLLECTION_NOT_FOUND);
throw new Exception(Exception::COLLECTION_NOT_FOUND);
}
$attributes = $collection->getAttribute('attributes');
@ -1428,19 +1428,19 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/attributes/:key')
$database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
if ($database->isEmpty()) {
throw new Exception('Database not found', 404, Exception::DATABASE_NOT_FOUND);
throw new Exception(Exception::DATABASE_NOT_FOUND);
}
$collection = $dbForProject->getDocument('database_' . $database->getInternalId(), $collectionId);
if ($collection->isEmpty()) {
throw new Exception('Collection not found', 404, Exception::COLLECTION_NOT_FOUND);
throw new Exception(Exception::COLLECTION_NOT_FOUND);
}
$attribute = $dbForProject->getDocument('attributes', $database->getInternalId() . '_' . $collection->getInternalId() . '_' . $key);
if ($attribute->isEmpty()) {
throw new Exception('Attribute not found', 404, Exception::ATTRIBUTE_NOT_FOUND);
throw new Exception(Exception::ATTRIBUTE_NOT_FOUND);
}
// Select response model based on type and format
@ -1495,18 +1495,18 @@ App::delete('/v1/databases/:databaseId/collections/:collectionId/attributes/:key
$db = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
if ($db->isEmpty()) {
throw new Exception('Database not found', 404, Exception::DATABASE_NOT_FOUND);
throw new Exception(Exception::DATABASE_NOT_FOUND);
}
$collection = $dbForProject->getDocument('database_' . $db->getInternalId(), $collectionId);
if ($collection->isEmpty()) {
throw new Exception('Collection not found', 404, Exception::COLLECTION_NOT_FOUND);
throw new Exception(Exception::COLLECTION_NOT_FOUND);
}
$attribute = $dbForProject->getDocument('attributes', $db->getInternalId() . '_' . $collection->getInternalId() . '_' . $key);
if ($attribute->isEmpty()) {
throw new Exception('Attribute not found', 404, Exception::ATTRIBUTE_NOT_FOUND);
throw new Exception(Exception::ATTRIBUTE_NOT_FOUND);
}
// Only update status if removing available attribute
@ -1594,12 +1594,12 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/indexes')
$db = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
if ($db->isEmpty()) {
throw new Exception('Database not found', 404, Exception::DATABASE_NOT_FOUND);
throw new Exception(Exception::DATABASE_NOT_FOUND);
}
$collection = $dbForProject->getDocument('database_' . $db->getInternalId(), $collectionId);
if ($collection->isEmpty()) {
throw new Exception('Collection not found', 404, Exception::COLLECTION_NOT_FOUND);
throw new Exception(Exception::COLLECTION_NOT_FOUND);
}
$count = $dbForProject->count('indexes', [
@ -1610,7 +1610,7 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/indexes')
$limit = 64 - MariaDB::getNumberOfDefaultIndexes();
if ($count >= $limit) {
throw new Exception('Index limit exceeded', 400, Exception::INDEX_LIMIT_EXCEEDED);
throw new Exception(Exception::INDEX_LIMIT_EXCEEDED, 'Index limit exceeded');
}
// Convert Document[] to array of attribute metadata
@ -1656,7 +1656,7 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/indexes')
$attributeIndex = \array_search($attribute, array_column($oldAttributes, 'key'));
if ($attributeIndex === false) {
throw new Exception('Unknown attribute: ' . $attribute, 400, Exception::ATTRIBUTE_UNKNOWN);
throw new Exception(Exception::ATTRIBUTE_UNKNOWN, 'Unknown attribute: ' . $attribute);
}
$attributeStatus = $oldAttributes[$attributeIndex]['status'];
@ -1665,7 +1665,7 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/indexes')
// ensure attribute is available
if ($attributeStatus !== 'available') {
throw new Exception('Attribute not available: ' . $oldAttributes[$attributeIndex]['key'], 400, Exception::ATTRIBUTE_NOT_AVAILABLE);
throw new Exception(Exception::ATTRIBUTE_NOT_AVAILABLE, 'Attribute not available: ' . $oldAttributes[$attributeIndex]['key']);
}
// set attribute size as index length only for strings
@ -1687,7 +1687,7 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/indexes')
'orders' => $orders,
]));
} catch (DuplicateException $th) {
throw new Exception('Index already exists', 409, Exception::INDEX_ALREADY_EXISTS);
throw new Exception(Exception::INDEX_ALREADY_EXISTS);
}
$dbForProject->deleteCachedDocument('database_' . $db->getInternalId(), $collectionId);
@ -1742,12 +1742,12 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/indexes')
$database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
if ($database->isEmpty()) {
throw new Exception('Database not found', 404, Exception::DATABASE_NOT_FOUND);
throw new Exception(Exception::DATABASE_NOT_FOUND);
}
$collection = $dbForProject->getDocument('database_' . $database->getInternalId(), $collectionId);
if ($collection->isEmpty()) {
throw new Exception('Collection not found', 404, Exception::COLLECTION_NOT_FOUND);
throw new Exception(Exception::COLLECTION_NOT_FOUND);
}
$indexes = $collection->getAttribute('indexes');
@ -1785,12 +1785,12 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/indexes/:key')
$database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
if ($database->isEmpty()) {
throw new Exception('Database not found', 404, Exception::DATABASE_NOT_FOUND);
throw new Exception(Exception::DATABASE_NOT_FOUND);
}
$collection = $dbForProject->getDocument('database_' . $database->getInternalId(), $collectionId);
if ($collection->isEmpty()) {
throw new Exception('Collection not found', 404, Exception::COLLECTION_NOT_FOUND);
throw new Exception(Exception::COLLECTION_NOT_FOUND);
}
$indexes = $collection->getAttribute('indexes');
@ -1799,7 +1799,7 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/indexes/:key')
$indexIndex = array_search($key, array_column($indexes, 'key'));
if ($indexIndex === false) {
throw new Exception('Index not found', 404, Exception::INDEX_NOT_FOUND);
throw new Exception(Exception::INDEX_NOT_FOUND);
}
$index = new Document([\array_merge($indexes[$indexIndex], [
@ -1839,18 +1839,18 @@ App::delete('/v1/databases/:databaseId/collections/:collectionId/indexes/:key')
$db = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
if ($db->isEmpty()) {
throw new Exception('Database not found', 404, Exception::DATABASE_NOT_FOUND);
throw new Exception(Exception::DATABASE_NOT_FOUND);
}
$collection = $dbForProject->getDocument('database_' . $db->getInternalId(), $collectionId);
if ($collection->isEmpty()) {
throw new Exception('Collection not found', 404, Exception::COLLECTION_NOT_FOUND);
throw new Exception(Exception::COLLECTION_NOT_FOUND);
}
$index = $dbForProject->getDocument('indexes', $db->getInternalId() . '_' . $collection->getInternalId() . '_' . $key);
if (empty($index->getId())) {
throw new Exception('Index not found', 404, Exception::INDEX_NOT_FOUND);
throw new Exception(Exception::INDEX_NOT_FOUND);
}
// Only update status if removing available index
@ -1918,30 +1918,30 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/documents')
$data = (\is_string($data)) ? \json_decode($data, true) : $data; // Cast to JSON array
if (empty($data)) {
throw new Exception('Missing payload', 400, Exception::DOCUMENT_MISSING_PAYLOAD);
throw new Exception(Exception::DOCUMENT_MISSING_PAYLOAD);
}
if (isset($data['$id'])) {
throw new Exception('$id is not allowed for creating new documents, try update instead', 400, Exception::DOCUMENT_INVALID_STRUCTURE);
throw new Exception(Exception::DOCUMENT_INVALID_STRUCTURE, '$id is not allowed for creating new documents, try update instead');
}
$database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
if ($database->isEmpty()) {
throw new Exception('Database not found', 404, Exception::DATABASE_NOT_FOUND);
throw new Exception(Exception::DATABASE_NOT_FOUND);
}
$collection = Authorization::skip(fn() => $dbForProject->getDocument('database_' . $database->getInternalId(), $collectionId));
if ($collection->isEmpty() || !$collection->getAttribute('enabled')) {
if (!($mode === APP_MODE_ADMIN && Auth::isPrivilegedUser(Authorization::getRoles()))) {
throw new Exception('Collection not found', 404, Exception::COLLECTION_NOT_FOUND);
throw new Exception(Exception::COLLECTION_NOT_FOUND);
}
}
$validator = new Authorization('create');
if (!$validator->isValid($collection->getCreate())) {
throw new Exception('Unauthorized permissions', 401, Exception::USER_UNAUTHORIZED);
throw new Exception(Exception::USER_UNAUTHORIZED);
}
/**
@ -1985,7 +1985,7 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/documents')
}
$role = \str_replace([$type, '(', ')', '"', ' '], '', $permission);
if (!Authorization::isRole($role)) {
throw new Exception('Permissions must be one of: (' . \implode(', ', Authorization::getRoles()) . ')', 400, Exception::USER_UNAUTHORIZED);
throw new Exception(Exception::USER_UNAUTHORIZED, 'Permissions must be one of: (' . \implode(', ', Authorization::getRoles()) . ')');
}
}
}
@ -1999,9 +1999,9 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/documents')
$document = $dbForProject->createDocument('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(), new Document($data));
$document->setAttribute('$collection', $collectionId);
} catch (StructureException $exception) {
throw new Exception($exception->getMessage(), 400, Exception::DOCUMENT_INVALID_STRUCTURE);
throw new Exception(Exception::DOCUMENT_INVALID_STRUCTURE, $exception->getMessage());
} catch (DuplicateException $exception) {
throw new Exception('Document already exists', 409, Exception::DOCUMENT_ALREADY_EXISTS);
throw new Exception(Exception::DOCUMENT_ALREADY_EXISTS);
}
$events
@ -2057,14 +2057,14 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/documents')
$database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
if ($database->isEmpty()) {
throw new Exception('Database not found', 404, Exception::DATABASE_NOT_FOUND);
throw new Exception(Exception::DATABASE_NOT_FOUND);
}
$collection = Authorization::skip(fn() => $dbForProject->getDocument('database_' . $database->getInternalId(), $collectionId));
if ($collection->isEmpty() || !$collection->getAttribute('enabled')) {
if (!($mode === APP_MODE_ADMIN && Auth::isPrivilegedUser(Authorization::getRoles()))) {
throw new Exception('Collection not found', 404, Exception::COLLECTION_NOT_FOUND);
throw new Exception(Exception::COLLECTION_NOT_FOUND);
}
}
@ -2072,11 +2072,17 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/documents')
$validator = new Authorization('read');
$valid = $validator->isValid($collection->getRead());
if (!$valid && !$documentSecurity) {
throw new Exception('Unauthorized permissions', 401, Exception::USER_UNAUTHORIZED);
throw new Exception(Exception::USER_UNAUTHORIZED);
}
$filterQueries = \array_map(function ($query) {
return Query::parse($query);
$query = Query::parse($query);
if (\count($query->getValues()) > 100) {
throw new Exception(Exception::GENERAL_QUERY_LIMIT_EXCEEDED, "You cannot use more than 100 query values on attribute '{$query->getAttribute()}'");
}
return $query;
}, $queries);
$otherQueries = [];
@ -2093,7 +2099,7 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/documents')
$cursorDocument = Authorization::skip(fn() => $dbForProject->getDocument('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(), $cursor));
}
if ($cursorDocument->isEmpty()) {
throw new Exception("Document '{$cursor}' for the 'cursor' value not found.", 400, Exception::GENERAL_CURSOR_NOT_FOUND);
throw new Exception(Exception::GENERAL_CURSOR_NOT_FOUND, "Document '{$cursor}' for the 'cursor' value not found.");
}
$otherQueries[] = $cursorDirection === Database::CURSOR_AFTER ? Query::cursorAfter($cursorDocument) : Query::cursorBefore($cursorDocument);
@ -2105,7 +2111,7 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/documents')
$attributes = $collection->getAttribute('attributes', []);
$validator = new QueriesValidator(new QueryValidator($attributes), $attributes, $collection->getAttribute('indexes', []), true);
if (!$validator->isValid($allQueries)) {
throw new Exception($validator->getDescription(), 400, Exception::GENERAL_QUERY_INVALID);
throw new Exception(Exception::GENERAL_QUERY_INVALID, $validator->getDescription());
}
}
@ -2158,14 +2164,14 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/documents/:documen
$database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
if ($database->isEmpty()) {
throw new Exception('Database not found', 404, Exception::DATABASE_NOT_FOUND);
throw new Exception(Exception::DATABASE_NOT_FOUND);
}
$collection = Authorization::skip(fn() => $dbForProject->getDocument('database_' . $database->getInternalId(), $collectionId));
if ($collection->isEmpty() || !$collection->getAttribute('enabled')) {
if (!($mode === APP_MODE_ADMIN && Auth::isPrivilegedUser(Authorization::getRoles()))) {
throw new Exception('Collection not found', 404, Exception::COLLECTION_NOT_FOUND);
throw new Exception(Exception::COLLECTION_NOT_FOUND);
}
}
@ -2173,7 +2179,7 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/documents/:documen
$validator = new Authorization('read');
$valid = $validator->isValid($collection->getRead());
if (!$valid && !$documentSecurity) {
throw new Exception('Unauthorized permissions', 401, Exception::USER_UNAUTHORIZED);
throw new Exception(Exception::USER_UNAUTHORIZED);
}
$document = $dbForProject->getDocument('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(), $documentId);
@ -2229,18 +2235,18 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/documents/:documen
$database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
if ($database->isEmpty()) {
throw new Exception('Database not found', 404, Exception::DATABASE_NOT_FOUND);
throw new Exception(Exception::DATABASE_NOT_FOUND);
}
$collection = $dbForProject->getDocument('database_' . $database->getInternalId(), $collectionId);
if ($collection->isEmpty()) {
throw new Exception('Collection not found', 404, Exception::COLLECTION_NOT_FOUND);
throw new Exception(Exception::COLLECTION_NOT_FOUND);
}
$document = $dbForProject->getDocument('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(), $documentId);
if ($document->isEmpty()) {
throw new Exception('No document found', 404, Exception::DOCUMENT_NOT_FOUND);
throw new Exception(Exception::DOCUMENT_NOT_FOUND);
}
$audit = new Audit($dbForProject);
@ -2332,14 +2338,14 @@ App::patch('/v1/databases/:databaseId/collections/:collectionId/documents/:docum
$database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
if ($database->isEmpty()) {
throw new Exception('Database not found', 404, Exception::DATABASE_NOT_FOUND);
throw new Exception(Exception::DATABASE_NOT_FOUND);
}
$collection = Authorization::skip(fn() => $dbForProject->getDocument('database_' . $database->getInternalId(), $collectionId));
if ($collection->isEmpty() || !$collection->getAttribute('enabled')) {
if (!($mode === APP_MODE_ADMIN && Auth::isPrivilegedUser(Authorization::getRoles()))) {
throw new Exception('Collection not found', 404, Exception::COLLECTION_NOT_FOUND);
throw new Exception(Exception::COLLECTION_NOT_FOUND);
}
}
@ -2347,20 +2353,20 @@ App::patch('/v1/databases/:databaseId/collections/:collectionId/documents/:docum
$validator = new Authorization('update');
$valid = $validator->isValid($collection->getUpdate());
if (!$valid && !$documentSecurity) {
throw new Exception('Unauthorized permissions', 401, Exception::USER_UNAUTHORIZED);
throw new Exception(Exception::USER_UNAUTHORIZED);
}
$document = $dbForProject->getDocument('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(), $documentId);
if ($document->isEmpty()) {
throw new Exception('Document not found', 404, Exception::DOCUMENT_NOT_FOUND);
throw new Exception(Exception::DOCUMENT_NOT_FOUND);
}
if ($documentSecurity) {
$valid |= $validator->isValid($document->getUpdate());
}
if (!$valid) {
throw new Exception('Unauthorized permissions', 401, Exception::USER_UNAUTHORIZED);
throw new Exception(Exception::USER_UNAUTHORIZED);
}
// Users can only manage their own roles, API keys and Admin users can manage any
@ -2374,7 +2380,7 @@ App::patch('/v1/databases/:databaseId/collections/:collectionId/documents/:docum
}
$role = \str_replace([$type, '(', ')', '"', ' '], '', $permission);
if (!Authorization::isRole($role)) {
throw new Exception('Permissions must be one of: (' . \implode(', ', Authorization::getRoles()) . ')', 400, Exception::USER_UNAUTHORIZED);
throw new Exception(Exception::USER_UNAUTHORIZED, 'Permissions must be one of: (' . \implode(', ', Authorization::getRoles()) . ')');
}
}
}
@ -2404,11 +2410,11 @@ App::patch('/v1/databases/:databaseId/collections/:collectionId/documents/:docum
*/
$document->setAttribute('$collection', $collectionId);
} catch (AuthorizationException) {
throw new Exception('Unauthorized permissions', 401, Exception::USER_UNAUTHORIZED);
throw new Exception(Exception::USER_UNAUTHORIZED);
} catch (DuplicateException) {
throw new Exception('Document already exists', 409, Exception::DOCUMENT_ALREADY_EXISTS);
throw new Exception(Exception::DOCUMENT_ALREADY_EXISTS);
} catch (StructureException $exception) {
throw new Exception($exception->getMessage(), 400, Exception::DOCUMENT_INVALID_STRUCTURE);
throw new Exception(Exception::DOCUMENT_INVALID_STRUCTURE, $exception->getMessage());
}
$events
@ -2460,14 +2466,14 @@ App::delete('/v1/databases/:databaseId/collections/:collectionId/documents/:docu
$database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
if ($database->isEmpty()) {
throw new Exception('Database not found', 404, Exception::DATABASE_NOT_FOUND);
throw new Exception(Exception::DATABASE_NOT_FOUND);
}
$collection = Authorization::skip(fn() => $dbForProject->getDocument('database_' . $database->getInternalId(), $collectionId));
if ($collection->isEmpty() || !$collection->getAttribute('enabled')) {
if (!($mode === APP_MODE_ADMIN && Auth::isPrivilegedUser(Authorization::getRoles()))) {
throw new Exception('Collection not found', 404, Exception::COLLECTION_NOT_FOUND);
throw new Exception(Exception::COLLECTION_NOT_FOUND);
}
}
@ -2475,13 +2481,13 @@ App::delete('/v1/databases/:databaseId/collections/:collectionId/documents/:docu
$validator = new Authorization('delete');
$valid = $validator->isValid($collection->getDelete());
if (!$valid && !$documentSecurity) {
throw new Exception('Unauthorized permissions', 401, Exception::USER_UNAUTHORIZED);
throw new Exception(Exception::USER_UNAUTHORIZED);
}
$document = $dbForProject->getDocument('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(), $documentId);
if ($document->isEmpty()) {
throw new Exception('No document found', 404, Exception::DOCUMENT_NOT_FOUND);
throw new Exception(Exception::DOCUMENT_NOT_FOUND);
}
if ($documentSecurity) {
@ -2779,7 +2785,7 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/usage')
$collection = $dbForProject->getCollection('database_' . $database->getInternalId() . '_collection_' . $collectionDocument->getInternalId());
if ($collection->isEmpty()) {
throw new Exception('Collection not found', 404, Exception::COLLECTION_NOT_FOUND);
throw new Exception(Exception::COLLECTION_NOT_FOUND);
}
$usage = [];

View file

@ -125,7 +125,7 @@ App::get('/v1/functions')
$cursorDocument = $dbForProject->getDocument('functions', $cursor);
if ($cursorDocument->isEmpty()) {
throw new Exception("Function '{$cursor}' for the 'cursor' value not found.", 400, Exception::GENERAL_CURSOR_NOT_FOUND);
throw new Exception(Exception::GENERAL_CURSOR_NOT_FOUND, "Function '{$cursor}' for the 'cursor' value not found.");
}
$queries[] = $cursorDirection === Database::CURSOR_AFTER ? Query::cursorAfter($cursorDocument) : Query::cursorBefore($cursorDocument);
@ -182,7 +182,7 @@ App::get('/v1/functions/:functionId')
$function = $dbForProject->getDocument('functions', $functionId);
if ($function->isEmpty()) {
throw new Exception('Function not found', 404, Exception::FUNCTION_NOT_FOUND);
throw new Exception(Exception::FUNCTION_NOT_FOUND);
}
$response->dynamic($function, Response::MODEL_FUNCTION);
@ -207,7 +207,7 @@ App::get('/v1/functions/:functionId/usage')
$function = $dbForProject->getDocument('functions', $functionId);
if ($function->isEmpty()) {
throw new Exception('Function not found', 404, Exception::FUNCTION_NOT_FOUND);
throw new Exception(Exception::FUNCTION_NOT_FOUND);
}
$usage = [];
@ -317,7 +317,7 @@ App::put('/v1/functions/:functionId')
$function = $dbForProject->getDocument('functions', $functionId);
if ($function->isEmpty()) {
throw new Exception('Function not found', 404, Exception::FUNCTION_NOT_FOUND);
throw new Exception(Exception::FUNCTION_NOT_FOUND);
}
$original = $function->getAttribute('schedule', '');
@ -376,19 +376,19 @@ App::patch('/v1/functions/:functionId/deployments/:deploymentId')
$build = $dbForProject->getDocument('builds', $deployment->getAttribute('buildId', ''));
if ($function->isEmpty()) {
throw new Exception('Function not found', 404, Exception::FUNCTION_NOT_FOUND);
throw new Exception(Exception::FUNCTION_NOT_FOUND);
}
if ($deployment->isEmpty()) {
throw new Exception('Deployment not found', 404, Exception::DEPLOYMENT_NOT_FOUND);
throw new Exception(Exception::DEPLOYMENT_NOT_FOUND);
}
if ($build->isEmpty()) {
throw new Exception('Build not found', 404, Exception::BUILD_NOT_FOUND);
throw new Exception(Exception::BUILD_NOT_FOUND);
}
if ($build->getAttribute('status') !== 'ready') {
throw new Exception('Build not ready', 400, Exception::BUILD_NOT_READY);
throw new Exception(Exception::BUILD_NOT_READY);
}
$schedule = $function->getAttribute('schedule', '');
@ -437,11 +437,11 @@ App::delete('/v1/functions/:functionId')
$function = $dbForProject->getDocument('functions', $functionId);
if ($function->isEmpty()) {
throw new Exception('Function not found', 404, Exception::FUNCTION_NOT_FOUND);
throw new Exception(Exception::FUNCTION_NOT_FOUND);
}
if (!$dbForProject->deleteDocument('functions', $function->getId())) {
throw new Exception('Failed to remove function from DB', 500, Exception::GENERAL_SERVER_ERROR);
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Failed to remove function from DB');
}
$deletes
@ -484,7 +484,7 @@ App::post('/v1/functions/:functionId/deployments')
$function = $dbForProject->getDocument('functions', $functionId);
if ($function->isEmpty()) {
throw new Exception('Function not found', 404, Exception::FUNCTION_NOT_FOUND);
throw new Exception(Exception::FUNCTION_NOT_FOUND);
}
$file = $request->getFiles('code');
@ -493,7 +493,7 @@ App::post('/v1/functions/:functionId/deployments')
$upload = new Upload();
if (empty($file)) {
throw new Exception('No file sent', 400, Exception::STORAGE_FILE_EMPTY);
throw new Exception(Exception::STORAGE_FILE_EMPTY, 'No file sent');
}
// Make sure we handle a single file and multiple files the same way
@ -502,7 +502,7 @@ App::post('/v1/functions/:functionId/deployments')
$fileSize = (\is_array($file['size']) && isset($file['size'][0])) ? $file['size'][0] : $file['size'];
if (!$fileExt->isValid($file['name'])) { // Check if file type is allowed
throw new Exception('File type not allowed', 400, Exception::STORAGE_FILE_TYPE_UNSUPPORTED);
throw new Exception(Exception::STORAGE_FILE_TYPE_UNSUPPORTED);
}
$contentRange = $request->getHeader('content-range');
@ -516,7 +516,7 @@ App::post('/v1/functions/:functionId/deployments')
$fileSize = $request->getContentRangeSize();
$deploymentId = $request->getHeader('x-appwrite-id', $deploymentId);
if (is_null($start) || is_null($end) || is_null($fileSize)) {
throw new Exception('Invalid content-range header', 400, Exception::STORAGE_INVALID_CONTENT_RANGE);
throw new Exception(Exception::STORAGE_INVALID_CONTENT_RANGE);
}
if ($end === $fileSize) {
@ -530,11 +530,11 @@ App::post('/v1/functions/:functionId/deployments')
}
if (!$fileSizeValidator->isValid($fileSize)) { // Check if file size is exceeding allowed limit
throw new Exception('File size not allowed', 400, Exception::STORAGE_INVALID_FILE_SIZE);
throw new Exception(Exception::STORAGE_INVALID_FILE_SIZE);
}
if (!$upload->isValid($fileTmpName)) {
throw new Exception('Invalid file', 403, Exception::STORAGE_INVALID_FILE);
throw new Exception(Exception::STORAGE_INVALID_FILE);
}
// Save to storage
@ -555,7 +555,7 @@ App::post('/v1/functions/:functionId/deployments')
$chunksUploaded = $deviceFunctions->upload($fileTmpName, $path, $chunk, $chunks, $metadata);
if (empty($chunksUploaded)) {
throw new Exception('Failed moving file', 500, Exception::GENERAL_SERVER_ERROR);
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Failed moving file');
}
$activate = (bool) filter_var($activate, FILTER_VALIDATE_BOOLEAN);
@ -668,7 +668,7 @@ App::get('/v1/functions/:functionId/deployments')
$function = $dbForProject->getDocument('functions', $functionId);
if ($function->isEmpty()) {
throw new Exception('Function not found', 404, Exception::FUNCTION_NOT_FOUND);
throw new Exception(Exception::FUNCTION_NOT_FOUND);
}
$filterQueries = [];
@ -688,7 +688,7 @@ App::get('/v1/functions/:functionId/deployments')
$cursorDocument = $dbForProject->getDocument('deployments', $cursor);
if ($cursorDocument->isEmpty()) {
throw new Exception("Tag '{$cursor}' for the 'cursor' value not found.", 400, Exception::GENERAL_CURSOR_NOT_FOUND);
throw new Exception(Exception::GENERAL_CURSOR_NOT_FOUND, "Tag '{$cursor}' for the 'cursor' value not found.");
}
$queries[] = $cursorDirection === Database::CURSOR_AFTER ? Query::cursorAfter($cursorDocument) : Query::cursorBefore($cursorDocument);
@ -730,17 +730,17 @@ App::get('/v1/functions/:functionId/deployments/:deploymentId')
$function = $dbForProject->getDocument('functions', $functionId);
if ($function->isEmpty()) {
throw new Exception('Function not found', 404, Exception::FUNCTION_NOT_FOUND);
throw new Exception(Exception::FUNCTION_NOT_FOUND);
}
$deployment = $dbForProject->getDocument('deployments', $deploymentId);
if ($deployment->getAttribute('resourceId') !== $function->getId()) {
throw new Exception('Deployment not found', 404, Exception::DEPLOYMENT_NOT_FOUND);
throw new Exception(Exception::DEPLOYMENT_NOT_FOUND);
}
if ($deployment->isEmpty()) {
throw new Exception('Deployment not found', 404, Exception::DEPLOYMENT_NOT_FOUND);
throw new Exception(Exception::DEPLOYMENT_NOT_FOUND);
}
$response->dynamic($deployment, Response::MODEL_DEPLOYMENT);
@ -769,21 +769,21 @@ App::delete('/v1/functions/:functionId/deployments/:deploymentId')
$function = $dbForProject->getDocument('functions', $functionId);
if ($function->isEmpty()) {
throw new Exception('Function not found', 404, Exception::FUNCTION_NOT_FOUND);
throw new Exception(Exception::FUNCTION_NOT_FOUND);
}
$deployment = $dbForProject->getDocument('deployments', $deploymentId);
if ($deployment->isEmpty()) {
throw new Exception('Deployment not found', 404, Exception::DEPLOYMENT_NOT_FOUND);
throw new Exception(Exception::DEPLOYMENT_NOT_FOUND);
}
if ($deployment->getAttribute('resourceId') !== $function->getId()) {
throw new Exception('Deployment not found', 404, Exception::DEPLOYMENT_NOT_FOUND);
throw new Exception(Exception::DEPLOYMENT_NOT_FOUND);
}
if ($deviceFunctions->delete($deployment->getAttribute('path', ''))) {
if (!$dbForProject->deleteDocument('deployments', $deployment->getId())) {
throw new Exception('Failed to remove deployment from DB', 500, Exception::GENERAL_SERVER_ERROR);
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Failed to remove deployment from DB');
}
}
@ -835,7 +835,7 @@ App::post('/v1/functions/:functionId/executions')
$function = Authorization::skip(fn () => $dbForProject->getDocument('functions', $functionId));
if ($function->isEmpty()) {
throw new Exception('Function not found', 404, Exception::FUNCTION_NOT_FOUND);
throw new Exception(Exception::FUNCTION_NOT_FOUND);
}
$runtimes = Config::getParam('runtimes', []);
@ -843,33 +843,33 @@ App::post('/v1/functions/:functionId/executions')
$runtime = (isset($runtimes[$function->getAttribute('runtime', '')])) ? $runtimes[$function->getAttribute('runtime', '')] : null;
if (\is_null($runtime)) {
throw new Exception('Runtime "' . $function->getAttribute('runtime', '') . '" is not supported', 400, Exception::FUNCTION_RUNTIME_UNSUPPORTED);
throw new Exception(Exception::FUNCTION_RUNTIME_UNSUPPORTED, 'Runtime "' . $function->getAttribute('runtime', '') . '" is not supported');
}
$deployment = Authorization::skip(fn () => $dbForProject->getDocument('deployments', $function->getAttribute('deployment', '')));
if ($deployment->getAttribute('resourceId') !== $function->getId()) {
throw new Exception('Deployment not found. Create a deployment before trying to execute a function', 404, Exception::DEPLOYMENT_NOT_FOUND);
throw new Exception(Exception::DEPLOYMENT_NOT_FOUND, 'Deployment not found. Create a deployment before trying to execute a function');
}
if ($deployment->isEmpty()) {
throw new Exception('Deployment not found. Create a deployment before trying to execute a function', 404, Exception::DEPLOYMENT_NOT_FOUND);
throw new Exception(Exception::DEPLOYMENT_NOT_FOUND, 'Deployment not found. Create a deployment before trying to execute a function');
}
/** Check if build has completed */
$build = Authorization::skip(fn () => $dbForProject->getDocument('builds', $deployment->getAttribute('buildId', '')));
if ($build->isEmpty()) {
throw new Exception('Build not found', 404, Exception::BUILD_NOT_FOUND);
throw new Exception(Exception::BUILD_NOT_FOUND);
}
if ($build->getAttribute('status') !== 'ready') {
throw new Exception('Build not ready', 400, Exception::BUILD_NOT_READY);
throw new Exception(Exception::BUILD_NOT_READY);
}
$validator = new Authorization('execute');
if (!$validator->isValid($function->getAttribute('execute'))) { // Check if user has write access to execute function
throw new Exception($validator->getDescription(), 401, Exception::USER_UNAUTHORIZED);
throw new Exception(Exception::USER_UNAUTHORIZED, $validator->getDescription());
}
$executionId = ID::unique();
@ -1015,7 +1015,7 @@ App::get('/v1/functions/:functionId/executions')
$function = Authorization::skip(fn () => $dbForProject->getDocument('functions', $functionId));
if ($function->isEmpty()) {
throw new Exception('Function not found', 404, Exception::FUNCTION_NOT_FOUND);
throw new Exception(Exception::FUNCTION_NOT_FOUND);
}
$filterQueries = [
@ -1034,7 +1034,7 @@ App::get('/v1/functions/:functionId/executions')
$cursorDocument = $dbForProject->getDocument('executions', $cursor);
if ($cursorDocument->isEmpty()) {
throw new Exception("Execution '{$cursor}' for the 'cursor' value not found.", 400, Exception::GENERAL_CURSOR_NOT_FOUND);
throw new Exception(Exception::GENERAL_CURSOR_NOT_FOUND, "Tag '{$cursor}' for the 'cursor' value not found.");
}
$queries[] = $cursorDirection === Database::CURSOR_AFTER ? Query::cursorAfter($cursorDocument) : Query::cursorBefore($cursorDocument);
@ -1069,17 +1069,17 @@ App::get('/v1/functions/:functionId/executions/:executionId')
$function = Authorization::skip(fn () => $dbForProject->getDocument('functions', $functionId));
if ($function->isEmpty()) {
throw new Exception('Function not found', 404, Exception::FUNCTION_NOT_FOUND);
throw new Exception(Exception::FUNCTION_NOT_FOUND);
}
$execution = $dbForProject->getDocument('executions', $executionId);
if ($execution->getAttribute('functionId') !== $function->getId()) {
throw new Exception('Execution not found', 404, Exception::EXECUTION_NOT_FOUND);
throw new Exception(Exception::EXECUTION_NOT_FOUND);
}
if ($execution->isEmpty()) {
throw new Exception('Execution not found', 404, Exception::EXECUTION_NOT_FOUND);
throw new Exception(Exception::EXECUTION_NOT_FOUND);
}
$response->dynamic($execution, Response::MODEL_EXECUTION);
@ -1109,21 +1109,21 @@ App::post('/v1/functions/:functionId/deployments/:deploymentId/builds/:buildId')
$deployment = $dbForProject->getDocument('deployments', $deploymentId);
if ($function->isEmpty()) {
throw new Exception('Function not found', 404, Exception::FUNCTION_NOT_FOUND);
throw new Exception(Exception::FUNCTION_NOT_FOUND);
}
if ($deployment->isEmpty()) {
throw new Exception('Deployment not found', 404, Exception::DEPLOYMENT_NOT_FOUND);
throw new Exception(Exception::DEPLOYMENT_NOT_FOUND);
}
$build = Authorization::skip(fn () => $dbForProject->getDocument('builds', $buildId));
if ($build->isEmpty()) {
throw new Exception('Build not found', 404, Exception::BUILD_NOT_FOUND);
throw new Exception(Exception::BUILD_NOT_FOUND);
}
if ($build->getAttribute('status') !== 'failed') {
throw new Exception('Build not failed', 400, Exception::BUILD_IN_PROGRESS);
throw new Exception(Exception::BUILD_IN_PROGRESS, 'Build not failed');
}
$events

View file

@ -19,6 +19,6 @@ App::post('/v1/graphql')
->label('scope', 'public')
->action(
function () {
throw new Exception('GraphQL support is coming soon!', 502, Exception::GENERAL_SERVER_ERROR);
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'GraphQL support is coming soon!', 503);
}
);

View file

@ -73,7 +73,7 @@ App::get('/v1/health/db')
$statement->execute();
} catch (Exception $_e) {
throw new Exception('Database is not available', 500, Exception::GENERAL_SERVER_ERROR);
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Database is not available');
}
$output = [
@ -104,7 +104,7 @@ App::get('/v1/health/cache')
$redis = $utopia->getResource('cache');
if (!$redis->ping(true)) {
throw new Exception('Cache is not available', 500, Exception::GENERAL_SERVER_ERROR);
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Cache is not available');
}
$output = [
@ -160,7 +160,7 @@ App::get('/v1/health/time')
$diff = ($timestamp - \time());
if ($diff > $gap || $diff < ($gap * -1)) {
throw new Exception('Server time gaps detected', 500, Exception::GENERAL_SERVER_ERROR);
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Server time gaps detected');
}
$output = [
@ -267,11 +267,11 @@ App::get('/v1/health/storage/local')
$device = new Local($volume);
if (!\is_readable($device->getRoot())) {
throw new Exception('Device ' . $key . ' dir is not readable', 500, Exception::GENERAL_SERVER_ERROR);
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Device ' . $key . ' dir is not readable');
}
if (!\is_writable($device->getRoot())) {
throw new Exception('Device ' . $key . ' dir is not writable', 500, Exception::GENERAL_SERVER_ERROR);
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Device ' . $key . ' dir is not writable');
}
}
@ -315,7 +315,7 @@ App::get('/v1/health/anti-virus')
$output['version'] = @$antivirus->version();
$output['status'] = (@$antivirus->ping()) ? 'pass' : 'fail';
} catch (\Exception $e) {
throw new Exception('Antivirus is not available', 500, Exception::GENERAL_SERVER_ERROR);
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Antivirus is not available');
}
}

View file

@ -40,7 +40,7 @@ App::init()
->inject('project')
->action(function (Document $project) {
if ($project->getId() !== 'console') {
throw new Exception('Access to this API is forbidden.', 401, Exception::GENERAL_ACCESS_FORBIDDEN);
throw new Exception(Exception::GENERAL_ACCESS_FORBIDDEN);
}
});
@ -74,7 +74,7 @@ App::post('/v1/projects')
$team = $dbForConsole->getDocument('teams', $teamId);
if ($team->isEmpty()) {
throw new Exception('Team not found', 404, Exception::TEAM_NOT_FOUND);
throw new Exception(Exception::TEAM_NOT_FOUND);
}
$auth = Config::getParam('auth', []);
@ -86,7 +86,7 @@ App::post('/v1/projects')
$projectId = ($projectId == 'unique()') ? ID::unique() : $projectId;
if ($projectId === 'console') {
throw new Exception("'console' is a reserved project.", 400, Exception::PROJECT_RESERVED_PROJECT);
throw new Exception(Exception::PROJECT_RESERVED_PROJECT, "'console' is a reserved project.");
}
$project = $dbForConsole->createDocument('projects', new Document([
@ -204,7 +204,7 @@ App::get('/v1/projects')
$cursorDocument = $dbForConsole->getDocument('projects', $cursor);
if ($cursorDocument->isEmpty()) {
throw new Exception("Project '{$cursor}' for the 'cursor' value not found.", 400, Exception::GENERAL_CURSOR_NOT_FOUND);
throw new Exception(Exception::GENERAL_CURSOR_NOT_FOUND, "Project '{$cursor}' for the 'cursor' value not found.");
}
$queries[] = $cursorDirection === Database::CURSOR_AFTER ? Query::cursorAfter($cursorDocument) : Query::cursorBefore($cursorDocument);
@ -237,7 +237,7 @@ App::get('/v1/projects/:projectId')
$project = $dbForConsole->getDocument('projects', $projectId);
if ($project->isEmpty()) {
throw new Exception('Project not found', 404, Exception::PROJECT_NOT_FOUND);
throw new Exception(Exception::PROJECT_NOT_FOUND);
}
$response->dynamic($project, Response::MODEL_PROJECT);
@ -264,7 +264,7 @@ App::get('/v1/projects/:projectId/usage')
$project = $dbForConsole->getDocument('projects', $projectId);
if ($project->isEmpty()) {
throw new Exception('Project not found', 404, Exception::PROJECT_NOT_FOUND);
throw new Exception(Exception::PROJECT_NOT_FOUND);
}
$usage = [];
@ -383,7 +383,7 @@ App::patch('/v1/projects/:projectId')
$project = $dbForConsole->getDocument('projects', $projectId);
if ($project->isEmpty()) {
throw new Exception('Project not found', 404, Exception::PROJECT_NOT_FOUND);
throw new Exception(Exception::PROJECT_NOT_FOUND);
}
$project = $dbForConsole->updateDocument('projects', $project->getId(), $project
@ -422,7 +422,7 @@ App::patch('/v1/projects/:projectId/service')
$project = $dbForConsole->getDocument('projects', $projectId);
if ($project->isEmpty()) {
throw new Exception('Project not found', 404, Exception::PROJECT_NOT_FOUND);
throw new Exception(Exception::PROJECT_NOT_FOUND);
}
$services = $project->getAttribute('services', []);
@ -454,7 +454,7 @@ App::patch('/v1/projects/:projectId/oauth2')
$project = $dbForConsole->getDocument('projects', $projectId);
if ($project->isEmpty()) {
throw new Exception('Project not found', 404, Exception::PROJECT_NOT_FOUND);
throw new Exception(Exception::PROJECT_NOT_FOUND);
}
$providers = $project->getAttribute('authProviders', []);
@ -485,7 +485,7 @@ App::patch('/v1/projects/:projectId/auth/limit')
$project = $dbForConsole->getDocument('projects', $projectId);
if ($project->isEmpty()) {
throw new Exception('Project not found', 404, Exception::PROJECT_NOT_FOUND);
throw new Exception(Exception::PROJECT_NOT_FOUND);
}
$auths = $project->getAttribute('auths', []);
@ -520,7 +520,7 @@ App::patch('/v1/projects/:projectId/auth/:method')
$status = ($status === '1' || $status === 'true' || $status === 1 || $status === true);
if ($project->isEmpty()) {
throw new Exception('Project not found', 404, Exception::PROJECT_NOT_FOUND);
throw new Exception(Exception::PROJECT_NOT_FOUND);
}
$auths = $project->getAttribute('auths', []);
@ -549,13 +549,13 @@ App::delete('/v1/projects/:projectId')
->action(function (string $projectId, string $password, Response $response, Document $user, Database $dbForConsole, Delete $deletes) {
if (!Auth::passwordVerify($password, $user->getAttribute('password'))) { // Double check user password
throw new Exception('Invalid credentials', 401, Exception::USER_INVALID_CREDENTIALS);
throw new Exception(Exception::USER_INVALID_CREDENTIALS);
}
$project = $dbForConsole->getDocument('projects', $projectId);
if ($project->isEmpty()) {
throw new Exception('Project not found', 404, Exception::PROJECT_NOT_FOUND);
throw new Exception(Exception::PROJECT_NOT_FOUND);
}
$deletes
@ -564,11 +564,11 @@ App::delete('/v1/projects/:projectId')
;
if (!$dbForConsole->deleteDocument('teams', $project->getAttribute('teamId', null))) {
throw new Exception('Failed to remove project team from DB', 500, Exception::GENERAL_SERVER_ERROR);
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Failed to remove project team from DB');
}
if (!$dbForConsole->deleteDocument('projects', $projectId)) {
throw new Exception('Failed to remove project from DB', 500, Exception::GENERAL_SERVER_ERROR);
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Failed to remove project from DB');
}
$response->noContent();
@ -600,7 +600,7 @@ App::post('/v1/projects/:projectId/webhooks')
$project = $dbForConsole->getDocument('projects', $projectId);
if ($project->isEmpty()) {
throw new Exception('Project not found', 404, Exception::PROJECT_NOT_FOUND);
throw new Exception(Exception::PROJECT_NOT_FOUND);
}
$security = (bool) filter_var($security, FILTER_VALIDATE_BOOLEAN);
@ -649,7 +649,7 @@ App::get('/v1/projects/:projectId/webhooks')
$project = $dbForConsole->getDocument('projects', $projectId);
if ($project->isEmpty()) {
throw new Exception('Project not found', 404, Exception::PROJECT_NOT_FOUND);
throw new Exception(Exception::PROJECT_NOT_FOUND);
}
$webhooks = $dbForConsole->find('webhooks', [
@ -682,7 +682,7 @@ App::get('/v1/projects/:projectId/webhooks/:webhookId')
$project = $dbForConsole->getDocument('projects', $projectId);
if ($project->isEmpty()) {
throw new Exception('Project not found', 404, Exception::PROJECT_NOT_FOUND);
throw new Exception(Exception::PROJECT_NOT_FOUND);
}
$webhook = $dbForConsole->findOne('webhooks', [
@ -691,7 +691,7 @@ App::get('/v1/projects/:projectId/webhooks/:webhookId')
]);
if ($webhook === false || $webhook->isEmpty()) {
throw new Exception('Webhook not found', 404, Exception::WEBHOOK_NOT_FOUND);
throw new Exception(Exception::WEBHOOK_NOT_FOUND);
}
$response->dynamic($webhook, Response::MODEL_WEBHOOK);
@ -722,7 +722,7 @@ App::put('/v1/projects/:projectId/webhooks/:webhookId')
$project = $dbForConsole->getDocument('projects', $projectId);
if ($project->isEmpty()) {
throw new Exception('Project not found', 404, Exception::PROJECT_NOT_FOUND);
throw new Exception(Exception::PROJECT_NOT_FOUND);
}
$security = ($security === '1' || $security === 'true' || $security === 1 || $security === true);
@ -733,7 +733,7 @@ App::put('/v1/projects/:projectId/webhooks/:webhookId')
]);
if ($webhook === false || $webhook->isEmpty()) {
throw new Exception('Webhook not found', 404, Exception::WEBHOOK_NOT_FOUND);
throw new Exception(Exception::WEBHOOK_NOT_FOUND);
}
$webhook
@ -770,7 +770,7 @@ App::patch('/v1/projects/:projectId/webhooks/:webhookId/signature')
$project = $dbForConsole->getDocument('projects', $projectId);
if ($project->isEmpty()) {
throw new Exception('Project not found', 404, Exception::PROJECT_NOT_FOUND);
throw new Exception(Exception::PROJECT_NOT_FOUND);
}
$webhook = $dbForConsole->findOne('webhooks', [
@ -779,7 +779,7 @@ App::patch('/v1/projects/:projectId/webhooks/:webhookId/signature')
]);
if ($webhook === false || $webhook->isEmpty()) {
throw new Exception('Webhook not found', 404, Exception::WEBHOOK_NOT_FOUND);
throw new Exception(Exception::WEBHOOK_NOT_FOUND);
}
$webhook->setAttribute('signatureKey', \bin2hex(\random_bytes(64)));
@ -808,7 +808,7 @@ App::delete('/v1/projects/:projectId/webhooks/:webhookId')
$project = $dbForConsole->getDocument('projects', $projectId);
if ($project->isEmpty()) {
throw new Exception('Project not found', 404, Exception::PROJECT_NOT_FOUND);
throw new Exception(Exception::PROJECT_NOT_FOUND);
}
$webhook = $dbForConsole->findOne('webhooks', [
@ -817,7 +817,7 @@ App::delete('/v1/projects/:projectId/webhooks/:webhookId')
]);
if ($webhook === false || $webhook->isEmpty()) {
throw new Exception('Webhook not found', 404, Exception::WEBHOOK_NOT_FOUND);
throw new Exception(Exception::WEBHOOK_NOT_FOUND);
}
$dbForConsole->deleteDocument('webhooks', $webhook->getId());
@ -850,7 +850,7 @@ App::post('/v1/projects/:projectId/keys')
$project = $dbForConsole->getDocument('projects', $projectId);
if ($project->isEmpty()) {
throw new Exception('Project not found', 404, Exception::PROJECT_NOT_FOUND);
throw new Exception(Exception::PROJECT_NOT_FOUND);
}
$key = new Document([
@ -894,7 +894,7 @@ App::get('/v1/projects/:projectId/keys')
$project = $dbForConsole->getDocument('projects', $projectId);
if ($project->isEmpty()) {
throw new Exception('Project not found', 404, Exception::PROJECT_NOT_FOUND);
throw new Exception(Exception::PROJECT_NOT_FOUND);
}
$keys = $dbForConsole->find('keys', [
@ -927,7 +927,7 @@ App::get('/v1/projects/:projectId/keys/:keyId')
$project = $dbForConsole->getDocument('projects', $projectId);
if ($project->isEmpty()) {
throw new Exception('Project not found', 404, Exception::PROJECT_NOT_FOUND);
throw new Exception(Exception::PROJECT_NOT_FOUND);
}
$key = $dbForConsole->findOne('keys', [
@ -936,7 +936,7 @@ App::get('/v1/projects/:projectId/keys/:keyId')
]);
if ($key === false || $key->isEmpty()) {
throw new Exception('Key not found', 404, Exception::KEY_NOT_FOUND);
throw new Exception(Exception::KEY_NOT_FOUND);
}
$response->dynamic($key, Response::MODEL_KEY);
@ -964,7 +964,7 @@ App::put('/v1/projects/:projectId/keys/:keyId')
$project = $dbForConsole->getDocument('projects', $projectId);
if ($project->isEmpty()) {
throw new Exception('Project not found', 404, Exception::PROJECT_NOT_FOUND);
throw new Exception(Exception::PROJECT_NOT_FOUND);
}
$key = $dbForConsole->findOne('keys', [
@ -973,7 +973,7 @@ App::put('/v1/projects/:projectId/keys/:keyId')
]);
if ($key === false || $key->isEmpty()) {
throw new Exception('Key not found', 404, Exception::KEY_NOT_FOUND);
throw new Exception(Exception::KEY_NOT_FOUND);
}
$key
@ -1007,7 +1007,7 @@ App::delete('/v1/projects/:projectId/keys/:keyId')
$project = $dbForConsole->getDocument('projects', $projectId);
if ($project->isEmpty()) {
throw new Exception('Project not found', 404, Exception::PROJECT_NOT_FOUND);
throw new Exception(Exception::PROJECT_NOT_FOUND);
}
$key = $dbForConsole->findOne('keys', [
@ -1016,7 +1016,7 @@ App::delete('/v1/projects/:projectId/keys/:keyId')
]);
if ($key === false || $key->isEmpty()) {
throw new Exception('Key not found', 404, Exception::KEY_NOT_FOUND);
throw new Exception(Exception::KEY_NOT_FOUND);
}
$dbForConsole->deleteDocument('keys', $key->getId());
@ -1050,7 +1050,7 @@ App::post('/v1/projects/:projectId/platforms')
$project = $dbForConsole->getDocument('projects', $projectId);
if ($project->isEmpty()) {
throw new Exception('Project not found', 404, Exception::PROJECT_NOT_FOUND);
throw new Exception(Exception::PROJECT_NOT_FOUND);
}
$platform = new Document([
@ -1095,7 +1095,7 @@ App::get('/v1/projects/:projectId/platforms')
$project = $dbForConsole->getDocument('projects', $projectId);
if ($project->isEmpty()) {
throw new Exception('Project not found', 404, Exception::PROJECT_NOT_FOUND);
throw new Exception(Exception::PROJECT_NOT_FOUND);
}
$platforms = $dbForConsole->find('platforms', [
@ -1128,7 +1128,7 @@ App::get('/v1/projects/:projectId/platforms/:platformId')
$project = $dbForConsole->getDocument('projects', $projectId);
if ($project->isEmpty()) {
throw new Exception('Project not found', 404, Exception::PROJECT_NOT_FOUND);
throw new Exception(Exception::PROJECT_NOT_FOUND);
}
$platform = $dbForConsole->findOne('platforms', [
@ -1137,7 +1137,7 @@ App::get('/v1/projects/:projectId/platforms/:platformId')
]);
if ($platform === false || $platform->isEmpty()) {
throw new Exception('Platform not found', 404, Exception::PLATFORM_NOT_FOUND);
throw new Exception(Exception::PLATFORM_NOT_FOUND);
}
$response->dynamic($platform, Response::MODEL_PLATFORM);
@ -1165,7 +1165,7 @@ App::put('/v1/projects/:projectId/platforms/:platformId')
$project = $dbForConsole->getDocument('projects', $projectId);
if ($project->isEmpty()) {
throw new Exception('Project not found', 404, Exception::PROJECT_NOT_FOUND);
throw new Exception(Exception::PROJECT_NOT_FOUND);
}
$platform = $dbForConsole->findOne('platforms', [
@ -1174,7 +1174,7 @@ App::put('/v1/projects/:projectId/platforms/:platformId')
]);
if ($platform === false || $platform->isEmpty()) {
throw new Exception('Platform not found', 404, Exception::PLATFORM_NOT_FOUND);
throw new Exception(Exception::PLATFORM_NOT_FOUND);
}
$platform
@ -1209,7 +1209,7 @@ App::delete('/v1/projects/:projectId/platforms/:platformId')
$project = $dbForConsole->getDocument('projects', $projectId);
if ($project->isEmpty()) {
throw new Exception('Project not found', 404, Exception::PROJECT_NOT_FOUND);
throw new Exception(Exception::PROJECT_NOT_FOUND);
}
$platform = $dbForConsole->findOne('platforms', [
@ -1218,7 +1218,7 @@ App::delete('/v1/projects/:projectId/platforms/:platformId')
]);
if ($platform === false || $platform->isEmpty()) {
throw new Exception('Platform not found', 404, Exception::PLATFORM_NOT_FOUND);
throw new Exception(Exception::PLATFORM_NOT_FOUND);
}
$dbForConsole->deleteDocument('platforms', $platformId);
@ -1249,7 +1249,7 @@ App::post('/v1/projects/:projectId/domains')
$project = $dbForConsole->getDocument('projects', $projectId);
if ($project->isEmpty()) {
throw new Exception('Project not found', 404, Exception::PROJECT_NOT_FOUND);
throw new Exception(Exception::PROJECT_NOT_FOUND);
}
$document = $dbForConsole->findOne('domains', [
@ -1258,13 +1258,13 @@ App::post('/v1/projects/:projectId/domains')
]);
if ($document && !$document->isEmpty()) {
throw new Exception('Domain already exists', 409, Exception::DOMAIN_ALREADY_EXISTS);
throw new Exception(Exception::DOMAIN_ALREADY_EXISTS);
}
$target = new Domain(App::getEnv('_APP_DOMAIN_TARGET', ''));
if (!$target->isKnown() || $target->isTest()) {
throw new Exception('Unreachable CNAME target (' . $target->get() . '), please use a domain with a public suffix.', 500, Exception::GENERAL_SERVER_ERROR);
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Unreachable CNAME target (' . $target->get() . '), please use a domain with a public suffix.');
}
$domain = new Domain($domain);
@ -1312,7 +1312,7 @@ App::get('/v1/projects/:projectId/domains')
$project = $dbForConsole->getDocument('projects', $projectId);
if ($project->isEmpty()) {
throw new Exception('Project not found', 404, Exception::PROJECT_NOT_FOUND);
throw new Exception(Exception::PROJECT_NOT_FOUND);
}
$domains = $dbForConsole->find('domains', [
@ -1345,7 +1345,7 @@ App::get('/v1/projects/:projectId/domains/:domainId')
$project = $dbForConsole->getDocument('projects', $projectId);
if ($project->isEmpty()) {
throw new Exception('Project not found', 404, Exception::PROJECT_NOT_FOUND);
throw new Exception(Exception::PROJECT_NOT_FOUND);
}
$domain = $dbForConsole->findOne('domains', [
@ -1354,7 +1354,7 @@ App::get('/v1/projects/:projectId/domains/:domainId')
]);
if ($domain === false || $domain->isEmpty()) {
throw new Exception('Domain not found', 404, Exception::DOMAIN_NOT_FOUND);
throw new Exception(Exception::DOMAIN_NOT_FOUND);
}
$response->dynamic($domain, Response::MODEL_DOMAIN);
@ -1379,7 +1379,7 @@ App::patch('/v1/projects/:projectId/domains/:domainId/verification')
$project = $dbForConsole->getDocument('projects', $projectId);
if ($project->isEmpty()) {
throw new Exception('Project not found', 404, Exception::PROJECT_NOT_FOUND);
throw new Exception(Exception::PROJECT_NOT_FOUND);
}
$domain = $dbForConsole->findOne('domains', [
@ -1388,13 +1388,13 @@ App::patch('/v1/projects/:projectId/domains/:domainId/verification')
]);
if ($domain === false || $domain->isEmpty()) {
throw new Exception('Domain not found', 404, Exception::DOMAIN_NOT_FOUND);
throw new Exception(Exception::DOMAIN_NOT_FOUND);
}
$target = new Domain(App::getEnv('_APP_DOMAIN_TARGET', ''));
if (!$target->isKnown() || $target->isTest()) {
throw new Exception('Unreachable CNAME target (' . $target->get() . '), please use a domain with a public suffix.', 500, Exception::GENERAL_SERVER_ERROR);
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Unreachable CNAME target (' . $target->get() . '), please use a domain with a public suffix.');
}
if ($domain->getAttribute('verification') === true) {
@ -1404,7 +1404,7 @@ App::patch('/v1/projects/:projectId/domains/:domainId/verification')
$validator = new CNAME($target->get()); // Verify Domain with DNS records
if (!$validator->isValid($domain->getAttribute('domain', ''))) {
throw new Exception('Failed to verify domain', 401, Exception::DOMAIN_VERIFICATION_FAILED);
throw new Exception(Exception::DOMAIN_VERIFICATION_FAILED);
}
@ -1439,7 +1439,7 @@ App::delete('/v1/projects/:projectId/domains/:domainId')
$project = $dbForConsole->getDocument('projects', $projectId);
if ($project->isEmpty()) {
throw new Exception('Project not found', 404, Exception::PROJECT_NOT_FOUND);
throw new Exception(Exception::PROJECT_NOT_FOUND);
}
$domain = $dbForConsole->findOne('domains', [
@ -1448,7 +1448,7 @@ App::delete('/v1/projects/:projectId/domains/:domainId')
]);
if ($domain === false || $domain->isEmpty()) {
throw new Exception('Domain not found', 404, Exception::DOMAIN_NOT_FOUND);
throw new Exception(Exception::DOMAIN_NOT_FOUND);
}
$dbForConsole->deleteDocument('domains', $domain->getId());

View file

@ -84,7 +84,7 @@ App::post('/v1/storage/buckets')
try {
$files = Config::getParam('collections', [])['files'] ?? [];
if (empty($files)) {
throw new Exception('Files collection is not configured.', 500, Exception::GENERAL_SERVER_ERROR);
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Files collection is not configured.');
}
$attributes = [];
@ -132,7 +132,7 @@ App::post('/v1/storage/buckets')
$dbForProject->createCollection('bucket_' . $bucket->getInternalId(), $attributes, $indexes);
} catch (Duplicate) {
throw new Exception('Bucket already exists', 409, Exception::STORAGE_BUCKET_ALREADY_EXISTS);
throw new Exception(Exception::STORAGE_BUCKET_ALREADY_EXISTS);
}
$audits
@ -186,7 +186,7 @@ App::get('/v1/storage/buckets')
$cursorDocument = $dbForProject->getDocument('buckets', $cursor);
if ($cursorDocument->isEmpty()) {
throw new Exception("Bucket '{$cursor}' for the 'cursor' value not found.", 400, Exception::GENERAL_CURSOR_NOT_FOUND);
throw new Exception(Exception::GENERAL_CURSOR_NOT_FOUND, "Bucket '{$cursor}' for the 'cursor' value not found.");
}
$queries[] = $cursorDirection === Database::CURSOR_AFTER ? Query::cursorAfter($cursorDocument) : Query::cursorBefore($cursorDocument);
@ -220,7 +220,7 @@ App::get('/v1/storage/buckets/:bucketId')
$bucket = $dbForProject->getDocument('buckets', $bucketId);
if ($bucket->isEmpty()) {
throw new Exception('Bucket not found', 404, Exception::STORAGE_BUCKET_NOT_FOUND);
throw new Exception(Exception::STORAGE_BUCKET_NOT_FOUND);
}
$usage->setParam('storage.buckets.read', 1);
@ -258,7 +258,7 @@ App::put('/v1/storage/buckets/:bucketId')
$bucket = $dbForProject->getDocument('buckets', $bucketId);
if ($bucket->isEmpty()) {
throw new Exception('Bucket not found', 404, Exception::STORAGE_BUCKET_NOT_FOUND);
throw new Exception(Exception::STORAGE_BUCKET_NOT_FOUND);
}
$permissions ??= $bucket->getPermissions();
@ -320,11 +320,11 @@ App::delete('/v1/storage/buckets/:bucketId')
$bucket = $dbForProject->getDocument('buckets', $bucketId);
if ($bucket->isEmpty()) {
throw new Exception('Bucket not found', 404, Exception::STORAGE_BUCKET_NOT_FOUND);
throw new Exception(Exception::STORAGE_BUCKET_NOT_FOUND);
}
if (!$dbForProject->deleteDocument('buckets', $bucketId)) {
throw new Exception('Failed to remove project from DB', 500, Exception::GENERAL_SERVER_ERROR);
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Failed to remove bucket from DB');
}
$deletes
@ -380,12 +380,12 @@ App::post('/v1/storage/buckets/:bucketId/files')
$bucket = Authorization::skip(fn () => $dbForProject->getDocument('buckets', $bucketId));
if ($bucket->isEmpty() || (!$bucket->getAttribute('enabled') && $mode !== APP_MODE_ADMIN)) {
throw new Exception('Bucket not found', 404, Exception::STORAGE_BUCKET_NOT_FOUND);
throw new Exception(Exception::STORAGE_BUCKET_NOT_FOUND);
}
$validator = new Authorization('create');
if (!$validator->isValid($bucket->getCreate())) {
throw new Exception('Unauthorized permissions', 401, Exception::USER_UNAUTHORIZED);
throw new Exception(Exception::USER_UNAUTHORIZED);
}
/**
@ -428,7 +428,7 @@ App::post('/v1/storage/buckets/:bucketId/files')
}
$role = \str_replace([$type, '(', ')', '"', ' '], '', $permission);
if (!Authorization::isRole($role)) {
throw new Exception('Permissions must be one of: (' . \implode(', ', Authorization::getRoles()) . ')', 400, Exception::USER_UNAUTHORIZED);
throw new Exception(Exception::USER_UNAUTHORIZED, 'Permissions must be one of: (' . \implode(', ', Authorization::getRoles()) . ')');
}
}
}
@ -444,12 +444,12 @@ App::post('/v1/storage/buckets/:bucketId/files')
$maximumFileSize = $bucket->getAttribute('maximumFileSize', 0);
if ($maximumFileSize > (int) App::getEnv('_APP_STORAGE_LIMIT', 0)) {
throw new Exception('Maximum bucket file size is larger than _APP_STORAGE_LIMIT', 500, Exception::GENERAL_SERVER_ERROR);
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Maximum bucket file size is larger than _APP_STORAGE_LIMIT');
}
$file = $request->getFiles('file');
if (empty($file)) {
throw new Exception('No file sent', 400, Exception::STORAGE_FILE_EMPTY);
throw new Exception(Exception::STORAGE_FILE_EMPTY);
}
// Make sure we handle a single file and multiple files the same way
@ -468,7 +468,7 @@ App::post('/v1/storage/buckets/:bucketId/files')
$fileSize = $request->getContentRangeSize();
$fileId = $request->getHeader('x-appwrite-id', $fileId);
if (is_null($start) || is_null($end) || is_null($fileSize)) {
throw new Exception('Invalid content-range header', 400, Exception::STORAGE_INVALID_CONTENT_RANGE);
throw new Exception(Exception::STORAGE_INVALID_CONTENT_RANGE);
}
if ($end === $fileSize) {
@ -488,18 +488,18 @@ App::post('/v1/storage/buckets/:bucketId/files')
$allowedFileExtensions = $bucket->getAttribute('allowedFileExtensions', []);
$fileExt = new FileExt($allowedFileExtensions);
if (!empty($allowedFileExtensions) && !$fileExt->isValid($fileName)) {
throw new Exception('File extension not allowed', 400, Exception::STORAGE_FILE_TYPE_UNSUPPORTED);
throw new Exception(Exception::STORAGE_FILE_TYPE_UNSUPPORTED, 'File extension not allowed');
}
// Check if file size is exceeding allowed limit
$fileSizeValidator = new FileSize($maximumFileSize);
if (!$fileSizeValidator->isValid($fileSize)) {
throw new Exception('File size not allowed', 400, Exception::STORAGE_INVALID_FILE_SIZE);
throw new Exception(Exception::STORAGE_INVALID_FILE_SIZE, 'File size not allowed');
}
$upload = new Upload();
if (!$upload->isValid($fileTmpName)) {
throw new Exception('Invalid file', 403, Exception::STORAGE_INVALID_FILE);
throw new Exception(Exception::STORAGE_INVALID_FILE);
}
// Save to storage
@ -520,7 +520,7 @@ App::post('/v1/storage/buckets/:bucketId/files')
$chunksUploaded = $deviceFiles->upload($fileTmpName, $path, $chunk, $chunks, $metadata);
if (empty($chunksUploaded)) {
throw new Exception('Failed uploading file', 500, Exception::GENERAL_SERVER_ERROR);
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Failed uploading file');
}
if ($chunksUploaded === $chunks) {
@ -532,7 +532,7 @@ App::post('/v1/storage/buckets/:bucketId/files')
if (!$antivirus->fileScan($path)) {
$deviceFiles->delete($path);
throw new Exception('Invalid file', 400, Exception::STORAGE_INVALID_FILE);
throw new Exception(Exception::STORAGE_INVALID_FILE);
}
}
@ -556,7 +556,7 @@ App::post('/v1/storage/buckets/:bucketId/files')
if (!empty($data)) {
if (!$deviceFiles->write($path, $data, $mimeType)) {
throw new Exception('Failed to save file', 500, Exception::GENERAL_SERVER_ERROR);
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Failed to save file');
}
}
@ -614,9 +614,9 @@ App::post('/v1/storage/buckets/:bucketId/files')
$file = $dbForProject->updateDocument('bucket_' . $bucket->getInternalId(), $fileId, $file);
}
} catch (StructureException $exception) {
throw new Exception($exception->getMessage(), 400, Exception::DOCUMENT_INVALID_STRUCTURE);
throw new Exception(Exception::DOCUMENT_INVALID_STRUCTURE, $exception->getMessage());
} catch (DuplicateException) {
throw new Exception('Document already exists', 409, Exception::DOCUMENT_ALREADY_EXISTS);
throw new Exception(Exception::DOCUMENT_ALREADY_EXISTS);
}
$audits
@ -658,9 +658,9 @@ App::post('/v1/storage/buckets/:bucketId/files')
$file = $dbForProject->updateDocument('bucket_' . $bucket->getInternalId(), $fileId, $file);
}
} catch (StructureException $exception) {
throw new Exception($exception->getMessage(), 400, Exception::DOCUMENT_INVALID_STRUCTURE);
throw new Exception(Exception::DOCUMENT_INVALID_STRUCTURE, $exception->getMessage());
} catch (DuplicateException) {
throw new Exception('Document already exists', 409, Exception::DOCUMENT_ALREADY_EXISTS);
throw new Exception(Exception::DOCUMENT_ALREADY_EXISTS);
}
}
@ -704,12 +704,12 @@ App::get('/v1/storage/buckets/:bucketId/files')
$bucket = Authorization::skip(fn () => $dbForProject->getDocument('buckets', $bucketId));
if ($bucket->isEmpty() || (!$bucket->getAttribute('enabled') && $mode !== APP_MODE_ADMIN)) {
throw new Exception('Bucket not found', 404, Exception::STORAGE_BUCKET_NOT_FOUND);
throw new Exception(Exception::STORAGE_BUCKET_NOT_FOUND);
}
$validator = new Authorization('read');
if (!$validator->isValid($bucket->getRead())) {
throw new Exception('Unauthorized permissions', 401, Exception::USER_UNAUTHORIZED);
throw new Exception(Exception::USER_UNAUTHORIZED);
}
$filterQueries = [];
@ -726,7 +726,7 @@ App::get('/v1/storage/buckets/:bucketId/files')
$cursorDocument = $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $cursor);
if ($cursorDocument->isEmpty()) {
throw new Exception("File '{$cursor}' for the 'cursor' value not found.", 400, Exception::GENERAL_CURSOR_NOT_FOUND);
throw new Exception(Exception::GENERAL_CURSOR_NOT_FOUND, "File '{$cursor}' for the 'cursor' value not found.");
}
$queries[] = $cursorDirection === Database::CURSOR_AFTER ? Query::cursorAfter($cursorDocument) : Query::cursorBefore($cursorDocument);
@ -774,20 +774,20 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId')
$bucket = Authorization::skip(fn () => $dbForProject->getDocument('buckets', $bucketId));
if ($bucket->isEmpty() || (!$bucket->getAttribute('enabled') && $mode !== APP_MODE_ADMIN)) {
throw new Exception('Bucket not found', 404, Exception::STORAGE_BUCKET_NOT_FOUND);
throw new Exception(Exception::STORAGE_BUCKET_NOT_FOUND);
}
$fileSecurity = $bucket->getAttribute('fileSecurity', false);
$validator = new Authorization('read');
$valid = $validator->isValid($bucket->getRead());
if (!$valid && !$fileSecurity) {
throw new Exception('Unauthorized permissions', 401, Exception::USER_UNAUTHORIZED);
throw new Exception(Exception::USER_UNAUTHORIZED);
}
$file = $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId);
if ($file->isEmpty() || $file->getAttribute('bucketId') !== $bucketId) {
throw new Exception('File not found', 404, Exception::STORAGE_FILE_NOT_FOUND);
throw new Exception(Exception::STORAGE_FILE_NOT_FOUND);
}
if ($fileSecurity) {
@ -841,20 +841,20 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/preview')
->action(function (string $bucketId, string $fileId, int $width, int $height, string $gravity, int $quality, int $borderWidth, string $borderColor, int $borderRadius, float $opacity, int $rotation, string $background, string $output, Request $request, Response $response, Document $project, Database $dbForProject, Stats $usage, string $mode, Device $deviceFiles, Device $deviceLocal) {
if (!\extension_loaded('imagick')) {
throw new Exception('Imagick extension is missing', 500, Exception::GENERAL_SERVER_ERROR);
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Imagick extension is missing');
}
$bucket = Authorization::skip(fn () => $dbForProject->getDocument('buckets', $bucketId));
if ($bucket->isEmpty() || (!$bucket->getAttribute('enabled') && $mode !== APP_MODE_ADMIN)) {
throw new Exception('Bucket not found', 404, Exception::STORAGE_BUCKET_NOT_FOUND);
throw new Exception(Exception::STORAGE_BUCKET_NOT_FOUND);
}
$fileSecurity = $bucket->getAttribute('fileSecurity', false);
$validator = new Authorization('read');
$valid = $validator->isValid($bucket->getRead());
if (!$valid && !$fileSecurity) {
throw new Exception('Unauthorized permissions', 401, Exception::USER_UNAUTHORIZED);
throw new Exception(Exception::USER_UNAUTHORIZED);
}
if ((\strpos($request->getAccept(), 'image/webp') === false) && ('webp' === $output)) { // Fallback webp to jpeg when no browser support
@ -871,7 +871,7 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/preview')
$file = $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId);
if ($file->isEmpty() || $file->getAttribute('bucketId') !== $bucketId) {
throw new Exception('File not found', 404, Exception::STORAGE_FILE_NOT_FOUND);
throw new Exception(Exception::STORAGE_FILE_NOT_FOUND);
}
if ($fileSecurity) {
@ -907,7 +907,7 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/preview')
$compressor = new GZIP();
if (!$deviceFiles->exists($path)) {
throw new Exception('File not found', 404, Exception::STORAGE_FILE_NOT_FOUND);
throw new Exception(Exception::STORAGE_FILE_NOT_FOUND);
}
$cache = new Cache(new Filesystem(APP_STORAGE_CACHE . DIRECTORY_SEPARATOR . 'app-' . $project->getId() . DIRECTORY_SEPARATOR . $bucketId . DIRECTORY_SEPARATOR . $fileId)); // Limit file number or size
@ -1013,20 +1013,20 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/download')
$bucket = Authorization::skip(fn () => $dbForProject->getDocument('buckets', $bucketId));
if ($bucket->isEmpty() || (!$bucket->getAttribute('enabled') && $mode !== APP_MODE_ADMIN)) {
throw new Exception('Bucket not found', 404, Exception::STORAGE_BUCKET_NOT_FOUND);
throw new Exception(Exception::STORAGE_BUCKET_NOT_FOUND);
}
$fileSecurity = $bucket->getAttribute('fileSecurity', false);
$validator = new Authorization('read');
$valid = $validator->isValid($bucket->getRead());
if (!$valid && !$fileSecurity) {
throw new Exception('Unauthorized permissions', 401, Exception::USER_UNAUTHORIZED);
throw new Exception(Exception::USER_UNAUTHORIZED);
}
$file = $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId);
if ($file->isEmpty() || $file->getAttribute('bucketId') !== $bucketId) {
throw new Exception('File not found', 404, Exception::STORAGE_FILE_NOT_FOUND);
throw new Exception(Exception::STORAGE_FILE_NOT_FOUND);
}
if ($bucket->getAttribute('fileSecurity', false)) {
@ -1039,7 +1039,7 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/download')
$path = $file->getAttribute('path', '');
if (!$deviceFiles->exists($path)) {
throw new Exception('File not found in ' . $path, 404, Exception::STORAGE_FILE_NOT_FOUND);
throw new Exception(Exception::STORAGE_FILE_NOT_FOUND, 'File not found in ' . $path);
}
$usage
@ -1067,7 +1067,7 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/download')
}
if ($unit !== 'bytes' || $start >= $end || $end >= $size) {
throw new Exception('Invalid range', 416, Exception::STORAGE_INVALID_RANGE);
throw new Exception(Exception::STORAGE_INVALID_RANGE);
}
$response
@ -1151,20 +1151,20 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/view')
$bucket = Authorization::skip(fn () => $dbForProject->getDocument('buckets', $bucketId));
if ($bucket->isEmpty() || (!$bucket->getAttribute('enabled') && $mode !== APP_MODE_ADMIN)) {
throw new Exception('Bucket not found', 404, Exception::STORAGE_BUCKET_NOT_FOUND);
throw new Exception(Exception::STORAGE_BUCKET_NOT_FOUND);
}
$fileSecurity = $bucket->getAttribute('fileSecurity', false);
$validator = new Authorization('read');
$valid = $validator->isValid($bucket->getRead());
if (!$valid && !$fileSecurity) {
throw new Exception('Unauthorized permissions', 401, Exception::USER_UNAUTHORIZED);
throw new Exception(Exception::USER_UNAUTHORIZED);
}
$file = $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId);
if ($file->isEmpty() || $file->getAttribute('bucketId') !== $bucketId) {
throw new Exception('File not found', 404, Exception::STORAGE_FILE_NOT_FOUND);
throw new Exception(Exception::STORAGE_FILE_NOT_FOUND);
}
if ($fileSecurity) {
@ -1179,7 +1179,7 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/view')
$path = $file->getAttribute('path', '');
if (!$deviceFiles->exists($path)) {
throw new Exception('File not found in ' . $path, 404, Exception::STORAGE_FILE_NOT_FOUND);
throw new Exception(Exception::STORAGE_FILE_NOT_FOUND, 'File not found in ' . $path);
}
$contentType = 'text/plain';
@ -1210,7 +1210,7 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/view')
}
if ($unit != 'bytes' || $start >= $end || $end >= $size) {
throw new Exception('Invalid range', 416, Exception::STORAGE_INVALID_RANGE);
throw new Exception(Exception::STORAGE_INVALID_RANGE);
}
$response
@ -1303,20 +1303,20 @@ App::put('/v1/storage/buckets/:bucketId/files/:fileId')
$bucket = Authorization::skip(fn () => $dbForProject->getDocument('buckets', $bucketId));
if ($bucket->isEmpty() || (!$bucket->getAttribute('enabled') && $mode !== APP_MODE_ADMIN)) {
throw new Exception('Bucket not found', 404, Exception::STORAGE_BUCKET_NOT_FOUND);
throw new Exception(Exception::STORAGE_BUCKET_NOT_FOUND);
}
$fileSecurity = $bucket->getAttributes('fileSecurity', false);
$validator = new Authorization('update');
$valid = $validator->isValid($bucket->getUpdate());
if (!$valid && !$fileSecurity) {
throw new Exception('Unauthorized permissions', 401, Exception::USER_UNAUTHORIZED);
throw new Exception(Exception::USER_UNAUTHORIZED);
}
$file = $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId);
if ($file->isEmpty() || $file->getAttribute('bucketId') !== $bucketId) {
throw new Exception('File not found', 404, Exception::STORAGE_FILE_NOT_FOUND);
throw new Exception(Exception::STORAGE_FILE_NOT_FOUND);
}
if ($fileSecurity) {
@ -1394,20 +1394,20 @@ App::delete('/v1/storage/buckets/:bucketId/files/:fileId')
$bucket = Authorization::skip(fn () => $dbForProject->getDocument('buckets', $bucketId));
if ($bucket->isEmpty() || (!$bucket->getAttribute('enabled') && $mode !== APP_MODE_ADMIN)) {
throw new Exception('Bucket not found', 404, Exception::STORAGE_BUCKET_NOT_FOUND);
throw new Exception(Exception::STORAGE_BUCKET_NOT_FOUND);
}
$fileSecurity = $bucket->getAttributes('fileSecurity', false);
$validator = new Authorization('delete');
$valid = $validator->isValid($bucket->getDelete());
if (!$valid && !$fileSecurity) {
throw new Exception('Unauthorized permissions', 401, Exception::USER_UNAUTHORIZED);
throw new Exception(Exception::USER_UNAUTHORIZED);
}
$file = $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId);
if ($file->isEmpty() || $file->getAttribute('bucketId') !== $bucketId) {
throw new Exception('File not found', 404, Exception::STORAGE_FILE_NOT_FOUND);
throw new Exception(Exception::STORAGE_FILE_NOT_FOUND);
}
if ($fileSecurity) {
@ -1436,10 +1436,10 @@ App::delete('/v1/storage/buckets/:bucketId/files/:fileId')
$deleted = $dbForProject->deleteDocument('bucket_' . $bucket->getInternalId(), $fileId);
if (!$deleted) {
throw new Exception('Failed to remove file from DB', 500, Exception::GENERAL_SERVER_ERROR);
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Failed to remove file from DB');
}
} else {
throw new Exception('Failed to delete file from device', 500, Exception::GENERAL_SERVER_ERROR);
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Failed to delete file from device');
}
$audits->setResource('file/' . $file->getId());
@ -1590,7 +1590,7 @@ App::get('/v1/storage/:bucketId/usage')
$bucket = $dbForProject->getDocument('buckets', $bucketId);
if ($bucket->isEmpty()) {
throw new Exception('Bucket not found', 404, Exception::STORAGE_BUCKET_NOT_FOUND);
throw new Exception(Exception::STORAGE_BUCKET_NOT_FOUND);
}
$usage = [];

View file

@ -153,7 +153,7 @@ App::get('/v1/teams')
$cursorDocument = $dbForProject->getDocument('teams', $cursor);
if ($cursorDocument->isEmpty()) {
throw new Exception("Team '{$cursor}' for the 'cursor' value not found.", 400, Exception::GENERAL_CURSOR_NOT_FOUND);
throw new Exception(Exception::GENERAL_CURSOR_NOT_FOUND, "Team '{$cursor}' for the 'cursor' value not found.");
}
$queries[] = $cursorDirection === Database::CURSOR_AFTER ? Query::cursorAfter($cursorDocument) : Query::cursorBefore($cursorDocument);
@ -187,7 +187,7 @@ App::get('/v1/teams/:teamId')
$team = $dbForProject->getDocument('teams', $teamId);
if ($team->isEmpty()) {
throw new Exception('Team not found', 404, Exception::TEAM_NOT_FOUND);
throw new Exception(Exception::TEAM_NOT_FOUND);
}
$response->dynamic($team, Response::MODEL_TEAM);
@ -216,7 +216,7 @@ App::put('/v1/teams/:teamId')
$team = $dbForProject->getDocument('teams', $teamId);
if ($team->isEmpty()) {
throw new Exception('Team not found', 404, Exception::TEAM_NOT_FOUND);
throw new Exception(Exception::TEAM_NOT_FOUND);
}
$team = $dbForProject->updateDocument('teams', $team->getId(), $team
@ -251,7 +251,7 @@ App::delete('/v1/teams/:teamId')
$team = $dbForProject->getDocument('teams', $teamId);
if ($team->isEmpty()) {
throw new Exception('Team not found', 404, Exception::TEAM_NOT_FOUND);
throw new Exception(Exception::TEAM_NOT_FOUND);
}
$memberships = $dbForProject->find('memberships', [
@ -262,12 +262,12 @@ App::delete('/v1/teams/:teamId')
// TODO delete all members individually from the user object
foreach ($memberships as $membership) {
if (!$dbForProject->deleteDocument('memberships', $membership->getId())) {
throw new Exception('Failed to remove membership for team from DB', 500, Exception::GENERAL_SERVER_ERROR);
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Failed to remove membership for team from DB');
}
}
if (!$dbForProject->deleteDocument('teams', $teamId)) {
throw new Exception('Failed to remove team from DB', 500, Exception::GENERAL_SERVER_ERROR);
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Failed to remove team from DB');
}
$deletes
@ -321,7 +321,7 @@ App::post('/v1/teams/:teamId/memberships')
$isAppUser = Auth::isAppUser(Authorization::getRoles());
if (!$isPrivilegedUser && !$isAppUser && empty(App::getEnv('_APP_SMTP_HOST'))) {
throw new Exception('SMTP Disabled', 503, Exception::GENERAL_SMTP_DISABLED);
throw new Exception(Exception::GENERAL_SMTP_DISABLED);
}
$email = \strtolower($email);
@ -329,7 +329,7 @@ App::post('/v1/teams/:teamId/memberships')
$team = $dbForProject->getDocument('teams', $teamId);
if ($team->isEmpty()) {
throw new Exception('Team not found', 404, Exception::TEAM_NOT_FOUND);
throw new Exception(Exception::TEAM_NOT_FOUND);
}
$invitee = $dbForProject->findOne('users', [Query::equal('email', [$email])]); // Get user by email address
@ -341,7 +341,7 @@ App::post('/v1/teams/:teamId/memberships')
$total = $dbForProject->count('users', [], APP_LIMIT_USERS);
if ($total >= $limit) {
throw new Exception('Project registration is restricted. Contact your administrator for more information.', 501, Exception::USER_COUNT_EXCEEDED);
throw new Exception(Exception::USER_COUNT_EXCEEDED, 'Project registration is restricted. Contact your administrator for more information.');
}
}
@ -375,14 +375,14 @@ App::post('/v1/teams/:teamId/memberships')
'search' => implode(' ', [$userId, $email, $name])
])));
} catch (Duplicate $th) {
throw new Exception('Account already exists', 409, Exception::USER_ALREADY_EXISTS);
throw new Exception(Exception::USER_ALREADY_EXISTS);
}
}
$isOwner = Authorization::isRole('team:' . $team->getId() . '/owner');
if (!$isOwner && !$isPrivilegedUser && !$isAppUser) { // Not owner, not admin, not app (server)
throw new Exception('User is not allowed to send invitations for this team', 401, Exception::USER_UNAUTHORIZED);
throw new Exception(Exception::USER_UNAUTHORIZED, 'User is not allowed to send invitations for this team');
}
$secret = Auth::tokenGenerator();
@ -413,7 +413,7 @@ App::post('/v1/teams/:teamId/memberships')
try {
$membership = Authorization::skip(fn() => $dbForProject->createDocument('memberships', $membership));
} catch (Duplicate $th) {
throw new Exception('User is already a member of this team', 409, Exception::TEAM_INVITE_ALREADY_EXISTS);
throw new Exception(Exception::TEAM_INVITE_ALREADY_EXISTS);
}
$team->setAttribute('total', $team->getAttribute('total', 0) + 1);
$team = Authorization::skip(fn() => $dbForProject->updateDocument('teams', $team->getId(), $team));
@ -423,7 +423,7 @@ App::post('/v1/teams/:teamId/memberships')
try {
$membership = $dbForProject->createDocument('memberships', $membership);
} catch (Duplicate $th) {
throw new Exception('User has already been invited or is already a member of this team', 409, Exception::TEAM_INVITE_ALREADY_EXISTS);
throw new Exception(Exception::TEAM_INVITE_ALREADY_EXISTS);
}
}
@ -488,7 +488,7 @@ App::get('/v1/teams/:teamId/memberships')
$team = $dbForProject->getDocument('teams', $teamId);
if ($team->isEmpty()) {
throw new Exception('Team not found', 404, Exception::TEAM_NOT_FOUND);
throw new Exception(Exception::TEAM_NOT_FOUND);
}
$filterQueries = [Query::equal('teamId', [$teamId])];
@ -505,7 +505,7 @@ App::get('/v1/teams/:teamId/memberships')
$cursorDocument = $dbForProject->getDocument('memberships', $cursor);
if ($cursorDocument->isEmpty()) {
throw new Exception("Membership '{$cursor}' for the 'cursor' value not found.", 400, Exception::GENERAL_CURSOR_NOT_FOUND);
throw new Exception(Exception::GENERAL_CURSOR_NOT_FOUND, "Membership '{$cursor}' for the 'cursor' value not found.");
}
$otherQueries[] = $cursorDirection === Database::CURSOR_AFTER ? Query::cursorAfter($cursorDocument) : Query::cursorBefore($cursorDocument);
@ -562,13 +562,13 @@ App::get('/v1/teams/:teamId/memberships/:membershipId')
$team = $dbForProject->getDocument('teams', $teamId);
if ($team->isEmpty()) {
throw new Exception('Team not found', 404, Exception::TEAM_NOT_FOUND);
throw new Exception(Exception::TEAM_NOT_FOUND);
}
$membership = $dbForProject->getDocument('memberships', $membershipId);
if ($membership->isEmpty() || empty($membership->getAttribute('userId'))) {
throw new Exception('Membership not found', 404, Exception::MEMBERSHIP_NOT_FOUND);
throw new Exception(Exception::MEMBERSHIP_NOT_FOUND);
}
$user = $dbForProject->getDocument('users', $membership->getAttribute('userId'));
@ -607,17 +607,17 @@ App::patch('/v1/teams/:teamId/memberships/:membershipId')
$team = $dbForProject->getDocument('teams', $teamId);
if ($team->isEmpty()) {
throw new Exception('Team not found', 404, Exception::TEAM_NOT_FOUND);
throw new Exception(Exception::TEAM_NOT_FOUND);
}
$membership = $dbForProject->getDocument('memberships', $membershipId);
if ($membership->isEmpty()) {
throw new Exception('Membership not found', 404, Exception::MEMBERSHIP_NOT_FOUND);
throw new Exception(Exception::MEMBERSHIP_NOT_FOUND);
}
$profile = $dbForProject->getDocument('users', $membership->getAttribute('userId'));
if ($profile->isEmpty()) {
throw new Exception('User not found', 404, Exception::USER_NOT_FOUND);
throw new Exception(Exception::USER_NOT_FOUND);
}
$isPrivilegedUser = Auth::isPrivilegedUser(Authorization::getRoles());
@ -625,7 +625,7 @@ App::patch('/v1/teams/:teamId/memberships/:membershipId')
$isOwner = Authorization::isRole('team:' . $team->getId() . '/owner');
if (!$isOwner && !$isPrivilegedUser && !$isAppUser) { // Not owner, not admin, not app (server)
throw new Exception('User is not allowed to modify roles', 401, Exception::USER_UNAUTHORIZED);
throw new Exception(Exception::USER_UNAUTHORIZED, 'User is not allowed to modify roles');
}
/**
@ -683,25 +683,25 @@ App::patch('/v1/teams/:teamId/memberships/:membershipId/status')
$membership = $dbForProject->getDocument('memberships', $membershipId);
if ($membership->isEmpty()) {
throw new Exception('Membership not found', 404, Exception::MEMBERSHIP_NOT_FOUND);
throw new Exception(Exception::MEMBERSHIP_NOT_FOUND);
}
if ($membership->getAttribute('teamId') !== $teamId) {
throw new Exception('Team IDs don\'t match', 404, Exception::TEAM_MEMBERSHIP_MISMATCH);
throw new Exception(Exception::TEAM_MEMBERSHIP_MISMATCH);
}
$team = Authorization::skip(fn() => $dbForProject->getDocument('teams', $teamId));
if ($team->isEmpty()) {
throw new Exception('Team not found', 404, Exception::TEAM_NOT_FOUND);
throw new Exception(Exception::TEAM_NOT_FOUND);
}
if (Auth::hash($secret) !== $membership->getAttribute('secret')) {
throw new Exception('Secret key not valid', 401, Exception::TEAM_INVALID_SECRET);
throw new Exception(Exception::TEAM_INVALID_SECRET);
}
if ($userId !== $membership->getAttribute('userId')) {
throw new Exception('Invite does not belong to current user (' . $user->getAttribute('email') . ')', 401, Exception::TEAM_INVITE_MISMATCH);
throw new Exception(Exception::TEAM_INVITE_MISMATCH, 'Invite does not belong to current user (' . $user->getAttribute('email') . ')');
}
if ($user->isEmpty()) {
@ -709,11 +709,11 @@ App::patch('/v1/teams/:teamId/memberships/:membershipId/status')
}
if ($membership->getAttribute('userId') !== $user->getId()) {
throw new Exception('Invite does not belong to current user (' . $user->getAttribute('email') . ')', 401, Exception::TEAM_INVITE_MISMATCH);
throw new Exception(Exception::TEAM_INVITE_MISMATCH, 'Invite does not belong to current user (' . $user->getAttribute('email') . ')');
}
if ($membership->getAttribute('confirm') === true) {
throw new Exception('Membership already confirmed', 409);
throw new Exception(Exception::MEMBERSHIP_ALREADY_CONFIRMED);
}
$membership // Attach user to team
@ -812,23 +812,23 @@ App::delete('/v1/teams/:teamId/memberships/:membershipId')
$membership = $dbForProject->getDocument('memberships', $membershipId);
if ($membership->isEmpty()) {
throw new Exception('Invite not found', 404, Exception::TEAM_INVITE_NOT_FOUND);
throw new Exception(Exception::TEAM_INVITE_NOT_FOUND);
}
if ($membership->getAttribute('teamId') !== $teamId) {
throw new Exception('Team IDs don\'t match', 404);
throw new Exception(Exception::TEAM_MEMBERSHIP_MISMATCH);
}
$user = $dbForProject->getDocument('users', $membership->getAttribute('userId'));
if ($user->isEmpty()) {
throw new Exception('User not found', 404, Exception::USER_NOT_FOUND);
throw new Exception(Exception::USER_NOT_FOUND);
}
$team = $dbForProject->getDocument('teams', $teamId);
if ($team->isEmpty()) {
throw new Exception('Team not found', 404, Exception::TEAM_NOT_FOUND);
throw new Exception(Exception::TEAM_NOT_FOUND);
}
/**
@ -842,9 +842,9 @@ App::delete('/v1/teams/:teamId/memberships/:membershipId')
try {
$dbForProject->deleteDocument('memberships', $membership->getId());
} catch (AuthorizationException $exception) {
throw new Exception('Unauthorized permissions', 401, Exception::USER_UNAUTHORIZED);
throw new Exception(Exception::USER_UNAUTHORIZED);
} catch (\Exception $exception) {
throw new Exception('Failed to remove membership from DB', 500, Exception::GENERAL_SERVER_ERROR);
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Failed to remove membership from DB');
}
$dbForProject->deleteCachedDocument('users', $user->getId());
@ -893,7 +893,7 @@ App::get('/v1/teams/:teamId/logs')
$team = $dbForProject->getDocument('teams', $teamId);
if ($team->isEmpty()) {
throw new Exception('Team not found', 404, Exception::TEAM_NOT_FOUND);
throw new Exception(Exception::TEAM_NOT_FOUND);
}
$audit = new Audit($dbForProject);

View file

@ -81,7 +81,7 @@ App::post('/v1/users')
'search' => implode(' ', [$userId, $email, $name])
]));
} catch (Duplicate $th) {
throw new Exception('Account already exists', 409, Exception::USER_ALREADY_EXISTS);
throw new Exception(Exception::USER_ALREADY_EXISTS);
}
$usage
@ -132,7 +132,7 @@ App::get('/v1/users')
$cursorDocument = $dbForProject->getDocument('users', $cursor);
if ($cursorDocument->isEmpty()) {
throw new Exception("User '{$cursor}' for the 'cursor' value not found.", 400, Exception::GENERAL_CURSOR_NOT_FOUND);
throw new Exception(Exception::GENERAL_CURSOR_NOT_FOUND, "User '{$cursor}' for the 'cursor' value not found.");
}
$queries[] = $cursorDirection === Database::CURSOR_AFTER ? Query::cursorAfter($cursorDocument) : Query::cursorBefore($cursorDocument);
@ -168,7 +168,7 @@ App::get('/v1/users/:userId')
$user = $dbForProject->getDocument('users', $userId);
if ($user->isEmpty()) {
throw new Exception('User not found', 404, Exception::USER_NOT_FOUND);
throw new Exception(Exception::USER_NOT_FOUND);
}
$usage
@ -197,7 +197,7 @@ App::get('/v1/users/:userId/prefs')
$user = $dbForProject->getDocument('users', $userId);
if ($user->isEmpty()) {
throw new Exception('User not found', 404, Exception::USER_NOT_FOUND);
throw new Exception(Exception::USER_NOT_FOUND);
}
$prefs = $user->getAttribute('prefs', new \stdClass());
@ -229,7 +229,7 @@ App::get('/v1/users/:userId/sessions')
$user = $dbForProject->getDocument('users', $userId);
if ($user->isEmpty()) {
throw new Exception('User not found', 404, Exception::USER_NOT_FOUND);
throw new Exception(Exception::USER_NOT_FOUND);
}
$sessions = $user->getAttribute('sessions', []);
@ -272,7 +272,7 @@ App::get('/v1/users/:userId/memberships')
$user = $dbForProject->getDocument('users', $userId);
if ($user->isEmpty()) {
throw new Exception('User not found', 404, Exception::USER_NOT_FOUND);
throw new Exception(Exception::USER_NOT_FOUND);
}
$memberships = array_map(function ($membership) use ($dbForProject, $user) {
@ -316,7 +316,7 @@ App::get('/v1/users/:userId/logs')
$user = $dbForProject->getDocument('users', $userId);
if ($user->isEmpty()) {
throw new Exception('User not found', 404, Exception::USER_NOT_FOUND);
throw new Exception(Exception::USER_NOT_FOUND);
}
$audit = new Audit($dbForProject);
@ -397,7 +397,7 @@ App::patch('/v1/users/:userId/status')
$user = $dbForProject->getDocument('users', $userId);
if ($user->isEmpty()) {
throw new Exception('User not found', 404, Exception::USER_NOT_FOUND);
throw new Exception(Exception::USER_NOT_FOUND);
}
$user = $dbForProject->updateDocument('users', $user->getId(), $user->setAttribute('status', (bool) $status));
@ -436,7 +436,7 @@ App::patch('/v1/users/:userId/verification')
$user = $dbForProject->getDocument('users', $userId);
if ($user->isEmpty()) {
throw new Exception('User not found', 404, Exception::USER_NOT_FOUND);
throw new Exception(Exception::USER_NOT_FOUND);
}
$user = $dbForProject->updateDocument('users', $user->getId(), $user->setAttribute('emailVerification', $emailVerification));
@ -475,7 +475,7 @@ App::patch('/v1/users/:userId/verification/phone')
$user = $dbForProject->getDocument('users', $userId);
if ($user->isEmpty()) {
throw new Exception('User not found', 404, Exception::USER_NOT_FOUND);
throw new Exception(Exception::USER_NOT_FOUND);
}
$user = $dbForProject->updateDocument('users', $user->getId(), $user->setAttribute('phoneVerification', $phoneVerification));
@ -514,7 +514,7 @@ App::patch('/v1/users/:userId/name')
$user = $dbForProject->getDocument('users', $userId);
if ($user->isEmpty()) {
throw new Exception('User not found', 404, Exception::USER_NOT_FOUND);
throw new Exception(Exception::USER_NOT_FOUND);
}
$user
@ -558,7 +558,7 @@ App::patch('/v1/users/:userId/password')
$user = $dbForProject->getDocument('users', $userId);
if ($user->isEmpty()) {
throw new Exception('User not found', 404, Exception::USER_NOT_FOUND);
throw new Exception(Exception::USER_NOT_FOUND);
}
$user
@ -601,7 +601,7 @@ App::patch('/v1/users/:userId/email')
$user = $dbForProject->getDocument('users', $userId);
if ($user->isEmpty()) {
throw new Exception('User not found', 404, Exception::USER_NOT_FOUND);
throw new Exception(Exception::USER_NOT_FOUND);
}
$email = \strtolower($email);
@ -615,7 +615,7 @@ App::patch('/v1/users/:userId/email')
try {
$user = $dbForProject->updateDocument('users', $user->getId(), $user);
} catch (Duplicate $th) {
throw new Exception('Email already exists', 409, Exception::USER_EMAIL_ALREADY_EXISTS);
throw new Exception(Exception::USER_EMAIL_ALREADY_EXISTS);
}
@ -653,7 +653,7 @@ App::patch('/v1/users/:userId/phone')
$user = $dbForProject->getDocument('users', $userId);
if ($user->isEmpty()) {
throw new Exception('User not found', 404, Exception::USER_NOT_FOUND);
throw new Exception(Exception::USER_NOT_FOUND);
}
$user
@ -665,7 +665,7 @@ App::patch('/v1/users/:userId/phone')
try {
$user = $dbForProject->updateDocument('users', $user->getId(), $user);
} catch (Duplicate $th) {
throw new Exception('Email already exists', 409, Exception::USER_EMAIL_ALREADY_EXISTS);
throw new Exception(Exception::USER_EMAIL_ALREADY_EXISTS);
}
@ -703,7 +703,7 @@ App::patch('/v1/users/:userId/prefs')
$user = $dbForProject->getDocument('users', $userId);
if ($user->isEmpty()) {
throw new Exception('User not found', 404, Exception::USER_NOT_FOUND);
throw new Exception(Exception::USER_NOT_FOUND);
}
$user = $dbForProject->updateDocument('users', $user->getId(), $user->setAttribute('prefs', $prefs));
@ -741,13 +741,13 @@ App::delete('/v1/users/:userId/sessions/:sessionId')
$user = $dbForProject->getDocument('users', $userId);
if ($user->isEmpty()) {
throw new Exception('User not found', 404, Exception::USER_NOT_FOUND);
throw new Exception(Exception::USER_NOT_FOUND);
}
$session = $dbForProject->getDocument('sessions', $sessionId);
if ($session->isEmpty()) {
throw new Exception('Session not found', 404, Exception::USER_SESSION_NOT_FOUND);
throw new Exception(Exception::USER_SESSION_NOT_FOUND);
}
$dbForProject->deleteDocument('sessions', $session->getId());
@ -788,7 +788,7 @@ App::delete('/v1/users/:userId/sessions')
$user = $dbForProject->getDocument('users', $userId);
if ($user->isEmpty()) {
throw new Exception('User not found', 404, Exception::USER_NOT_FOUND);
throw new Exception(Exception::USER_NOT_FOUND);
}
$sessions = $user->getAttribute('sessions', []);
@ -835,7 +835,7 @@ App::delete('/v1/users/:userId')
$user = $dbForProject->getDocument('users', $userId);
if ($user->isEmpty()) {
throw new Exception('User not found', 404, Exception::USER_NOT_FOUND);
throw new Exception(Exception::USER_NOT_FOUND);
}
// clone user object to send to workers

View file

@ -132,11 +132,11 @@ App::init()
}
if ($project->isEmpty()) {
throw new AppwriteException('Project not found', 404, AppwriteException::PROJECT_NOT_FOUND);
throw new AppwriteException(AppwriteException::PROJECT_NOT_FOUND);
}
if (!empty($route->getLabel('sdk.auth', [])) && $project->isEmpty() && ($route->getLabel('scope', '') !== 'public')) {
throw new AppwriteException('Missing or unknown project ID', 400, AppwriteException::PROJECT_UNKNOWN);
throw new AppwriteException(AppwriteException::PROJECT_UNKNOWN);
}
$referrer = $request->getReferer();
@ -207,7 +207,7 @@ App::init()
if (App::getEnv('_APP_OPTIONS_FORCE_HTTPS', 'disabled') === 'enabled') { // Force HTTPS
if ($request->getProtocol() !== 'https') {
if ($request->getMethod() !== Request::METHOD_GET) {
throw new AppwriteException('Method unsupported over HTTP.', 500, AppwriteException::GENERAL_PROTOCOL_UNSUPPORTED);
throw new AppwriteException(AppwriteException::GENERAL_PROTOCOL_UNSUPPORTED, 'Method unsupported over HTTP.');
}
return $response->redirect('https://' . $request->getHostname() . $request->getURI());
@ -240,7 +240,7 @@ App::init()
&& $route->getLabel('origin', false) !== '*'
&& empty($request->getHeader('x-appwrite-key', ''))
) {
throw new AppwriteException($originValidator->getDescription(), 403, AppwriteException::GENERAL_UNKNOWN_ORIGIN);
throw new AppwriteException(AppwriteException::GENERAL_UNKNOWN_ORIGIN, $originValidator->getDescription());
}
/*
@ -296,7 +296,7 @@ App::init()
$expire = $key->getAttribute('expire');
if (!empty($expire) && $expire < DateTime::now()) {
throw new AppwriteException('Project key expired', 401, AppwriteException:: PROJECT_KEY_EXPIRED);
throw new AppwriteException(AppwriteException:: PROJECT_KEY_EXPIRED);
}
Authorization::setRole(Auth::USER_ROLE_APPS);
@ -317,24 +317,24 @@ App::init()
&& !$project->getAttribute('services', [])[$service]
&& !(Auth::isPrivilegedUser(Authorization::getRoles()) || Auth::isAppUser(Authorization::getRoles()))
) {
throw new AppwriteException('Service is disabled', 503, AppwriteException::GENERAL_SERVICE_DISABLED);
throw new AppwriteException(AppwriteException::GENERAL_SERVICE_DISABLED);
}
}
if (!\in_array($scope, $scopes)) {
if ($project->isEmpty()) { // Check if permission is denied because project is missing
throw new AppwriteException('Project not found', 404, AppwriteException::PROJECT_NOT_FOUND);
throw new AppwriteException(AppwriteException::PROJECT_NOT_FOUND);
}
throw new AppwriteException($user->getAttribute('email', 'User') . ' (role: ' . \strtolower($roles[$role]['label']) . ') missing scope (' . $scope . ')', 401, AppwriteException::GENERAL_UNAUTHORIZED_SCOPE);
throw new AppwriteException(AppwriteException::GENERAL_UNAUTHORIZED_SCOPE, $user->getAttribute('email', 'User') . ' (role: ' . \strtolower($roles[$role]['label']) . ') missing scope (' . $scope . ')');
}
if (false === $user->getAttribute('status')) { // Account is blocked
throw new AppwriteException('Invalid credentials. User is blocked', 401, AppwriteException::USER_BLOCKED);
throw new AppwriteException(AppwriteException::USER_BLOCKED);
}
if ($user->getAttribute('reset')) {
throw new AppwriteException('Password reset is required', 412, AppwriteException::USER_PASSWORD_RESET_REQUIRED);
throw new AppwriteException(AppwriteException::USER_PASSWORD_RESET_REQUIRED);
}
});
@ -446,7 +446,7 @@ App::error()
/** Handle Utopia Errors */
if ($error instanceof Utopia\Exception) {
$error = new AppwriteException($message, $code, AppwriteException::GENERAL_UNKNOWN, $error);
$error = new AppwriteException(AppwriteException::GENERAL_UNKNOWN, $message, $code, $error);
switch ($code) {
case 400:
$error->setType(AppwriteException::GENERAL_ARGUMENT_INVALID);
@ -459,7 +459,7 @@ App::error()
/** Wrap all exceptions inside Appwrite\Extend\Exception */
if (!($error instanceof AppwriteException)) {
$error = new AppwriteException($message, $code, AppwriteException::GENERAL_UNKNOWN, $error);
$error = new AppwriteException(AppwriteException::GENERAL_UNKNOWN, $message, $code, $error);
}
switch ($code) { // Don't show 500 errors!
@ -602,32 +602,32 @@ App::get('/.well-known/acme-challenge')
]);
if (!$validator->isValid($token) || \count($uriChunks) !== 4) {
throw new AppwriteException('Invalid challenge token.', 400);
throw new AppwriteException(AppwriteException::GENERAL_ARGUMENT_INVALID, 'Invalid challenge token.');
}
$base = \realpath(APP_STORAGE_CERTIFICATES);
$absolute = \realpath($base . '/.well-known/acme-challenge/' . $token);
if (!$base) {
throw new AppwriteException('Storage error', 500, AppwriteException::GENERAL_SERVER_ERROR);
throw new AppwriteException(AppwriteException::GENERAL_SERVER_ERROR, 'Storage error');
}
if (!$absolute) {
throw new AppwriteException('Unknown path', 404);
throw new AppwriteException(AppwriteException::GENERAL_ROUTE_NOT_FOUND, 'Unknown path');
}
if (!\substr($absolute, 0, \strlen($base)) === $base) {
throw new AppwriteException('Invalid path', 401);
throw new AppwriteException(AppwriteException::GENERAL_UNAUTHORIZED_SCOPE, 'Invalid path');
}
if (!\file_exists($absolute)) {
throw new AppwriteException('Unknown path', 404);
throw new AppwriteException(AppwriteException::GENERAL_ROUTE_NOT_FOUND, 'Unknown path');
}
$content = @\file_get_contents($absolute);
if (!$content) {
throw new AppwriteException('Failed to get contents', 500, AppwriteException::GENERAL_SERVER_ERROR);
throw new AppwriteException(AppwriteException::GENERAL_SERVER_ERROR, 'Failed to get contents');
}
$response->text($content);

View file

@ -253,31 +253,31 @@ App::post('/v1/mock/tests/general/upload')
$file['size'] = (\is_array($file['size'])) ? $file['size'][0] : $file['size'];
if (is_null($start) || is_null($end) || is_null($size)) {
throw new Exception('Invalid content-range header', 400, Exception::GENERAL_MOCK);
throw new Exception(Exception::GENERAL_MOCK, 'Invalid content-range header');
}
if ($start > $end || $end > $size) {
throw new Exception('Invalid content-range header', 400, Exception::GENERAL_MOCK);
throw new Exception(Exception::GENERAL_MOCK, 'Invalid content-range header');
}
if ($start === 0 && !empty($id)) {
throw new Exception('First chunked request cannot have id header', 400, Exception::GENERAL_MOCK);
throw new Exception(Exception::GENERAL_MOCK, 'First chunked request cannot have id header');
}
if ($start !== 0 && $id !== 'newfileid') {
throw new Exception('All chunked request must have id header (except first)', 400, Exception::GENERAL_MOCK);
throw new Exception(Exception::GENERAL_MOCK, 'All chunked request must have id header (except first)');
}
if ($end !== $size && $end - $start + 1 !== $chunkSize) {
throw new Exception('Chunk size must be 5MB (except last chunk)', 400, Exception::GENERAL_MOCK);
throw new Exception(Exception::GENERAL_MOCK, 'Chunk size must be 5MB (except last chunk)');
}
if ($end !== $size && $file['size'] !== $chunkSize) {
throw new Exception('Wrong chunk size', 400, Exception::GENERAL_MOCK);
throw new Exception(Exception::GENERAL_MOCK, 'Wrong chunk size');
}
if ($file['size'] > $chunkSize) {
throw new Exception('Chunk size must be 5MB or less', 400, Exception::GENERAL_MOCK);
throw new Exception(Exception::GENERAL_MOCK, 'Chunk size must be 5MB or less');
}
if ($end !== $size) {
@ -293,15 +293,15 @@ App::post('/v1/mock/tests/general/upload')
$file['size'] = (\is_array($file['size'])) ? $file['size'][0] : $file['size'];
if ($file['name'] !== 'file.png') {
throw new Exception('Wrong file name', 400, Exception::GENERAL_MOCK);
throw new Exception(Exception::GENERAL_MOCK, 'Wrong file name');
}
if ($file['size'] !== 38756) {
throw new Exception('Wrong file size', 400, Exception::GENERAL_MOCK);
throw new Exception(Exception::GENERAL_MOCK, 'Wrong file size');
}
if (\md5(\file_get_contents($file['tmp_name'])) !== 'd80e7e6999a3eb2ae0d631a96fe135a4') {
throw new Exception('Wrong file uploaded', 400, Exception::GENERAL_MOCK);
throw new Exception(Exception::GENERAL_MOCK, 'Wrong file uploaded');
}
}
});
@ -374,7 +374,7 @@ App::get('/v1/mock/tests/general/get-cookie')
->action(function (Request $request) {
if ($request->getCookie('cookieName', '') !== 'cookieValue') {
throw new Exception('Missing cookie value', 400, Exception::GENERAL_MOCK);
throw new Exception(Exception::GENERAL_MOCK, 'Missing cookie value');
}
});
@ -408,7 +408,7 @@ App::get('/v1/mock/tests/general/400-error')
->label('sdk.response.model', Response::MODEL_ERROR)
->label('sdk.mock', true)
->action(function () {
throw new Exception('Mock 400 error', 400, Exception::GENERAL_MOCK);
throw new Exception(Exception::GENERAL_MOCK, 'Mock 400 error');
});
App::get('/v1/mock/tests/general/500-error')
@ -424,7 +424,7 @@ App::get('/v1/mock/tests/general/500-error')
->label('sdk.response.model', Response::MODEL_ERROR)
->label('sdk.mock', true)
->action(function () {
throw new Exception('Mock 500 error', 500, Exception::GENERAL_MOCK);
throw new Exception(Exception::GENERAL_MOCK, 'Mock 500 error', 500);
});
App::get('/v1/mock/tests/general/502-error')
@ -480,11 +480,11 @@ App::get('/v1/mock/tests/general/oauth2/token')
->action(function (string $client_id, string $client_secret, string $grantType, string $redirectURI, string $code, string $refreshToken, Response $response) {
if ($client_id != '1') {
throw new Exception('Invalid client ID', 400, Exception::GENERAL_MOCK);
throw new Exception(Exception::GENERAL_MOCK, 'Invalid client ID');
}
if ($client_secret != '123456') {
throw new Exception('Invalid client secret', 400, Exception::GENERAL_MOCK);
throw new Exception(Exception::GENERAL_MOCK, 'Invalid client secret');
}
$responseJson = [
@ -495,18 +495,18 @@ App::get('/v1/mock/tests/general/oauth2/token')
if ($grantType === 'authorization_code') {
if ($code !== 'abcdef') {
throw new Exception('Invalid token', 400, Exception::GENERAL_MOCK);
throw new Exception(Exception::GENERAL_MOCK, 'Invalid token');
}
$response->json($responseJson);
} elseif ($grantType === 'refresh_token') {
if ($refreshToken !== 'tuvwxyz') {
throw new Exception('Invalid refresh token', 400, Exception::GENERAL_MOCK);
throw new Exception(Exception::GENERAL_MOCK, 'Invalid refresh token');
}
$response->json($responseJson);
} else {
throw new Exception('Invalid grant type', 400, Exception::GENERAL_MOCK);
throw new Exception(Exception::GENERAL_MOCK, 'Invalid grant type');
}
});
@ -520,7 +520,7 @@ App::get('/v1/mock/tests/general/oauth2/user')
->action(function (string $token, Response $response) {
if ($token != '123456') {
throw new Exception('Invalid token', 400, Exception::GENERAL_MOCK);
throw new Exception(Exception::GENERAL_MOCK, 'Invalid token');
}
$response->json([
@ -571,7 +571,7 @@ App::shutdown()
$tests = (\file_exists($path)) ? \json_decode(\file_get_contents($path), true) : [];
if (!\is_array($tests)) {
throw new Exception('Failed to read results', 500, Exception::GENERAL_MOCK);
throw new Exception(Exception::GENERAL_MOCK, 'Failed to read results', 500);
}
$result[$route->getMethod() . ':' . $route->getPath()] = true;
@ -579,7 +579,7 @@ App::shutdown()
$tests = \array_merge($tests, $result);
if (!\file_put_contents($path, \json_encode($tests), LOCK_EX)) {
throw new Exception('Failed to save results', 500, Exception::GENERAL_MOCK);
throw new Exception(Exception::GENERAL_MOCK, 'Failed to save results', 500);
}
$response->dynamic(new Document(['result' => $route->getMethod() . ':' . $route->getPath() . ':passed']), Response::MODEL_MOCK);

View file

@ -39,7 +39,7 @@ App::init()
$route = $utopia->match($request);
if ($project->isEmpty() && $route->getLabel('abuse-limit', 0) > 0) { // Abuse limit requires an active project scope
throw new Exception('Missing or unknown project ID', 400, Exception::PROJECT_UNKNOWN);
throw new Exception(Exception::PROJECT_UNKNOWN);
}
/*
@ -92,7 +92,7 @@ App::init()
&& $abuse->check()) // Abuse is not disabled
&& (!$isAppUser && !$isPrivilegedUser)
) { // User is not an admin or API key
throw new Exception('Too many requests', 429, Exception::GENERAL_RATE_LIMIT_EXCEEDED);
throw new Exception(Exception::GENERAL_RATE_LIMIT_EXCEEDED);
}
}
@ -154,36 +154,37 @@ App::init()
switch ($route->getLabel('auth.type', '')) {
case 'emailPassword':
if (($auths['emailPassword'] ?? true) === false) {
throw new Exception('Email / Password authentication is disabled for this project', 501, Exception::USER_AUTH_METHOD_UNSUPPORTED);
throw new Exception(Exception::USER_AUTH_METHOD_UNSUPPORTED, 'Email / Password authentication is disabled for this project');
}
break;
case 'magic-url':
if ($project->getAttribute('usersAuthMagicURL', true) === false) {
throw new Exception('Magic URL authentication is disabled for this project', 501, Exception::USER_AUTH_METHOD_UNSUPPORTED);
throw new Exception(Exception::USER_AUTH_METHOD_UNSUPPORTED, 'Magic URL authentication is disabled for this project');
}
break;
case 'anonymous':
if (($auths['anonymous'] ?? true) === false) {
throw new Exception('Anonymous authentication is disabled for this project', 501, Exception::USER_AUTH_METHOD_UNSUPPORTED);
throw new Exception(Exception::USER_AUTH_METHOD_UNSUPPORTED, 'Anonymous authentication is disabled for this project');
}
break;
case 'invites':
if (($auths['invites'] ?? true) === false) {
throw new Exception('Invites authentication is disabled for this project', 501, Exception::USER_AUTH_METHOD_UNSUPPORTED);
throw new Exception(Exception::USER_AUTH_METHOD_UNSUPPORTED, 'Invites authentication is disabled for this project');
}
break;
case 'jwt':
if (($auths['JWT'] ?? true) === false) {
throw new Exception('JWT authentication is disabled for this project', 501, Exception::USER_AUTH_METHOD_UNSUPPORTED);
throw new Exception(Exception::USER_AUTH_METHOD_UNSUPPORTED, 'JWT authentication is disabled for this project');
}
break;
default:
throw new Exception('Unsupported authentication route', 501, Exception::USER_AUTH_METHOD_UNSUPPORTED);
throw new Exception(Exception::USER_AUTH_METHOD_UNSUPPORTED, 'Unsupported authentication route');
break;
}
});

View file

@ -595,9 +595,9 @@ App::get('/console/version')
if ($version && isset($version['version'])) {
return $response->json(['version' => $version['version']]);
} else {
throw new Exception('Failed to check for a newer version', 500, Exception::GENERAL_SERVER_ERROR);
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Failed to check for a newer version');
}
} catch (\Throwable $th) {
throw new Exception('Failed to check for a newer version', 500, Exception::GENERAL_SERVER_ERROR);
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Failed to check for a newer version');
}
});

View file

@ -464,7 +464,7 @@ $register->set('logger', function () {
}
if (!Logger::hasProvider($providerName)) {
throw new Exception("Logging provider not supported. Logging disabled.", 500, Exception::GENERAL_SERVER_ERROR);
throw new Exception(Exception::GENERAL_SERVER_ERROR, "Logging provider not supported. Logging is disabled");
}
$classname = '\\Utopia\\Logger\\Adapter\\' . \ucfirst($providerName);
@ -834,7 +834,7 @@ App::setResource('user', function ($mode, $project, $console, $request, $respons
try {
$payload = $jwt->decode($authJWT);
} catch (JWTException $error) {
throw new Exception('Failed to verify JWT. ' . $error->getMessage(), 401, Exception::USER_JWT_INVALID);
throw new Exception(Exception::USER_JWT_INVALID, 'Failed to verify JWT. ' . $error->getMessage());
}
$jwtUserId = $payload['userId'] ?? '';

View file

@ -2,6 +2,8 @@
namespace Appwrite\Extend;
use Utopia\Config\Config;
class Exception extends \Exception
{
/**
@ -70,6 +72,7 @@ class Exception extends \Exception
public const USER_AUTH_METHOD_UNSUPPORTED = 'user_auth_method_unsupported';
public const USER_PHONE_ALREADY_EXISTS = 'user_phone_already_exists';
public const USER_PHONE_NOT_FOUND = 'user_phone_not_found';
public const USER_MISSING_ID = 'user_missing_id';
/** Teams */
public const TEAM_NOT_FOUND = 'team_not_found';
@ -81,6 +84,7 @@ class Exception extends \Exception
/** Membership */
public const MEMBERSHIP_NOT_FOUND = 'membership_not_found';
public const MEMBERSHIP_ALREADY_CONFIRMED = 'membership_already_confirmed';
/** Avatars */
public const AVATAR_SET_NOT_FOUND = 'avatar_set_not_found';
@ -117,8 +121,8 @@ class Exception extends \Exception
public const EXECUTION_NOT_FOUND = 'execution_not_found';
/** Databases */
public const DATABASE_NOT_FOUND = 'database_not_found';
public const DATABASE_ALREADY_EXISTS = 'database_already_exists';
public const DATABASE_NOT_FOUND = 'database_not_found';
public const DATABASE_ALREADY_EXISTS = 'database_already_exists';
/** Collections */
public const COLLECTION_NOT_FOUND = 'collection_not_found';
@ -153,7 +157,6 @@ class Exception extends \Exception
public const PROJECT_PROVIDER_UNSUPPORTED = 'project_provider_unsupported';
public const PROJECT_INVALID_SUCCESS_URL = 'project_invalid_success_url';
public const PROJECT_INVALID_FAILURE_URL = 'project_invalid_failure_url';
public const PROJECT_MISSING_USER_ID = 'project_missing_user_id';
public const PROJECT_RESERVED_PROJECT = 'project_reserved_project';
public const PROJECT_KEY_EXPIRED = 'project_key_expired';
@ -171,14 +174,22 @@ class Exception extends \Exception
public const DOMAIN_ALREADY_EXISTS = 'domain_already_exists';
public const DOMAIN_VERIFICATION_FAILED = 'domain_verification_failed';
protected $type = '';
private $type = '';
public function __construct(string $message, int $code = 0, string $type = Exception::GENERAL_UNKNOWN, \Throwable $previous = null)
public function __construct(string $type = Exception::GENERAL_UNKNOWN, string $message = null, int $code = null, \Throwable $previous = null)
{
$this->errors = Config::getParam('errors');
$this->type = $type;
parent::__construct($message, $code, $previous);
if (isset($this->errors[$type])) {
$this->code = $this->errors[$type]['code'];
$this->message = $this->errors[$type]['description'];
}
$this->message = $message ?? $this->message;
$this->code = $code ?? $this->code;
parent::__construct($this->message, $this->code, $previous);
}
/**