appwrite/app/controllers/api/projects.php

188 lines
7.5 KiB
PHP
Raw Normal View History

2019-12-14 19:33:29 +00:00
<?php
2024-02-11 14:51:19 +00:00
use Appwrite\Auth\Validator\MockNumber;
2023-08-23 02:04:36 +00:00
use Appwrite\Extend\Exception;
2025-01-17 04:31:39 +00:00
use Appwrite\SDK\AuthType;
use Appwrite\SDK\Method;
use Appwrite\SDK\Response as SDKResponse;
2020-08-14 21:56:50 +00:00
use Appwrite\Utopia\Response;
2021-06-07 05:17:29 +00:00
use Utopia\Config\Config;
2021-08-16 13:27:15 +00:00
use Utopia\Database\Database;
2021-05-15 22:41:42 +00:00
use Utopia\Database\Document;
use Utopia\Database\Validator\UID;
use Utopia\Http\Http;
2024-04-01 11:08:46 +00:00
use Utopia\System\System;
2024-10-08 07:54:40 +00:00
use Utopia\Validator\ArrayList;
use Utopia\Validator\Boolean;
use Utopia\Validator\Nullable;
2024-10-08 07:54:40 +00:00
use Utopia\Validator\Text;
use Utopia\Validator\WhiteList;
2026-02-04 05:30:22 +00:00
Http::init()
2022-07-22 06:00:42 +00:00
->groups(['projects'])
2022-08-02 01:10:48 +00:00
->inject('project')
2022-07-22 06:00:42 +00:00
->action(function (Document $project) {
if ($project->getId() !== 'console') {
throw new Exception(Exception::GENERAL_ACCESS_FORBIDDEN);
2022-07-22 06:00:42 +00:00
}
});
2021-07-31 21:36:18 +00:00
2026-02-04 05:30:22 +00:00
Http::get('/v1/projects/:projectId')
2023-08-01 15:26:48 +00:00
->desc('Get project')
2020-06-25 18:32:12 +00:00
->groups(['api', 'projects'])
2019-12-14 19:33:29 +00:00
->label('scope', 'projects.read')
2025-01-17 04:31:39 +00:00
->label('sdk', new Method(
namespace: 'projects',
2025-03-31 05:48:17 +00:00
group: 'projects',
2025-01-17 04:31:39 +00:00
name: 'get',
description: '/docs/references/projects/get.md',
2025-01-17 04:31:39 +00:00
auth: [AuthType::ADMIN],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_PROJECT,
)
]
))
2025-10-21 02:04:08 +00:00
->param('projectId', '', fn (Database $dbForPlatform) => new UID($dbForPlatform->getAdapter()->getMaxUIDLength()), 'Project unique ID.', false, ['dbForPlatform'])
2020-12-26 16:33:36 +00:00
->inject('response')
->inject('dbForPlatform')
->action(function (string $projectId, Response $response, Database $dbForPlatform) {
2024-10-08 07:54:40 +00:00
$project = $dbForPlatform->getDocument('projects', $projectId);
2019-12-14 19:33:29 +00:00
2021-05-15 22:41:42 +00:00
if ($project->isEmpty()) {
throw new Exception(Exception::PROJECT_NOT_FOUND);
2020-06-30 15:46:42 +00:00
}
2019-12-14 19:33:29 +00:00
2021-07-25 14:47:18 +00:00
$response->dynamic($project, Response::MODEL_PROJECT);
2020-12-26 16:33:36 +00:00
});
2019-12-14 19:33:29 +00:00
2026-02-04 05:30:22 +00:00
Http::patch('/v1/projects/:projectId/service/all')
->desc('Update all service status')
->groups(['api', 'projects'])
->label('scope', 'projects.write')
->action(function () {
2026-04-09 14:08:11 +00:00
throw new Exception(Exception::GENERAL_NOT_IMPLEMENTED, 'Bulk API no longer exists for services. Please change status individually.');
2024-03-04 22:12:54 +00:00
});
2026-02-04 05:30:22 +00:00
Http::patch('/v1/projects/:projectId/api/all')
2024-03-04 22:28:42 +00:00
->desc('Update all API status')
->groups(['api', 'projects'])
->label('scope', 'projects.write')
->action(function () {
2026-04-09 14:08:11 +00:00
throw new Exception(Exception::GENERAL_NOT_IMPLEMENTED, 'Bulk API no longer exists for services. Please change status individually.');
2024-03-04 22:28:42 +00:00
});
2026-02-04 05:30:22 +00:00
Http::patch('/v1/projects/:projectId/oauth2')
2023-08-01 15:26:48 +00:00
->desc('Update project OAuth2')
2020-06-25 18:32:12 +00:00
->groups(['api', 'projects'])
2019-12-14 19:33:29 +00:00
->label('scope', 'projects.write')
2025-01-17 04:31:39 +00:00
->label('sdk', new Method(
namespace: 'projects',
2025-03-31 05:48:17 +00:00
group: 'auth',
2025-01-17 04:31:39 +00:00
name: 'updateOAuth2',
description: '/docs/references/projects/update-oauth2.md',
2025-01-17 04:31:39 +00:00
auth: [AuthType::ADMIN],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_PROJECT,
)
]
))
2025-10-21 02:04:08 +00:00
->param('projectId', '', fn (Database $dbForPlatform) => new UID($dbForPlatform->getAdapter()->getMaxUIDLength()), 'Project unique ID.', false, ['dbForPlatform'])
2023-10-25 17:33:23 +00:00
->param('provider', '', new WhiteList(\array_keys(Config::getParam('oAuthProviders')), true), 'Provider Name')
->param('appId', null, new Nullable(new Text(256)), 'Provider app ID. Max length: 256 chars.', true)
->param('secret', null, new Nullable(new text(512)), 'Provider secret key. Max length: 512 chars.', true)
->param('enabled', null, new Nullable(new Boolean()), 'Provider status. Set to \'false\' to disable new session creation.', true)
2020-12-26 16:33:36 +00:00
->inject('response')
->inject('dbForPlatform')
->action(function (string $projectId, string $provider, ?string $appId, ?string $secret, ?bool $enabled, Response $response, Database $dbForPlatform) {
2024-10-08 07:54:40 +00:00
$project = $dbForPlatform->getDocument('projects', $projectId);
2019-12-14 19:33:29 +00:00
2021-05-15 22:41:42 +00:00
if ($project->isEmpty()) {
throw new Exception(Exception::PROJECT_NOT_FOUND);
2020-06-30 15:46:42 +00:00
}
2019-12-14 19:33:29 +00:00
2023-10-25 17:33:23 +00:00
$providers = $project->getAttribute('oAuthProviders', []);
2022-08-19 09:43:03 +00:00
if ($appId !== null) {
$providers[$provider . 'Appid'] = $appId;
}
2022-08-19 09:43:03 +00:00
if ($secret !== null) {
$providers[$provider . 'Secret'] = $secret;
}
2022-08-19 09:43:03 +00:00
if ($enabled !== null) {
$providers[$provider . 'Enabled'] = $enabled;
}
2021-08-06 10:35:50 +00:00
$project = $dbForPlatform->updateDocument('projects', $project->getId(), $project->setAttribute('oAuthProviders', $providers));
2020-06-30 15:46:42 +00:00
2024-11-01 11:38:56 +00:00
$response->dynamic($project, Response::MODEL_PROJECT);
});
2026-04-22 09:30:39 +00:00
// Backwards compatibility
2026-02-04 05:30:22 +00:00
Http::patch('/v1/projects/:projectId/auth/mock-numbers')
2024-02-11 14:51:19 +00:00
->desc('Update the mock numbers for the project')
->groups(['api', 'projects'])
->label('scope', 'projects.write')
2025-10-21 02:04:08 +00:00
->param('projectId', '', fn (Database $dbForPlatform) => new UID($dbForPlatform->getAdapter()->getMaxUIDLength()), 'Project unique ID.', false, ['dbForPlatform'])
2024-02-11 14:51:19 +00:00
->param('numbers', '', new ArrayList(new MockNumber(), 10), 'An array of mock numbers and their corresponding verification codes (OTPs). Each number should be a valid E.164 formatted phone number. Maximum of 10 numbers are allowed.')
->inject('response')
->inject('dbForPlatform')
->action(function (string $projectId, array $numbers, Response $response, Database $dbForPlatform) {
2024-02-11 14:51:19 +00:00
2024-07-21 19:30:06 +00:00
$uniqueNumbers = [];
foreach ($numbers as $number) {
2024-07-21 19:45:39 +00:00
if (isset($uniqueNumbers[$number['phone']])) {
throw new Exception(Exception::GENERAL_BAD_REQUEST, 'Duplicate phone numbers are not allowed.');
2024-07-21 19:30:06 +00:00
}
2024-07-21 19:45:39 +00:00
$uniqueNumbers[$number['phone']] = $number['otp'];
2024-07-21 19:30:06 +00:00
}
2024-07-22 09:08:02 +00:00
$project = $dbForPlatform->getDocument('projects', $projectId);
2024-02-11 14:51:19 +00:00
if ($project->isEmpty()) {
throw new Exception(Exception::PROJECT_NOT_FOUND);
}
$auths = $project->getAttribute('auths', []);
$auths['mockNumbers'] = $numbers;
$project = $dbForPlatform->updateDocument('projects', $project->getId(), $project->setAttribute('auths', $auths));
2024-02-11 14:51:19 +00:00
$response->dynamic($project, Response::MODEL_PROJECT);
});
2026-04-22 07:59:00 +00:00
// Backwards compatibility
Http::delete('/v1/projects/:projectId/templates/email')
->alias('/v1/projects/:projectId/templates/email/:type/:locale')
->desc('Delete custom email template')
->groups(['api', 'projects'])
->label('scope', 'projects.write')
->param('projectId', '', fn (Database $dbForPlatform) => new UID($dbForPlatform->getAdapter()->getMaxUIDLength()), 'Project unique ID.', false, ['dbForPlatform'])
->param('type', '', new WhiteList(Config::getParam('locale-templates')['email'] ?? [], true), 'Template type')
->param('locale', '', fn ($localeCodes) => new WhiteList($localeCodes), 'Template locale', true, ['localeCodes'])
->inject('response')
->inject('dbForPlatform')
->action(function (string $projectId, string $type, string $locale, Response $response, Database $dbForPlatform) {
$locale = $locale ?: System::getEnv('_APP_LOCALE', 'en');
$project = $dbForPlatform->getDocument('projects', $projectId);
if ($project->isEmpty()) {
throw new Exception(Exception::PROJECT_NOT_FOUND);
}
$templates = $project->getAttribute('templates', []);
unset($templates['email.' . $type . '-' . $locale]);
$project = $dbForPlatform->updateDocument('projects', $project->getId(), $project->setAttribute('templates', $templates));
$response->noContent();
});