From 0a25463b8d8d7cd0db4b4b233353187a31492ebd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Sat, 22 Feb 2025 18:26:51 +0100 Subject: [PATCH] Apex domain exception + proxy tests --- .github/workflows/tests.yml | 2 + .../Modules/Proxy/Http/Rules/Create.php | 8 +++ tests/e2e/Services/Proxy/ProxyBase.php | 46 +++++++++++++++ .../Services/Proxy/ProxyCustomServerTest.php | 56 +++++++++++++++++++ 4 files changed, 112 insertions(+) create mode 100644 tests/e2e/Services/Proxy/ProxyBase.php create mode 100644 tests/e2e/Services/Proxy/ProxyCustomServerTest.php diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index fef758a613..f7c5fe7c5c 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -146,6 +146,7 @@ jobs: Projects, Realtime, Sites, + Proxy, Storage, Teams, Users, @@ -212,6 +213,7 @@ jobs: Projects, Realtime, Sites, + Proxy, Storage, Teams, Users, diff --git a/src/Appwrite/Platform/Modules/Proxy/Http/Rules/Create.php b/src/Appwrite/Platform/Modules/Proxy/Http/Rules/Create.php index b989310a3d..efb17f1718 100644 --- a/src/Appwrite/Platform/Modules/Proxy/Http/Rules/Create.php +++ b/src/Appwrite/Platform/Modules/Proxy/Http/Rules/Create.php @@ -10,6 +10,7 @@ use Appwrite\SDK\AuthType; use Appwrite\SDK\Method; use Appwrite\SDK\Response as SDKResponse; use Appwrite\Utopia\Response; +use Utopia\App; use Utopia\Database\Database; use Utopia\Database\Document; use Utopia\Database\Helpers\ID; @@ -124,6 +125,13 @@ class Create extends Action throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'Domain may not start with http:// or https://.'); } + // Apex domain prevention due to CNAME limitations + if (empty(App::getEnv('_APP_DOMAINS_NAMESERVERS', ''))) { + if ($domain->get() === $domain->getRegisterable()) { + throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'The instance does not allow root-level (apex) domains.'); + } + } + // TODO: @christyjacob remove once we migrate the rules in 1.7.x $ruleId = System::getEnv('_APP_RULES_FORMAT') === 'md5' ? md5($domain->get()) : ID::unique(); diff --git a/tests/e2e/Services/Proxy/ProxyBase.php b/tests/e2e/Services/Proxy/ProxyBase.php new file mode 100644 index 0000000000..cf33744190 --- /dev/null +++ b/tests/e2e/Services/Proxy/ProxyBase.php @@ -0,0 +1,46 @@ +client->call(Client::METHOD_POST, '/proxy/rules', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), $params); + + return $rule; + } + + protected function deleteRule(string $ruleId): mixed + { + $rule = $this->client->call(Client::METHOD_DELETE, '/proxy/rules/' . $ruleId, array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), []); + + return $rule; + } + + protected function setupRule(mixed $params): string + { + $rule = $this->createRule($params); + + $this->assertEquals(201, $rule['headers']['status-code'], 'Failed to setup rule: ' . \json_encode($rule)); + + return $rule['body']['$id']; + } + + protected function cleanupRule(string $ruleId): void + { + $rule = $this->deleteRule($ruleId); + $this->assertEquals(204, $rule['headers']['status-code'], 'Failed to cleanup rule: ' . \json_encode($rule)); + } +} diff --git a/tests/e2e/Services/Proxy/ProxyCustomServerTest.php b/tests/e2e/Services/Proxy/ProxyCustomServerTest.php new file mode 100644 index 0000000000..5ffe9a4c3a --- /dev/null +++ b/tests/e2e/Services/Proxy/ProxyCustomServerTest.php @@ -0,0 +1,56 @@ +createRule([ + 'domain' => 'api.myapp.com', + 'resourceType' => 'api' + ]); + + $this->assertEquals(201, $rule['headers']['status-code']); + $this->assertEquals('api.myapp.com', $rule['body']['domain']); + $this->assertArrayHasKey('$id', $rule['body']); + $this->assertArrayHasKey('resourceType', $rule['body']); + $this->assertArrayHasKey('resourceId', $rule['body']); + $this->assertArrayHasKey('status', $rule['body']); + $this->assertArrayHasKey('logs', $rule['body']); + $this->assertArrayHasKey('renewAt', $rule['body']); + + $ruleId = $rule['body']['$id']; + + $rule = $this->deleteRule($ruleId); + + $this->assertEquals(204, $rule['headers']['status-code']); + } + + public function testCreateRuleSetup(): void + { + $ruleId = $this->setupRule([ + 'domain' => 'api2.myapp.com', + 'resourceType' => 'api' + ]); + $this->cleanupRule($ruleId); + } + + public function testCreateRuleApex(): void + { + $rule = $this->createRule([ + 'domain' => 'myapp.com', + 'resourceType' => 'api' + ]); + + $this->assertEquals(400, $rule['headers']['status-code']); + } +}