Delete DNS validator from Appwrite

This commit is contained in:
Khushboo Verma
2025-11-13 13:34:52 +05:30
parent ac42bb04f4
commit 790c440799
2 changed files with 0 additions and 220 deletions
-120
View File
@@ -1,120 +0,0 @@
<?php
namespace Appwrite\Network\Validator;
use Utopia\DNS\Client;
use Utopia\DNS\Message;
use Utopia\DNS\Message\Question;
use Utopia\DNS\Message\Record;
use Utopia\Domains\Domain;
use Utopia\System\System;
use Utopia\Validator;
class DNS extends Validator
{
public function __construct(
protected string $target,
protected int $type = Record::TYPE_CNAME,
protected string $server = ''
) {
$this->server = $server ?: System::getEnv('_APP_DNS', '8.8.8.8');
}
public function getDescription(): string
{
return 'Invalid DNS record.';
}
public function isValid($value): bool
{
if (!is_string($value) || trim($value) === '') {
return false;
}
$client = new Client($this->server);
try {
$response = $client->query(Message::query(
new Question($value, $this->type)
));
} catch (\Throwable) {
return false;
}
$this->count = \count($query);
$typeMatches = array_filter(
$response->answers,
fn (Record $record) => $record->type === $this->type
);
if (empty($typeMatches)) {
if ($this->type === Record::TYPE_CAA) {
return $this->validateParentCAA($value);
}
return false;
}
foreach ($typeMatches as $record) {
if ($this->type === Record::TYPE_CAA) {
$valuePart = $this->extractCAAValue($record->rdata);
if ($valuePart !== '' && $valuePart === $this->target) {
return true;
}
} else {
$this->recordValues[] = $record->getRdata();
}
if ($record->rdata === $this->target) {
return true;
}
}
return false;
}
private function validateParentCAA(string $domain): bool
{
try {
$domainInfo = new Domain($domain);
} catch (\Throwable) {
return false;
}
if ($domainInfo->get() === $domainInfo->getApex()) {
return true;
}
$parts = explode('.', $domainInfo->get());
array_shift($parts);
$parent = implode('.', $parts);
if ($parent === '') {
return false;
}
$validator = new self($this->target, Record::TYPE_CAA, $this->server);
return $validator->isValid($parent);
}
private function extractCAAValue(string $rdata): string
{
$parts = explode(' ', $rdata, 3);
if (count($parts) < 3) {
return '';
}
$value = trim($parts[2], '"');
return explode(';', $value)[0] ?? '';
}
public function isArray(): bool
{
return false;
}
public function getType(): string
{
return self::TYPE_STRING;
}
}
-100
View File
@@ -1,100 +0,0 @@
<?php
namespace Tests\Unit\Network\Validators;
use Appwrite\Network\Validator\DNS;
use Appwrite\Tests\Retry;
use PHPUnit\Framework\TestCase;
use Utopia\DNS\Message\Record;
use Utopia\DNS\Validator\DNS as ValidatorDNS;
use Utopia\System\System;
/**
* DNS Setup (on Appwrite Labs digital ocean team, network tab):
*
* certainly.caa.appwrite.org: CAA 0 issue "certainly.com"
* certainly-full.caa.appwrite.org: CAA 128 issuewild "certainly.com;account=123456;validationmethods=dns-01"
* letsencrypt.certainly.caa.appwrite.org: CAA 0 issue "letsencrypt.org"
*/
class DNSTest extends TestCase
{
public function testCNAME(): void
{
$validator = new ValidatorDNS('appwrite.io', Record::TYPE_CNAME, System::getEnv('_APP_DNS', '8.8.8.8'));
$this->assertEquals($validator->isValid(''), false);
$this->assertEquals($validator->isValid(null), false);
$this->assertEquals($validator->isValid(false), false);
$this->assertEquals($validator->isValid('cname-unit-test.appwrite.org'), true);
$this->assertEquals($validator->isValid('test1.appwrite.org'), false);
}
public function testA(): void
{
// IPv4 for documentation purposes
$validator = new ValidatorDNS('203.0.113.1', Record::TYPE_A, System::getEnv('_APP_DNS', '8.8.8.8'));
$this->assertEquals($validator->isValid(''), false);
$this->assertEquals($validator->isValid(null), false);
$this->assertEquals($validator->isValid(false), false);
$this->assertEquals($validator->isValid('a-unit-test.appwrite.org'), true);
$this->assertEquals($validator->isValid('test1.appwrite.org'), false);
}
public function testAAAA(): void
{
// IPv6 for documentation purposes
$validator = new ValidatorDNS('2001:db8::1', Record::TYPE_AAAA, System::getEnv('_APP_DNS', '8.8.8.8'));
$this->assertEquals($validator->isValid(''), false);
$this->assertEquals($validator->isValid(null), false);
$this->assertEquals($validator->isValid(false), false);
$this->assertEquals($validator->isValid('aaaa-unit-test.appwrite.org'), true);
$this->assertEquals($validator->isValid('test1.appwrite.org'), false);
}
#[Retry(count: 5)]
public function testCAA(): void
{
$certainly = new ValidatorDNS('certainly.com', Record::TYPE_CAA, 'ns1.digitalocean.com');
$letsencrypt = new ValidatorDNS('letsencrypt.org', Record::TYPE_CAA, 'ns1.digitalocean.com');
// No CAA record succeeds on main domain & subdomains for any issuer
$this->assertEquals($certainly->isValid('caa.appwrite.org'), true);
$this->assertEquals($certainly->isValid('sub.caa.appwrite.org'), true);
$this->assertEquals($certainly->isValid('sub.sub.caa.appwrite.org'), true);
$this->assertEquals($letsencrypt->isValid('caa.appwrite.org'), true);
$this->assertEquals($letsencrypt->isValid('sub.caa.appwrite.org'), true);
$this->assertEquals($letsencrypt->isValid('sub.sub.caa.appwrite.org'), true);
// Custom flags and tag is allowed, but only for Certainly
$this->assertEquals($certainly->isValid('certainly-full.caa.appwrite.org'), true);
$this->assertEquals($letsencrypt->isValid('certainly-full.caa.appwrite.org'), false);
// Custom flags&tag are not allowed if validator includes specific flags&tag
$certainlyFull = new ValidatorDNS('0 issue "certainly.com"', Record::TYPE_CAA, System::getEnv('_APP_DNS', '8.8.8.8'));
$this->assertEquals($certainlyFull->isValid('certainly-full.caa.appwrite.org'), false);
// Custom flags&tag still allows if they match exactly
$certainlyFull = new ValidatorDNS('128 issuewild "certainly.com;account=123456;validationmethods=dns-01"', Record::TYPE_CAA, System::getEnv('_APP_DNS', '8.8.8.8'));
$this->assertEquals($certainlyFull->isValid('certainly-full.caa.appwrite.org'), true);
// Certainly CAA allows Certainly, but not LetsEncrypt; Same for subdomains
$this->assertEquals($certainly->isValid('certainly.caa.appwrite.org'), true);
$this->assertEquals($letsencrypt->isValid('certainly.caa.appwrite.org'), false);
$this->assertEquals($certainly->isValid('sub.certainly.caa.appwrite.org'), true);
$this->assertEquals($letsencrypt->isValid('sub.certainly.caa.appwrite.org'), false);
$this->assertEquals($certainly->isValid('sub.sub.certainly.caa.appwrite.org'), true);
$this->assertEquals($letsencrypt->isValid('sub.sub.certainly.caa.appwrite.org'), false);
// LetsEncrypt CAA on subdomain with parent allowing Certainly. Only LetsEncrypt is allowed; Same for subdomains
$this->assertEquals($certainly->isValid('letsencrypt.certainly.caa.appwrite.org'), false);
$this->assertEquals($letsencrypt->isValid('letsencrypt.certainly.caa.appwrite.org'), true);
$this->assertEquals($certainly->isValid('sub.letsencrypt.certainly.caa.appwrite.org'), false);
$this->assertEquals($letsencrypt->isValid('sub.letsencrypt.certainly.caa.appwrite.org'), true);
$this->assertEquals($certainly->isValid('sub.sub.letsencrypt.certainly.caa.appwrite.org'), false);
$this->assertEquals($letsencrypt->isValid('sub.sub.letsencrypt.certainly.caa.appwrite.org'), true);
}
}