From e4c1305da5c729c2266232f318cfe152d21ca257 Mon Sep 17 00:00:00 2001 From: Deon George Date: Wed, 10 Aug 2022 15:18:56 +1000 Subject: [PATCH] Added Supplier Domain importing - using dreamscape API --- app/Console/Commands/SupplierDomainSync.php | 40 ++++++++++ app/Jobs/SupplierDomainSync.php | 81 ++++++++++++++++++++ app/Models/Supplier.php | 10 +++ app/Models/Supplier/Domain.php | 18 +++++ app/Models/TLD.php | 50 ++++++++++++ composer.lock | 85 ++++++++++----------- config/nameservers.php | 28 +++++++ config/services.php | 1 + 8 files changed, 268 insertions(+), 45 deletions(-) create mode 100644 app/Console/Commands/SupplierDomainSync.php create mode 100644 app/Jobs/SupplierDomainSync.php create mode 100644 config/nameservers.php diff --git a/app/Console/Commands/SupplierDomainSync.php b/app/Console/Commands/SupplierDomainSync.php new file mode 100644 index 0000000..a1d91bc --- /dev/null +++ b/app/Console/Commands/SupplierDomainSync.php @@ -0,0 +1,40 @@ +argument('supplier'))->singleOrFail(); + + Job::dispatchSync(Site::findOrFail($this->argument('siteid')),$so,$this->option('forceprod')); + } +} \ No newline at end of file diff --git a/app/Jobs/SupplierDomainSync.php b/app/Jobs/SupplierDomainSync.php new file mode 100644 index 0000000..6db8319 --- /dev/null +++ b/app/Jobs/SupplierDomainSync.php @@ -0,0 +1,81 @@ +site = $site; + $this->supplier = $supplier; + $this->forceprod = $forceprod; + + Config::set('site',$site); + } + + /** + * Execute the job. + * + * @return void + */ + public function handle() + { + $registrar_id = ($x=$this->supplier->registrar()) ? $x->id : NULL; + + foreach ($this->supplier->API($this->forceprod)->getDomains(['fetchall'=>true]) as $domain) { + // @todo See if we can find this domain by its ID + + // Find this domain by it's name + if (! $to=TLD::domaintld($domain->domain_name)) { + Log::alert(sprintf('%s:Domain [%s] from (%s) is not in a TLD that we manage',self::LOGKEY,$this->supplier->name,$domain->domain_name)); + + } elseif (($domainpart=strtolower($to->domain_part($domain->domain_name))) && (($x=$to->domains->where('domain_name',$domainpart))->count() === 1)) { + $o = $x->pop(); + $o->registrar_auth_password = $domain->auth_key; + $o->expire_at = Carbon::create($domain->expiry_date); + $o->registrar_account = $domain->account; + $o->registrar_username = ''; + $o->registrar_ns = Supplier\Domain::nameserver_name($domain->nameservers()); + if ($registrar_id) + $o->domain_registrar_id = $registrar_id; + + if ($o->getDirty()) { + Log::info(sprintf('%s:Updating Domain [%s] from (%s)',self::LOGKEY,$domain->domain_name,$this->supplier->name)); + $o->save(); + + } else { + Log::info(sprintf('%s:No Change to Domain [%s] from (%s)',self::LOGKEY,$domain->domain_name,$this->supplier->name)); + } + + // Alert an unmanaged name. + } else { + Log::alert(sprintf('%s:Domain [%s] from (%s) is not one managed in OSB',self::LOGKEY,$this->supplier->name,$domain->domain_name)); + } + } + } +} \ No newline at end of file diff --git a/app/Models/Supplier.php b/app/Models/Supplier.php index edb260c..731ddd5 100644 --- a/app/Models/Supplier.php +++ b/app/Models/Supplier.php @@ -165,6 +165,16 @@ class Supplier extends Model return $this->api_class() && (collect(['api_key','api_secret'])->diff($this->detail->connections->keys())->count() === 0); } + /** + * If this supplier has a domain registrar, return it. + * + * @return DomainRegistrar|null + */ + public function registrar(): ?DomainRegistrar + { + return ($x=config('services.supplier.'.strtolower($this->name).'.registrar')) ? DomainRegistrar::where('name',$x)->single() : NULL; + } + /** * Return the traffic records, that were not matched to a service. * diff --git a/app/Models/Supplier/Domain.php b/app/Models/Supplier/Domain.php index 5e57c60..2ef89bd 100644 --- a/app/Models/Supplier/Domain.php +++ b/app/Models/Supplier/Domain.php @@ -2,6 +2,8 @@ namespace App\Models\Supplier; +use Illuminate\Support\Collection; + use App\Interfaces\SupplierItem; use App\Models\Product\Domain as ProductDomain; use App\Models\TLD; @@ -29,6 +31,22 @@ final class Domain extends Type implements SupplierItem return $this->hasMany(ProductDomain::class,'supplier_item_id','id'); } + /* STATIC */ + + /** + * Determine the owner of the name servers used for the domain + * + */ + public static function nameserver_name(Collection $nameservers): string + { + foreach (config('nameservers') as $key => $ns) { + if ($nameservers->diff($ns)->count() < count($ns)) + return $key; + } + + return 'custom'; + } + /* RELATIONS */ public function tld() diff --git a/app/Models/TLD.php b/app/Models/TLD.php index 9174ae8..5b5117e 100644 --- a/app/Models/TLD.php +++ b/app/Models/TLD.php @@ -3,15 +3,65 @@ namespace App\Models; use Illuminate\Database\Eloquent\Model; +use Illuminate\Support\Str; + +use App\Models\Service\Domain; class TLD extends Model { protected $table = 'tlds'; + /* RELATIONS */ + + public function domains() + { + return $this->hasMany(Domain::class,'tld_id'); + } + + /* STATIC */ + + /** + * Given a domain name, return the TLD component + * + * @param string $domainname + * @return TLD|null + */ + public static function domaintld(string $domainname): ?TLD + { + $tld = NULL; + + foreach (self::get() as $o) { + // Find the most specific match + if (preg_match('/'.$o->name.'$/i',$domainname) && (! $tld || (strlen($o->name) > strlen($tld->name)))) + $tld = $o; + } + + return $tld; + } + /* ATTRIBUTES */ public function getNameAttribute($value): string { return strtoupper($value); } + + /* METHOD */ + + /** + * Given a domain name, return the domain part + * + * @param string $domainname + * @return string|null + */ + public function domain_part(string $domainname): ?string + { + $domainname = strtoupper($domainname); + + // Quick check that this domain is part of this model + if (! Str::endsWith($domainname,'.'.$this->name)) + return NULL; + + return Str::replaceLast('.'.$this->name,'',$domainname); + } } \ No newline at end of file diff --git a/composer.lock b/composer.lock index ca01267..cc8a890 100644 --- a/composer.lock +++ b/composer.lock @@ -142,26 +142,26 @@ }, { "name": "brick/math", - "version": "0.9.3", + "version": "0.10.1", "source": { "type": "git", "url": "https://github.com/brick/math.git", - "reference": "ca57d18f028f84f777b2168cd1911b0dee2343ae" + "reference": "de846578401f4e58f911b3afeb62ced56365ed87" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/brick/math/zipball/ca57d18f028f84f777b2168cd1911b0dee2343ae", - "reference": "ca57d18f028f84f777b2168cd1911b0dee2343ae", + "url": "https://api.github.com/repos/brick/math/zipball/de846578401f4e58f911b3afeb62ced56365ed87", + "reference": "de846578401f4e58f911b3afeb62ced56365ed87", "shasum": "" }, "require": { "ext-json": "*", - "php": "^7.1 || ^8.0" + "php": "^7.4 || ^8.0" }, "require-dev": { "php-coveralls/php-coveralls": "^2.2", - "phpunit/phpunit": "^7.5.15 || ^8.5 || ^9.0", - "vimeo/psalm": "4.9.2" + "phpunit/phpunit": "^9.0", + "vimeo/psalm": "4.25.0" }, "type": "library", "autoload": { @@ -186,19 +186,15 @@ ], "support": { "issues": "https://github.com/brick/math/issues", - "source": "https://github.com/brick/math/tree/0.9.3" + "source": "https://github.com/brick/math/tree/0.10.1" }, "funding": [ { "url": "https://github.com/BenMorel", "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/brick/math", - "type": "tidelift" } ], - "time": "2021-08-15T20:50:18+00:00" + "time": "2022-08-01T22:54:31+00:00" }, { "name": "clarkeash/doorman", @@ -1964,16 +1960,16 @@ }, { "name": "laravel/framework", - "version": "v9.23.0", + "version": "v9.24.0", "source": { "type": "git", "url": "https://github.com/laravel/framework.git", - "reference": "c4eea9060d847b5c93957b203caa8f57544a76ab" + "reference": "053840f579cf01d353d81333802afced79b1c0af" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/framework/zipball/c4eea9060d847b5c93957b203caa8f57544a76ab", - "reference": "c4eea9060d847b5c93957b203caa8f57544a76ab", + "url": "https://api.github.com/repos/laravel/framework/zipball/053840f579cf01d353d81333802afced79b1c0af", + "reference": "053840f579cf01d353d81333802afced79b1c0af", "shasum": "" }, "require": { @@ -2140,7 +2136,7 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2022-08-02T14:24:44+00:00" + "time": "2022-08-09T13:43:22+00:00" }, { "name": "laravel/passport", @@ -2280,16 +2276,16 @@ }, { "name": "laravel/socialite", - "version": "v5.5.3", + "version": "v5.5.4", "source": { "type": "git", "url": "https://github.com/laravel/socialite.git", - "reference": "9dfc76b31ee041c45a7cae86f23339784abde46d" + "reference": "3eec261bf83690dd85812587457f093e3156dca6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/socialite/zipball/9dfc76b31ee041c45a7cae86f23339784abde46d", - "reference": "9dfc76b31ee041c45a7cae86f23339784abde46d", + "url": "https://api.github.com/repos/laravel/socialite/zipball/3eec261bf83690dd85812587457f093e3156dca6", + "reference": "3eec261bf83690dd85812587457f093e3156dca6", "shasum": "" }, "require": { @@ -2345,7 +2341,7 @@ "issues": "https://github.com/laravel/socialite/issues", "source": "https://github.com/laravel/socialite" }, - "time": "2022-07-18T13:51:19+00:00" + "time": "2022-08-08T13:27:06+00:00" }, { "name": "laravel/ui", @@ -3346,11 +3342,11 @@ }, { "name": "leenooks/dreamscape", - "version": "0.1.0", + "version": "0.1.1", "source": { "type": "git", "url": "https://dev.leenooks.net/leenooks/dreamscape", - "reference": "379f20590e3492dcd888857ace67076a96d83c50" + "reference": "f5bec882f5c697b4d5c6b53b5efff26bf71bb4a5" }, "require": { "jenssegers/model": "^1.5" @@ -3373,7 +3369,7 @@ "laravel", "leenooks" ], - "time": "2022-08-04T10:45:31+00:00" + "time": "2022-08-10T05:17:16+00:00" }, { "name": "leenooks/laravel", @@ -3660,16 +3656,16 @@ }, { "name": "nesbot/carbon", - "version": "2.60.0", + "version": "2.61.0", "source": { "type": "git", "url": "https://github.com/briannesbitt/Carbon.git", - "reference": "00a259ae02b003c563158b54fb6743252b638ea6" + "reference": "bdf4f4fe3a3eac4de84dbec0738082a862c68ba6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/00a259ae02b003c563158b54fb6743252b638ea6", - "reference": "00a259ae02b003c563158b54fb6743252b638ea6", + "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/bdf4f4fe3a3eac4de84dbec0738082a862c68ba6", + "reference": "bdf4f4fe3a3eac4de84dbec0738082a862c68ba6", "shasum": "" }, "require": { @@ -3758,7 +3754,7 @@ "type": "tidelift" } ], - "time": "2022-07-27T15:57:48+00:00" + "time": "2022-08-06T12:41:24+00:00" }, { "name": "nette/schema", @@ -5258,20 +5254,20 @@ }, { "name": "ramsey/uuid", - "version": "4.3.1", + "version": "4.4.0", "source": { "type": "git", "url": "https://github.com/ramsey/uuid.git", - "reference": "8505afd4fea63b81a85d3b7b53ac3cb8dc347c28" + "reference": "373f7bacfcf3de038778ff27dcce5672ddbf4c8a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ramsey/uuid/zipball/8505afd4fea63b81a85d3b7b53ac3cb8dc347c28", - "reference": "8505afd4fea63b81a85d3b7b53ac3cb8dc347c28", + "url": "https://api.github.com/repos/ramsey/uuid/zipball/373f7bacfcf3de038778ff27dcce5672ddbf4c8a", + "reference": "373f7bacfcf3de038778ff27dcce5672ddbf4c8a", "shasum": "" }, "require": { - "brick/math": "^0.8 || ^0.9", + "brick/math": "^0.8 || ^0.9 || ^0.10", "ext-ctype": "*", "ext-json": "*", "php": "^8.0", @@ -5287,7 +5283,6 @@ "doctrine/annotations": "^1.8", "ergebnis/composer-normalize": "^2.15", "mockery/mockery": "^1.3", - "moontoast/math": "^1.1", "paragonie/random-lib": "^2", "php-mock/php-mock": "^2.2", "php-mock/php-mock-mockery": "^1.3", @@ -5336,7 +5331,7 @@ ], "support": { "issues": "https://github.com/ramsey/uuid/issues", - "source": "https://github.com/ramsey/uuid/tree/4.3.1" + "source": "https://github.com/ramsey/uuid/tree/4.4.0" }, "funding": [ { @@ -5348,7 +5343,7 @@ "type": "tidelift" } ], - "time": "2022-03-27T21:42:02+00:00" + "time": "2022-08-05T17:58:37+00:00" }, { "name": "rennokki/laravel-eloquent-query-cache", @@ -10604,16 +10599,16 @@ }, { "name": "spatie/flare-client-php", - "version": "1.2.0", + "version": "1.3.0", "source": { "type": "git", "url": "https://github.com/spatie/flare-client-php.git", - "reference": "86a380f5b1ce839af04a08f1c8f2697184cdf23f" + "reference": "b1b974348750925b717fa8c8b97a0db0d1aa40ca" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/flare-client-php/zipball/86a380f5b1ce839af04a08f1c8f2697184cdf23f", - "reference": "86a380f5b1ce839af04a08f1c8f2697184cdf23f", + "url": "https://api.github.com/repos/spatie/flare-client-php/zipball/b1b974348750925b717fa8c8b97a0db0d1aa40ca", + "reference": "b1b974348750925b717fa8c8b97a0db0d1aa40ca", "shasum": "" }, "require": { @@ -10661,7 +10656,7 @@ ], "support": { "issues": "https://github.com/spatie/flare-client-php/issues", - "source": "https://github.com/spatie/flare-client-php/tree/1.2.0" + "source": "https://github.com/spatie/flare-client-php/tree/1.3.0" }, "funding": [ { @@ -10669,7 +10664,7 @@ "type": "github" } ], - "time": "2022-05-16T12:13:39+00:00" + "time": "2022-08-08T10:10:20+00:00" }, { "name": "spatie/ignition", diff --git a/config/nameservers.php b/config/nameservers.php new file mode 100644 index 0000000..8891960 --- /dev/null +++ b/config/nameservers.php @@ -0,0 +1,28 @@ + [ + 'bruce.ns.cloudflare.com', + 'melinda.ns.cloudflare.com', + ], + 'dreamscape' => [ + 'ns1.secureparkme.com', + 'ns2.secureparkme.com', + ], + 'dreamscape-dns' => [ + 'ns1.dnspackage.com', + 'ns2.dnspackage.com', + ], + 'dreamscape-email' => [ + 'ns3.secureparkme.com', + 'ns4.secureparkme.com', + ], + 'dreamscape-host' => [ + 'ns1.syrahost.com', + 'ns2.syrahost.com', + ], + 'graytech' => [ + 'ns1.graytech.com.au', + 'ns2.graytech.com.au', + ], +]; \ No newline at end of file diff --git a/config/services.php b/config/services.php index 960491d..cfcc8f2 100644 --- a/config/services.php +++ b/config/services.php @@ -46,6 +46,7 @@ return [ 'supplier' => [ 'crazydomain' => [ 'api'=> \Dreamscape\API::class, + 'registrar' => 'crazydomain', // Key in the domain_registrars table ] ], ];