mirror of
https://github.com/appwrite/appwrite.git
synced 2026-05-26 13:51:13 +00:00
Delete DNS validator from Appwrite
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user