Skip to content

Commit df90e15

Browse files
committed
move domains to project scope
1 parent 6f50f78 commit df90e15

20 files changed

+1110
-681
lines changed

app/Actions/Domain/AddDomain.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use App\Models\DNSProvider;
66
use App\Models\Domain;
7+
use App\Models\Project;
78
use App\Models\User;
89
use Illuminate\Support\Facades\Validator;
910
use Illuminate\Validation\Rule;
@@ -16,7 +17,7 @@ class AddDomain
1617
*
1718
* @throws ValidationException
1819
*/
19-
public function add(User $user, array $input): Domain
20+
public function add(User $user, Project $project, array $input): Domain
2021
{
2122
$this->validate($input);
2223

@@ -36,6 +37,7 @@ public function add(User $user, array $input): Domain
3637
$domain = new Domain;
3738
$domain->dns_provider_id = $dnsProvider->id;
3839
$domain->user_id = $user->id;
40+
$domain->project_id = $project->id;
3941
$domain->domain = $domainData['name'];
4042
$domain->provider_domain_id = $domainData['id'];
4143
$domain->metadata = $domainData;

app/Http/Controllers/API/DNSProviderController.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use App\Http\Controllers\Controller;
99
use App\Http\Resources\DNSProviderResource;
1010
use App\Models\DNSProvider;
11+
use Illuminate\Http\JsonResponse;
1112
use Illuminate\Http\Request;
1213
use Illuminate\Http\Resources\Json\ResourceCollection;
1314
use Spatie\RouteAttributes\Attributes\Delete;
@@ -69,4 +70,14 @@ public function destroy(DNSProvider $dnsProvider): \Illuminate\Http\JsonResponse
6970

7071
return response()->json(['message' => 'DNS provider deleted successfully']);
7172
}
73+
74+
#[Get('{dnsProvider}/available', name: 'api.dns-providers.available', middleware: 'ability:read')]
75+
public function availableDomains(DNSProvider $dnsProvider): JsonResponse
76+
{
77+
$this->authorize('view', $dnsProvider);
78+
79+
$domains = $dnsProvider->provider()->getDomains();
80+
81+
return response()->json($domains);
82+
}
7283
}

app/Http/Controllers/API/DNSRecordController.php

Lines changed: 36 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use App\Http\Resources\DNSRecordResource;
1010
use App\Models\DNSRecord;
1111
use App\Models\Domain;
12+
use App\Models\Project;
1213
use Illuminate\Http\JsonResponse;
1314
use Illuminate\Http\Request;
1415
use Illuminate\Http\Resources\Json\ResourceCollection;
@@ -19,67 +20,83 @@
1920
use Spatie\RouteAttributes\Attributes\Post;
2021
use Spatie\RouteAttributes\Attributes\Prefix;
2122

22-
#[Prefix('api/domains/{domain}/records')]
23-
#[Middleware(['auth:sanctum'])]
23+
#[Prefix('api/projects/{project}/domains/{domain}/records')]
24+
#[Middleware(['auth:sanctum', 'can-see-project'])]
2425
class DNSRecordController extends Controller
2526
{
2627
#[Get('/', name: 'api.dns-records', middleware: 'ability:read')]
27-
public function index(Domain $domain): ResourceCollection
28+
public function index(Project $project, Domain $domain): ResourceCollection
2829
{
2930
$this->authorize('view', $domain);
3031

32+
$this->validateRoute($project, $domain);
33+
3134
$records = $domain->records()->orderBy('type')->orderBy('name')->get();
3235

3336
return DNSRecordResource::collection($records);
3437
}
3538

3639
#[Post('/', name: 'api.dns-records.create', middleware: 'ability:write')]
37-
public function create(Request $request, Domain $domain): DNSRecordResource
40+
public function create(Request $request, Project $project, Domain $domain): DNSRecordResource
3841
{
3942
$this->authorize('update', $domain);
4043

44+
$this->validateRoute($project, $domain);
45+
4146
$record = app(CreateDNSRecord::class)->create($domain, $request->all());
4247

4348
return new DNSRecordResource($record);
4449
}
4550

4651
#[Get('{dnsRecord}', name: 'api.dns-records.show', middleware: 'ability:read')]
47-
public function show(Domain $domain, DNSRecord $dnsRecord): DNSRecordResource
52+
public function show(Project $project, Domain $domain, DNSRecord $dnsRecord): DNSRecordResource
4853
{
49-
if ($dnsRecord->domain_id !== $domain->id) {
50-
abort(404);
51-
}
52-
5354
$this->authorize('view', $domain);
5455

56+
$this->validateRoute($project, $domain);
57+
58+
$this->validateRecord($domain, $dnsRecord);
59+
5560
return new DNSRecordResource($dnsRecord);
5661
}
5762

5863
#[Patch('{dnsRecord}', name: 'api.dns-records.update', middleware: 'ability:write')]
59-
public function update(Request $request, Domain $domain, DNSRecord $dnsRecord): DNSRecordResource
64+
public function update(Request $request, Project $project, Domain $domain, DNSRecord $dnsRecord): DNSRecordResource
6065
{
61-
if ($dnsRecord->domain_id !== $domain->id) {
62-
abort(404);
63-
}
64-
6566
$this->authorize('update', $domain);
6667

68+
$this->validateRoute($project, $domain);
69+
70+
$this->validateRecord($domain, $dnsRecord);
71+
6772
app(UpdateDNSRecord::class)->update($dnsRecord, $request->all());
6873

6974
return new DNSRecordResource($dnsRecord);
7075
}
7176

7277
#[Delete('{dnsRecord}', name: 'api.dns-records.destroy', middleware: 'ability:write')]
73-
public function destroy(Domain $domain, DNSRecord $dnsRecord): JsonResponse
78+
public function destroy(Project $project, Domain $domain, DNSRecord $dnsRecord): JsonResponse
7479
{
75-
if ($dnsRecord->domain_id !== $domain->id) {
76-
abort(404);
77-
}
78-
7980
$this->authorize('update', $domain);
81+
$this->validateRoute($project, $domain);
82+
$this->validateRecord($domain, $dnsRecord);
8083

8184
app(DeleteDNSRecord::class)->delete($dnsRecord);
8285

8386
return response()->json(['message' => 'DNS record deleted successfully']);
8487
}
88+
89+
private function validateRoute(Project $project, Domain $domain): void
90+
{
91+
if ($project->id !== $domain->project_id) {
92+
abort(404, 'Domain not found in project');
93+
}
94+
}
95+
96+
private function validateRecord(Domain $domain, DNSRecord $dnsRecord): void
97+
{
98+
if ($dnsRecord->domain_id !== $domain->id) {
99+
abort(404, 'DNS record not found in domain');
100+
}
101+
}
85102
}

app/Http/Controllers/API/DomainController.php

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
use App\Actions\Domain\RemoveDomain;
77
use App\Http\Controllers\Controller;
88
use App\Http\Resources\DomainResource;
9-
use App\Models\DNSProvider;
109
use App\Models\Domain;
10+
use App\Models\Project;
1111
use Illuminate\Http\JsonResponse;
1212
use Illuminate\Http\Request;
1313
use Illuminate\Http\Resources\Json\ResourceCollection;
@@ -17,56 +17,58 @@
1717
use Spatie\RouteAttributes\Attributes\Post;
1818
use Spatie\RouteAttributes\Attributes\Prefix;
1919

20-
#[Prefix('api/domains')]
21-
#[Middleware(['auth:sanctum'])]
20+
#[Prefix('api/projects/{project}/domains')]
21+
#[Middleware(['auth:sanctum', 'can-see-project'])]
2222
class DomainController extends Controller
2323
{
24-
#[Get('/', name: 'api.domains', middleware: 'ability:read')]
25-
public function index(): ResourceCollection
24+
#[Get('/', name: 'api.projects.domains', middleware: 'ability:read')]
25+
public function index(Project $project): ResourceCollection
2626
{
27-
$this->authorize('viewAny', Domain::class);
27+
$this->authorize('viewAny', [Domain::class, $project]);
2828

29-
$domains = user()->domains()->with('dnsProvider')->simplePaginate(25);
29+
$domains = $project->domains()->with('dnsProvider')->simplePaginate(25);
3030

3131
return DomainResource::collection($domains);
3232
}
3333

34-
#[Post('/', name: 'api.domains.create', middleware: 'ability:write')]
35-
public function create(Request $request): DomainResource
34+
#[Post('/', name: 'api.projects.domains.create', middleware: 'ability:write')]
35+
public function create(Request $request, Project $project): DomainResource
3636
{
37-
$this->authorize('create', Domain::class);
37+
$this->authorize('create', [Domain::class, $project]);
3838

3939
$user = user();
40-
$domain = app(AddDomain::class)->add($user, $request->all());
40+
41+
$domain = app(AddDomain::class)->add($user, $project, $request->all());
4142

4243
return new DomainResource($domain->load('dnsProvider'));
4344
}
4445

45-
#[Get('{domain}', name: 'api.domains.show', middleware: 'ability:read')]
46-
public function show(Domain $domain): DomainResource
46+
#[Get('{domain}', name: 'api.projects.domains.show', middleware: 'ability:read')]
47+
public function show(Project $project, Domain $domain): DomainResource
4748
{
4849
$this->authorize('view', $domain);
4950

51+
$this->validateRoute($project, $domain);
52+
5053
return new DomainResource($domain->load('dnsProvider'));
5154
}
5255

53-
#[Delete('{domain}', name: 'api.domains.destroy', middleware: 'ability:write')]
54-
public function destroy(Domain $domain): JsonResponse
56+
#[Delete('{domain}', name: 'api.projects.domains.destroy', middleware: 'ability:write')]
57+
public function destroy(Project $project, Domain $domain): JsonResponse
5558
{
5659
$this->authorize('delete', $domain);
5760

61+
$this->validateRoute($project, $domain);
62+
5863
app(RemoveDomain::class)->remove($domain);
5964

6065
return response()->json(['message' => 'Domain removed successfully']);
6166
}
6267

63-
#[Get('{dnsProvider}/available', name: 'api.domains.available', middleware: 'ability:read')]
64-
public function availableDomains(DNSProvider $dnsProvider): JsonResponse
68+
private function validateRoute(Project $project, Domain $domain): void
6569
{
66-
$this->authorize('view', $dnsProvider);
67-
68-
$domains = $dnsProvider->provider()->getDomains();
69-
70-
return response()->json($domains);
70+
if ($project->id !== $domain->project_id) {
71+
abort(404, 'Domain not found in project');
72+
}
7173
}
7274
}

app/Http/Controllers/DomainController.php

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,24 +27,28 @@ class DomainController extends Controller
2727
#[Get('/', name: 'domains')]
2828
public function index(): Response
2929
{
30-
$this->authorize('viewAny', Domain::class);
31-
3230
$user = user();
3331

32+
$this->authorize('viewAny', [Domain::class, $user->currentProject]);
33+
34+
$domains = $user->currentProject->domains()->latest()->with('dnsProvider')->simplePaginate(config('web.pagination_size'));
35+
3436
return Inertia::render('domains/index', [
35-
'domains' => DomainResource::collection(Domain::getByProjectId($user->current_project_id, $user)->with('dnsProvider')->simplePaginate(config('web.pagination_size'))),
37+
'domains' => DomainResource::collection($domains),
3638
'dnsProviders' => DNSProvider::getByProjectId($user->current_project_id, $user)->where('connected', true)->get(),
3739
]);
3840
}
3941

4042
#[Get('/json', name: 'domains.json')]
4143
public function json(): ResourceCollection
4244
{
43-
$this->authorize('viewAny', Domain::class);
44-
4545
$user = user();
4646

47-
return DomainResource::collection(Domain::getByProjectId($user->current_project_id, $user)->with('dnsProvider')->get());
47+
$this->authorize('viewAny', [Domain::class, $user->currentProject]);
48+
49+
$domains = $user->currentProject->domains()->with('dnsProvider')->orderByDesc('id')->get();
50+
51+
return DomainResource::collection($domains);
4852
}
4953

5054
#[Get('/{dnsProvider}/available', name: 'domains.available')]
@@ -60,9 +64,11 @@ public function availableDomains(DNSProvider $dnsProvider): JsonResponse
6064
#[Post('/', name: 'domains.store')]
6165
public function store(Request $request): RedirectResponse
6266
{
63-
$this->authorize('create', Domain::class);
67+
$user = user();
68+
69+
$this->authorize('create', [Domain::class, $user->currentProject]);
6470

65-
app(AddDomain::class)->add(user(), $request->all());
71+
app(AddDomain::class)->add($user, $user->currentProject, $request->all());
6672

6773
return back()->with('success', 'Domain added.');
6874
}

app/Http/Controllers/Workflow/WorkflowController.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
use Spatie\RouteAttributes\Attributes\Put;
2121

2222
#[Prefix('workflows')]
23-
#[Middleware('auth')]
23+
#[Middleware(['auth', 'has-project'])]
2424
class WorkflowController extends Controller
2525
{
2626
#[Get('/', name: 'workflows')]

app/Http/Controllers/Workflow/WorkflowRunController.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
use Spatie\RouteAttributes\Attributes\Prefix;
1818

1919
#[Prefix('workflows/{workflow}/runs')]
20-
#[Middleware('auth')]
20+
#[Middleware(['auth', 'has-project'])]
2121
class WorkflowRunController extends Controller
2222
{
2323
#[Get('/', name: 'workflow-runs')]

app/Models/Domain.php

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
namespace App\Models;
44

55
use Database\Factories\DomainFactory;
6-
use Illuminate\Database\Eloquent\Builder;
76
use Illuminate\Database\Eloquent\Factories\HasFactory;
87
use Illuminate\Database\Eloquent\Relations\BelongsTo;
98
use Illuminate\Database\Eloquent\Relations\HasMany;
@@ -13,11 +12,13 @@
1312
/**
1413
* @property int $dns_provider_id
1514
* @property int $user_id
15+
* @property int $project_id
1616
* @property string $domain
1717
* @property string $provider_domain_id
1818
* @property array<string, mixed> $metadata
1919
* @property DNSProvider $dnsProvider
2020
* @property User $user
21+
* @property Project $project
2122
* @property DNSRecord[] $records
2223
*/
2324
class Domain extends AbstractModel
@@ -28,6 +29,7 @@ class Domain extends AbstractModel
2829
protected $fillable = [
2930
'dns_provider_id',
3031
'user_id',
32+
'project_id',
3133
'domain',
3234
'provider_domain_id',
3335
'metadata',
@@ -36,6 +38,7 @@ class Domain extends AbstractModel
3638
protected $casts = [
3739
'dns_provider_id' => 'integer',
3840
'user_id' => 'integer',
41+
'project_id' => 'integer',
3942
'metadata' => 'array',
4043
];
4144

@@ -56,28 +59,19 @@ public function user(): BelongsTo
5659
}
5760

5861
/**
59-
* @return HasMany<DNSRecord, covariant $this>
62+
* @return BelongsTo<Project, covariant $this>
6063
*/
61-
public function records(): HasMany
64+
public function project(): BelongsTo
6265
{
63-
return $this->hasMany(DNSRecord::class);
66+
return $this->belongsTo(Project::class);
6467
}
6568

6669
/**
67-
* @return Builder<Domain>
70+
* @return HasMany<DNSRecord, covariant $this>
6871
*/
69-
public static function getByProjectId(int $projectId, User $user): Builder
72+
public function records(): HasMany
7073
{
71-
/** @var Builder<Domain> $query */
72-
$query = static::query();
73-
74-
return $query
75-
->where('user_id', $user->id)
76-
->whereHas('dnsProvider', function (Builder $query) use ($projectId): void {
77-
$query->where(function (Builder $query) use ($projectId): void {
78-
$query->where('project_id', $projectId)->orWhereNull('project_id');
79-
});
80-
});
74+
return $this->hasMany(DNSRecord::class);
8175
}
8276

8377
public function syncDnsRecords(): void

0 commit comments

Comments
 (0)