Changeset View
Changeset View
Standalone View
Standalone View
src/app/Http/Controllers/API/V4/DomainsController.php
<?php | <?php | ||||
namespace App\Http\Controllers\API\V4; | namespace App\Http\Controllers\API\V4; | ||||
use App\Domain; | use App\Domain; | ||||
use App\Http\Controllers\Controller; | use App\Http\Controllers\Controller; | ||||
use App\Backends\LDAP; | use App\Backends\LDAP; | ||||
use App\Rules\UserEmailDomain; | use App\Rules\UserEmailDomain; | ||||
use Carbon\Carbon; | |||||
use Illuminate\Http\Request; | use Illuminate\Http\Request; | ||||
use Illuminate\Support\Facades\DB; | use Illuminate\Support\Facades\DB; | ||||
use Illuminate\Support\Facades\Validator; | use Illuminate\Support\Facades\Validator; | ||||
class DomainsController extends Controller | class DomainsController extends Controller | ||||
{ | { | ||||
/** @var array Common object properties in the API response */ | |||||
protected static $objectProps = ['namespace', 'status', 'type']; | |||||
/** | /** | ||||
* Return a list of domains owned by the current user | * Return a list of domains owned by the current user | ||||
* | * | ||||
* @return \Illuminate\Http\JsonResponse | * @return \Illuminate\Http\JsonResponse | ||||
*/ | */ | ||||
public function index() | public function index() | ||||
{ | { | ||||
$user = $this->guard()->user(); | $user = $this->guard()->user(); | ||||
$list = []; | |||||
foreach ($user->domains() as $domain) { | |||||
if (!$domain->isPublic()) { | |||||
$data = $domain->toArray(); | |||||
$data = array_merge($data, self::domainStatuses($domain)); | |||||
$list[] = $data; | |||||
} | |||||
} | |||||
usort($list, function ($a, $b) { | $list = \collect($user->domains()) | ||||
return strcmp($a['namespace'], $b['namespace']); | ->filter(function ($domain) { | ||||
}); | return !$domain->isPublic(); | ||||
}) | |||||
->map(function ($domain) { | |||||
return $this->objectToClient($domain); | |||||
}) | |||||
->sortBy('namespace') | |||||
->values() | |||||
->all(); | |||||
return response()->json($list); | return response()->json($list); | ||||
} | } | ||||
/** | /** | ||||
* Show the form for creating a new domain. | * Show the form for creating a new domain. | ||||
* | * | ||||
* @return \Illuminate\Http\JsonResponse | * @return \Illuminate\Http\JsonResponse | ||||
▲ Show 20 Lines • Show All 202 Lines • ▼ Show 20 Lines | public function show($id) | ||||
if (!$this->checkTenant($domain)) { | if (!$this->checkTenant($domain)) { | ||||
return $this->errorResponse(404); | return $this->errorResponse(404); | ||||
} | } | ||||
if (!$this->guard()->user()->canRead($domain)) { | if (!$this->guard()->user()->canRead($domain)) { | ||||
return $this->errorResponse(403); | return $this->errorResponse(403); | ||||
} | } | ||||
$response = $domain->toArray(); | $response = $this->objectToClient($domain, true); | ||||
// Add hash information to the response | // Add hash information to the response | ||||
$response['hash_text'] = $domain->hash(Domain::HASH_TEXT); | $response['hash_text'] = $domain->hash(Domain::HASH_TEXT); | ||||
$response['hash_cname'] = $domain->hash(Domain::HASH_CNAME); | $response['hash_cname'] = $domain->hash(Domain::HASH_CNAME); | ||||
$response['hash_code'] = $domain->hash(Domain::HASH_CODE); | $response['hash_code'] = $domain->hash(Domain::HASH_CODE); | ||||
// Add DNS/MX configuration for the domain | // Add DNS/MX configuration for the domain | ||||
$response['dns'] = self::getDNSConfig($domain); | $response['dns'] = self::getDNSConfig($domain); | ||||
$response['mx'] = self::getMXConfig($domain->namespace); | $response['mx'] = self::getMXConfig($domain->namespace); | ||||
// Domain configuration, e.g. spf whitelist | // Domain configuration, e.g. spf whitelist | ||||
$response['config'] = $domain->getConfig(); | $response['config'] = $domain->getConfig(); | ||||
// Status info | // Status info | ||||
$response['statusInfo'] = self::statusInfo($domain); | $response['statusInfo'] = self::statusInfo($domain); | ||||
// Entitlements info | // Entitlements info | ||||
$response['skus'] = \App\Entitlement::objectEntitlementsSummary($domain); | $response['skus'] = \App\Entitlement::objectEntitlementsSummary($domain); | ||||
$response = array_merge($response, self::domainStatuses($domain)); | |||||
// Some basic information about the domain wallet | // Some basic information about the domain wallet | ||||
$wallet = $domain->wallet(); | $wallet = $domain->wallet(); | ||||
$response['wallet'] = $wallet->toArray(); | $response['wallet'] = $wallet->toArray(); | ||||
if ($wallet->discount) { | if ($wallet->discount) { | ||||
$response['wallet']['discount'] = $wallet->discount->discount; | $response['wallet']['discount'] = $wallet->discount->discount; | ||||
$response['wallet']['discount_description'] = $wallet->discount->description; | $response['wallet']['discount_description'] = $wallet->discount->description; | ||||
} | } | ||||
Show All 14 Lines | public function status($id) | ||||
if (!$this->checkTenant($domain)) { | if (!$this->checkTenant($domain)) { | ||||
return $this->errorResponse(404); | return $this->errorResponse(404); | ||||
} | } | ||||
if (!$this->guard()->user()->canRead($domain)) { | if (!$this->guard()->user()->canRead($domain)) { | ||||
return $this->errorResponse(403); | return $this->errorResponse(403); | ||||
} | } | ||||
$response = self::statusInfo($domain); | $response = $this->processStateUpdate($domain); | ||||
$response = array_merge($response, self::objectState($domain)); | |||||
if (!empty(request()->input('refresh'))) { | |||||
$updated = false; | |||||
$last_step = 'none'; | |||||
foreach ($response['process'] as $idx => $step) { | |||||
$last_step = $step['label']; | |||||
if (!$step['state']) { | |||||
if (!$this->execProcessStep($domain, $step['label'])) { | |||||
break; | |||||
} | |||||
$updated = true; | |||||
} | |||||
} | |||||
if ($updated) { | |||||
$response = self::statusInfo($domain); | |||||
} | |||||
$success = $response['isReady']; | |||||
$suffix = $success ? 'success' : 'error-' . $last_step; | |||||
$response['status'] = $success ? 'success' : 'error'; | |||||
$response['message'] = \trans('app.process-' . $suffix); | |||||
} | |||||
$response = array_merge($response, self::domainStatuses($domain)); | |||||
return response()->json($response); | return response()->json($response); | ||||
} | } | ||||
/** | /** | ||||
* Update the specified domain. | * Update the specified domain. | ||||
* | * | ||||
* @param \Illuminate\Http\Request $request | * @param \Illuminate\Http\Request $request | ||||
▲ Show 20 Lines • Show All 69 Lines • ▼ Show 20 Lines | class DomainsController extends Controller | ||||
/** | /** | ||||
* Prepare domain statuses for the UI | * Prepare domain statuses for the UI | ||||
* | * | ||||
* @param \App\Domain $domain Domain object | * @param \App\Domain $domain Domain object | ||||
* | * | ||||
* @return array Statuses array | * @return array Statuses array | ||||
*/ | */ | ||||
protected static function domainStatuses(Domain $domain): array | protected static function objectState(Domain $domain): array | ||||
{ | { | ||||
return [ | return [ | ||||
'isLdapReady' => $domain->isLdapReady(), | 'isLdapReady' => $domain->isLdapReady(), | ||||
'isConfirmed' => $domain->isConfirmed(), | 'isConfirmed' => $domain->isConfirmed(), | ||||
'isVerified' => $domain->isVerified(), | 'isVerified' => $domain->isVerified(), | ||||
'isSuspended' => $domain->isSuspended(), | 'isSuspended' => $domain->isSuspended(), | ||||
'isActive' => $domain->isActive(), | 'isActive' => $domain->isActive(), | ||||
'isDeleted' => $domain->isDeleted() || $domain->trashed(), | 'isDeleted' => $domain->isDeleted() || $domain->trashed(), | ||||
]; | ]; | ||||
} | } | ||||
/** | /** | ||||
* Domain status (extended) information. | * Domain status (extended) information. | ||||
* | * | ||||
* @param \App\Domain $domain Domain object | * @param \App\Domain $domain Domain object | ||||
* | * | ||||
* @return array Status information | * @return array Status information | ||||
*/ | */ | ||||
public static function statusInfo(Domain $domain): array | public static function statusInfo(Domain $domain): array | ||||
{ | { | ||||
$process = []; | |||||
// If that is not a public domain, add domain specific steps | // If that is not a public domain, add domain specific steps | ||||
$steps = [ | return self::processStateInfo( | ||||
$domain, | |||||
[ | |||||
'domain-new' => true, | 'domain-new' => true, | ||||
'domain-ldap-ready' => $domain->isLdapReady(), | 'domain-ldap-ready' => $domain->isLdapReady(), | ||||
'domain-verified' => $domain->isVerified(), | 'domain-verified' => $domain->isVerified(), | ||||
'domain-confirmed' => $domain->isConfirmed(), | 'domain-confirmed' => [$domain->isConfirmed(), "/domain/{$domain->id}"], | ||||
]; | ] | ||||
); | |||||
$count = count($steps); | |||||
// Create a process check list | |||||
foreach ($steps as $step_name => $state) { | |||||
$step = [ | |||||
'label' => $step_name, | |||||
'title' => \trans("app.process-{$step_name}"), | |||||
'state' => $state, | |||||
]; | |||||
if ($step_name == 'domain-confirmed' && !$state) { | |||||
$step['link'] = "/domain/{$domain->id}"; | |||||
} | |||||
$process[] = $step; | |||||
if ($state) { | |||||
$count--; | |||||
} | |||||
} | |||||
$state = $count === 0 ? 'done' : 'running'; | |||||
// After 180 seconds assume the process is in failed state, | |||||
// this should unlock the Refresh button in the UI | |||||
if ($count > 0 && $domain->created_at->diffInSeconds(Carbon::now()) > 180) { | |||||
$state = 'failed'; | |||||
} | |||||
return [ | |||||
'process' => $process, | |||||
'processState' => $state, | |||||
'isReady' => $count === 0, | |||||
]; | |||||
} | } | ||||
/** | /** | ||||
* Execute (synchronously) specified step in a domain setup process. | * Execute (synchronously) specified step in a domain setup process. | ||||
* | * | ||||
* @param \App\Domain $domain Domain object | * @param \App\Domain $domain Domain object | ||||
* @param string $step Step identifier (as in self::statusInfo()) | * @param string $step Step identifier (as in self::statusInfo()) | ||||
* | * | ||||
Show All 32 Lines |