mirror of
https://github.com/appwrite/appwrite.git
synced 2026-05-26 13:51:13 +00:00
fix: create a validator isntead of redundant code
This commit is contained in:
+1
-1
@@ -1033,7 +1033,7 @@ services:
|
||||
volumes:
|
||||
- appwrite-mariadb:/var/lib/mysql:rw
|
||||
ports:
|
||||
- "3306:3306"
|
||||
- "3307:3306"
|
||||
environment:
|
||||
- MYSQL_ROOT_PASSWORD=${_APP_DB_ROOT_PASS}
|
||||
- MYSQL_DATABASE=${_APP_DB_SCHEMA}
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
namespace Appwrite\Network\Validator;
|
||||
|
||||
use Utopia\Validator;
|
||||
|
||||
class AppwriteNetworkDomain extends Validator
|
||||
{
|
||||
public function getDescription(): string
|
||||
{
|
||||
return 'Sub-subdomains are not allowed for appwrite.network. Only one level of subdomain is permitted.';
|
||||
}
|
||||
|
||||
public function isValid($value): bool
|
||||
{
|
||||
if (!is_string($value) || empty($value)) {
|
||||
return true;
|
||||
}
|
||||
if (\str_starts_with($value, '.')) {
|
||||
return false;
|
||||
}
|
||||
if (\str_ends_with($value, '.appwrite.network.')) {
|
||||
return false;
|
||||
}
|
||||
if (!\str_ends_with(\strtolower($value), '.appwrite.network')) {
|
||||
return true;
|
||||
}
|
||||
$subdomain = substr(strtolower($value), 0, -strlen('.appwrite.network'));
|
||||
if (\str_contains($subdomain, '.')) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function isArray(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getType(): string
|
||||
{
|
||||
return self::TYPE_STRING;
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@
|
||||
namespace Appwrite\Platform\Modules\Console\Http\Resources;
|
||||
|
||||
use Appwrite\Extend\Exception;
|
||||
use Appwrite\Network\Validator\AppwriteNetworkDomain;
|
||||
use Appwrite\SDK\AuthType;
|
||||
use Appwrite\SDK\ContentType;
|
||||
use Appwrite\SDK\Method;
|
||||
@@ -68,11 +69,10 @@ class Get extends Action
|
||||
) {
|
||||
if ($type === 'rules') {
|
||||
$validator = new Domain($value);
|
||||
if (\str_ends_with(\strtolower($value), '.appwrite.network')) {
|
||||
$subdomain = \str_replace('.appwrite.network', '', strtolower($value));
|
||||
if (\str_contains($subdomain, '.')) {
|
||||
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'Sub-subdomains are not allowed for appwrite.network. Only one level of subdomain is permitted.');
|
||||
}
|
||||
|
||||
$appwriteNetworkValidator = new AppwriteNetworkDomain();
|
||||
if (!$appwriteNetworkValidator->isValid($value)) {
|
||||
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, $appwriteNetworkValidator->getDescription());
|
||||
}
|
||||
|
||||
if (!$validator->isValid($value)) {
|
||||
|
||||
@@ -5,6 +5,7 @@ namespace Appwrite\Platform\Modules\Proxy\Http\Rules\API;
|
||||
use Appwrite\Event\Certificate;
|
||||
use Appwrite\Event\Event;
|
||||
use Appwrite\Extend\Exception;
|
||||
use Appwrite\Network\Validator\AppwriteNetworkDomain;
|
||||
use Appwrite\Network\Validator\DNS;
|
||||
use Appwrite\SDK\AuthType;
|
||||
use Appwrite\SDK\Method;
|
||||
@@ -106,11 +107,10 @@ class Create extends Action
|
||||
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'This domain name is not allowed. Please use a different domain.');
|
||||
}
|
||||
|
||||
if (\str_ends_with(\strtolower($domain), '.appwrite.network')) {
|
||||
$subdomain = \str_replace('.appwrite.network', '', \strtolower($domain));
|
||||
if (empty($subdomain) || \str_contains($subdomain, '.')) {
|
||||
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'Sub-subdomains are not allowed for appwrite.network. Only one level of subdomain is permitted.');
|
||||
}
|
||||
|
||||
$appwriteNetworkValidator = new AppwriteNetworkDomain();
|
||||
if (!$appwriteNetworkValidator->isValid($domain)) {
|
||||
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, $appwriteNetworkValidator->getDescription());
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
@@ -5,6 +5,7 @@ namespace Appwrite\Platform\Modules\Proxy\Http\Rules\Function;
|
||||
use Appwrite\Event\Certificate;
|
||||
use Appwrite\Event\Event;
|
||||
use Appwrite\Extend\Exception;
|
||||
use Appwrite\Network\Validator\AppwriteNetworkDomain;
|
||||
use Appwrite\Network\Validator\DNS;
|
||||
use Appwrite\SDK\AuthType;
|
||||
use Appwrite\SDK\Method;
|
||||
@@ -111,11 +112,10 @@ class Create extends Action
|
||||
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'This domain name is not allowed. Please use a different domain.');
|
||||
}
|
||||
|
||||
if (\str_ends_with(\strtolower($domain), '.appwrite.network')) {
|
||||
$subdomain = \str_replace('.appwrite.network', '', strtolower($domain));
|
||||
if (\str_contains($subdomain, '.')) {
|
||||
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'Sub-subdomains are not allowed for appwrite.network. Only one level of subdomain is permitted.');
|
||||
}
|
||||
|
||||
$appwriteNetworkValidator = new AppwriteNetworkDomain();
|
||||
if (!$appwriteNetworkValidator->isValid($domain)) {
|
||||
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, $appwriteNetworkValidator->getDescription());
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
@@ -5,6 +5,7 @@ namespace Appwrite\Platform\Modules\Proxy\Http\Rules\Redirect;
|
||||
use Appwrite\Event\Certificate;
|
||||
use Appwrite\Event\Event;
|
||||
use Appwrite\Extend\Exception;
|
||||
use Appwrite\Network\Validator\AppwriteNetworkDomain;
|
||||
use Appwrite\Network\Validator\DNS;
|
||||
use Appwrite\SDK\AuthType;
|
||||
use Appwrite\SDK\Method;
|
||||
@@ -114,11 +115,10 @@ class Create extends Action
|
||||
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'This domain name is not allowed. Please use a different domain.');
|
||||
}
|
||||
|
||||
if (\str_ends_with(\strtolower($domain), '.appwrite.network')) {
|
||||
$subdomain = \str_replace('.appwrite.network', '', strtolower($domain));
|
||||
if (\str_contains($subdomain, '.')) {
|
||||
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'Sub-subdomains are not allowed for appwrite.network. Only one level of subdomain is permitted.');
|
||||
}
|
||||
|
||||
$appwriteNetworkValidator = new AppwriteNetworkDomain();
|
||||
if (!$appwriteNetworkValidator->isValid($domain)) {
|
||||
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, $appwriteNetworkValidator->getDescription());
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
@@ -5,6 +5,7 @@ namespace Appwrite\Platform\Modules\Proxy\Http\Rules\Site;
|
||||
use Appwrite\Event\Certificate;
|
||||
use Appwrite\Event\Event;
|
||||
use Appwrite\Extend\Exception;
|
||||
use Appwrite\Network\Validator\AppwriteNetworkDomain;
|
||||
use Appwrite\Network\Validator\DNS;
|
||||
use Appwrite\SDK\AuthType;
|
||||
use Appwrite\SDK\Method;
|
||||
@@ -111,11 +112,10 @@ class Create extends Action
|
||||
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'This domain name is not allowed. Please use a different domain.');
|
||||
}
|
||||
|
||||
if (\str_ends_with(\strtolower($domain), '.appwrite.network')) {
|
||||
$subdomain = \str_replace('.appwrite.network', '', strtolower($domain));
|
||||
if (\str_contains($subdomain, '.')) {
|
||||
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'Sub-subdomains are not allowed for appwrite.network. Only one level of subdomain is permitted.');
|
||||
}
|
||||
|
||||
$appwriteNetworkValidator = new AppwriteNetworkDomain();
|
||||
if (!$appwriteNetworkValidator->isValid($domain)) {
|
||||
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, $appwriteNetworkValidator->getDescription());
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
@@ -81,33 +81,6 @@ class ProxyCustomServerTest extends Scope
|
||||
$this->cleanupRule($rule['body']['$id']);
|
||||
}
|
||||
|
||||
public function testCreateAPIRuleAppwriteNetworkValidation(): void
|
||||
{
|
||||
// Test vallid single subdomain for appwrite.network
|
||||
$validDomain = \uniqid() . '.appwrite.network';
|
||||
$rule = $this->createAPIRule($validDomain);
|
||||
$this->assertEquals(201, $rule['headers']['status-code']);
|
||||
$this->cleanupRule($rule['body']['$id']);
|
||||
|
||||
// Test invalid sub-subdomain for appwrite.network
|
||||
$invalidDomain = 'api.staging.appwrite.network';
|
||||
$rule = $this->createAPIRule($invalidDomain);
|
||||
$this->assertEquals(400, $rule['headers']['status-code']);
|
||||
$this->assertStringContainsString('Sub-subdomains are not allowed for appwrite.network', $rule['body']['message']);
|
||||
|
||||
// Test another invalid sub-subdomain with multiple dots
|
||||
$invalidDomain2 = 'asadsdsa.sddsa.appwrite.network';
|
||||
$rule = $this->createAPIRule($invalidDomain2);
|
||||
$this->assertEquals(400, $rule['headers']['status-code']);
|
||||
$this->assertStringContainsString('Sub-subdomains are not allowed for appwrite.network', $rule['body']['message']);
|
||||
|
||||
// Test valid domain that doesn't end with appwrite.network (should pass)
|
||||
$otherDomain = \uniqid() . '.example.com';
|
||||
$rule = $this->createAPIRule($otherDomain);
|
||||
$this->assertEquals(201, $rule['headers']['status-code']);
|
||||
$this->cleanupRule($rule['body']['$id']);
|
||||
}
|
||||
|
||||
public function testCreateAPIRule(): void
|
||||
{
|
||||
$domain = \uniqid() . '-api.custom.localhost';
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Unit\Network\Validators;
|
||||
|
||||
use Appwrite\Network\Validator\AppwriteNetworkDomain;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class AppwriteNetworkDomainTest extends TestCase
|
||||
{
|
||||
protected ?AppwriteNetworkDomain $validator = null;
|
||||
|
||||
public function setUp(): void
|
||||
{
|
||||
$this->validator = new AppwriteNetworkDomain();
|
||||
}
|
||||
|
||||
public function tearDown(): void
|
||||
{
|
||||
$this->validator = null;
|
||||
}
|
||||
|
||||
public function testValidSingleSubdomains(): void
|
||||
{
|
||||
// Valid single-level subdomains for appwrite.network
|
||||
$this->assertEquals(true, $this->validator->isValid('api.appwrite.network'));
|
||||
$this->assertEquals(true, $this->validator->isValid('app.appwrite.network'));
|
||||
$this->assertEquals(true, $this->validator->isValid('test.appwrite.network'));
|
||||
$this->assertEquals(true, $this->validator->isValid('myapp.appwrite.network'));
|
||||
$this->assertEquals(true, $this->validator->isValid('123.appwrite.network'));
|
||||
$this->assertEquals(true, $this->validator->isValid('my-app.appwrite.network'));
|
||||
$this->assertEquals(true, $this->validator->isValid('a.appwrite.network'));
|
||||
|
||||
// Test case insensitivity
|
||||
$this->assertEquals(true, $this->validator->isValid('API.APPWRITE.NETWORK'));
|
||||
$this->assertEquals(true, $this->validator->isValid('Api.Appwrite.Network'));
|
||||
}
|
||||
|
||||
public function testInvalidSubSubdomains(): void
|
||||
{
|
||||
// Invalid sub-subdomains for appwrite.network
|
||||
$this->assertEquals(false, $this->validator->isValid('api.staging.appwrite.network'));
|
||||
$this->assertEquals(false, $this->validator->isValid('app.dev.appwrite.network'));
|
||||
$this->assertEquals(false, $this->validator->isValid('test.beta.appwrite.network'));
|
||||
$this->assertEquals(false, $this->validator->isValid('foo.bar.appwrite.network'));
|
||||
$this->assertEquals(false, $this->validator->isValid('a.b.appwrite.network'));
|
||||
$this->assertEquals(false, $this->validator->isValid('very.long.subdomain.appwrite.network'));
|
||||
$this->assertEquals(false, $this->validator->isValid('multi.level.deep.appwrite.network'));
|
||||
|
||||
// Test case insensitivity
|
||||
$this->assertEquals(false, $this->validator->isValid('API.STAGING.APPWRITE.NETWORK'));
|
||||
$this->assertEquals(false, $this->validator->isValid('Api.Dev.Appwrite.Network'));
|
||||
}
|
||||
|
||||
public function testNonAppwriteNetworkDomains(): void
|
||||
{
|
||||
// Non-appwrite.network domains should pass validation (not our concern)
|
||||
$this->assertEquals(true, $this->validator->isValid('example.com'));
|
||||
$this->assertEquals(true, $this->validator->isValid('api.example.com'));
|
||||
$this->assertEquals(true, $this->validator->isValid('deep.nested.example.com'));
|
||||
$this->assertEquals(true, $this->validator->isValid('google.com'));
|
||||
$this->assertEquals(true, $this->validator->isValid('sub.domain.test.io'));
|
||||
$this->assertEquals(true, $this->validator->isValid('localhost'));
|
||||
$this->assertEquals(true, $this->validator->isValid('127.0.0.1'));
|
||||
|
||||
// Similar but different domains
|
||||
$this->assertEquals(true, $this->validator->isValid('appwrite.com'));
|
||||
$this->assertEquals(true, $this->validator->isValid('api.appwrite.com'));
|
||||
$this->assertEquals(true, $this->validator->isValid('test.appwrite.org'));
|
||||
$this->assertEquals(true, $this->validator->isValid('notappwrite.network'));
|
||||
}
|
||||
|
||||
public function testDoubleSubdomainCustomDomain(): void
|
||||
{
|
||||
// Double subdomain for a custom domain should be allowed
|
||||
$this->assertEquals(true, $this->validator->isValid('stage.dashboard.example.com'));
|
||||
$this->assertEquals(true, $this->validator->isValid('foo.bar.baz.example.com'));
|
||||
}
|
||||
|
||||
public function testEdgeCases(): void
|
||||
{
|
||||
// Empty and invalid values should pass (let other validators handle them)
|
||||
$this->assertEquals(true, $this->validator->isValid(''));
|
||||
$this->assertEquals(true, $this->validator->isValid(null));
|
||||
$this->assertEquals(true, $this->validator->isValid(false));
|
||||
$this->assertEquals(true, $this->validator->isValid(123));
|
||||
$this->assertEquals(true, $this->validator->isValid([]));
|
||||
|
||||
// Just the root domain (unlikely but should be valid)
|
||||
$this->assertEquals(true, $this->validator->isValid('appwrite.network'));
|
||||
|
||||
// Domain with trailing/leading dots
|
||||
$this->assertEquals(false, $this->validator->isValid('api.test.appwrite.network.'));
|
||||
$this->assertEquals(false, $this->validator->isValid('.api.test.appwrite.network'));
|
||||
}
|
||||
|
||||
public function testValidatorProperties(): void
|
||||
{
|
||||
$this->assertEquals('Sub-subdomains are not allowed for appwrite.network. Only one level of subdomain is permitted.', $this->validator->getDescription());
|
||||
$this->assertEquals(false, $this->validator->isArray());
|
||||
$this->assertEquals('string', $this->validator->getType());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user