Refactor console availability endpoint

This commit is contained in:
Khushboo Verma
2025-02-12 16:10:44 +05:30
parent b46eebb23c
commit aae3b40d16
2 changed files with 60 additions and 23 deletions
@@ -9,10 +9,12 @@ use Appwrite\SDK\Method;
use Appwrite\SDK\Response as SDKResponse;
use Appwrite\Utopia\Response;
use Utopia\Database\Database;
use Utopia\Database\Query;
use Utopia\Database\Validator\Authorization;
use Utopia\Database\Validator\UID;
use Utopia\Platform\Action;
use Utopia\Platform\Scope\HTTP;
use Utopia\Validator\Domain;
use Utopia\Validator\Text;
use Utopia\Validator\WhiteList;
class Get extends Action
@@ -21,20 +23,20 @@ class Get extends Action
public static function getName()
{
return 'getResourceAvailability';
return 'getResources';
}
public function __construct()
{
$this
->setHttpMethod(Action::HTTP_REQUEST_METHOD_GET)
->setHttpPath('v1/console/resources/:resourceId')
->setHttpPath('v1/console/resources')
->desc('Check resource ID availability')
->groups(['api', 'projects'])
->label('scope', 'rules.read')
->label('sdk', new Method(
namespace: 'console',
name: 'getResourceAvailability',
name: 'getResource',
description: <<<EOT
Check if a resource ID is available.
EOT,
@@ -50,21 +52,33 @@ class Get extends Action
->label('abuse-limit', 10)
->label('abuse-key', 'userId:{userId}, url:{url}')
->label('abuse-time', 60)
->param('resourceId', '', new UID(), 'ID of the resource.')
->param('value', '', new Text(256), 'Resource value.')
->param('type', '', new WhiteList(['rules']), 'Resource type.')
->inject('response')
->inject('dbForPlatform')
->callback([$this, 'action']);
}
public function action(string $resourceId, string $type, Response $response, Database $dbForPlatform)
public function action(string $value, string $type, Response $response, Database $dbForPlatform)
{
$document = Authorization::skip(fn () => $dbForPlatform->getDocument('rules', $resourceId));
if ($type == 'rules') {
$validator = new Domain($value);
if (!$document->isEmpty()) {
throw new Exception(Exception::RESOURCE_ALREADY_EXISTS);
if (!$validator->isValid($value)) {
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, $validator->getDescription());
}
$document = Authorization::skip(fn () => $dbForPlatform->findOne('rules', [
Query::equal('domain', [$value]),
]));
if (!$document->isEmpty()) {
throw new Exception(Exception::RESOURCE_ALREADY_EXISTS);
}
$response->noContent();
}
$response->noContent();
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'Invalid type');
}
}
@@ -11,7 +11,6 @@ use Utopia\Database\Document;
use Utopia\Database\Helpers\ID;
use Utopia\Database\Query;
use Utopia\Database\Validator\Datetime as DatetimeValidator;
use Utopia\System\System;
class SitesCustomServerTest extends Scope
{
@@ -1294,49 +1293,73 @@ class SitesCustomServerTest extends Scope
$this->assertNotEmpty($site['body']['$id']);
$this->assertEquals('Test Site', $site['body']['name']);
$sitesDomain = System::getEnv('_APP_DOMAIN_SITES', '');
$domain = "test-site.{$sitesDomain}";
$ruleId1 = \md5($domain);
$rule = $this->client->call(Client::METHOD_GET, '/proxy/rules', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'queries' => [
Query::equal('resourceId', [$siteId])
]
]);
$response = $this->client->call(Client::METHOD_GET, '/console/resources/' . $ruleId1, [
$this->assertEquals(200, $rule['headers']['status-code']);
$this->assertNotEmpty($rule['body']['rules'][0]['domain']);
$domain = $rule['body']['rules'][0]['domain'];
$response = $this->client->call(Client::METHOD_GET, '/console/resources', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'cookie' => 'a_session_console=' . $this->getRoot()['session'],
'x-appwrite-project' => 'console',
], [
'type' => 'rules',
'value' => $domain,
]);
$this->assertEquals(409, $response['headers']['status-code']); // subdomain unavailable
$this->assertEquals(409, $response['headers']['status-code']); // domain unavailable
$domain = "non-existent-subdomain.{$sitesDomain}";
$ruleId2 = \md5($domain);
$nonExistingDomain = "non-existent-subdomain.sites.localhost";
$response = $this->client->call(Client::METHOD_GET, '/console/resources/' . $ruleId2, [
$response = $this->client->call(Client::METHOD_GET, '/console/resources', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'cookie' => 'a_session_console=' . $this->getRoot()['session'],
'x-appwrite-project' => 'console',
], [
'type' => 'rules',
'value' => $nonExistingDomain,
]);
$this->assertEquals(204, $response['headers']['status-code']); // subdomain available
$this->assertEquals(204, $response['headers']['status-code']); // domain available
$this->cleanupSite($siteId);
sleep(1);
$this->assertEventually(function () use ($siteId) {
$rule = $this->client->call(Client::METHOD_GET, '/proxy/rules', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'queries' => [
Query::equal('resourceId', [$siteId])
]
]);
$response = $this->client->call(Client::METHOD_GET, '/console/resources/' . $ruleId1, [
$this->assertEquals(200, $rule['headers']['status-code']);
$this->assertEmpty($rule['body']['rules']);
}, 1000, 500);
$response = $this->client->call(Client::METHOD_GET, '/console/resources', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'cookie' => 'a_session_console=' . $this->getRoot()['session'],
'x-appwrite-project' => 'console',
], [
'type' => 'rules',
'value' => $domain,
]);
$this->assertEquals(204, $response['headers']['status-code']); // subdomain available as site is deleted
$this->assertEquals(204, $response['headers']['status-code']); // domain available as site is deleted
}
// TODO: Add tests for deletion of resources when site is deleted