Skip to content

Commit 9cc4e05

Browse files
committed
🐛 destructive operations gates
1 parent aab3ab5 commit 9cc4e05

File tree

5 files changed

+189
-0
lines changed

5 files changed

+189
-0
lines changed

src/Concerns/PerformsRestOperations.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,9 @@ public function destroy(DestroyRequest $request)
140140

141141
foreach ($models as $model) {
142142
self::newResource()->authorizeTo('delete', $model);
143+
}
143144

145+
foreach ($models as $model) {
144146
$resource->destroying($request, $model);
145147

146148
$resource->performDelete($request, $model);
@@ -177,7 +179,9 @@ public function restore(RestoreRequest $request)
177179

178180
foreach ($models as $model) {
179181
self::newResource()->authorizeTo('restore', $model);
182+
}
180183

184+
foreach ($models as $model) {
181185
$resource->restoring($request, $model);
182186

183187
$resource->performRestore($request, $model);
@@ -215,7 +219,9 @@ public function forceDelete(ForceDestroyRequest $request)
215219

216220
foreach ($models as $model) {
217221
self::newResource()->authorizeTo('forceDelete', $model);
222+
}
218223

224+
foreach ($models as $model) {
219225
$resource->forceDestroying($request, $model);
220226

221227
$resource->performForceDelete($request, $model);

tests/Feature/Controllers/DeleteOperationsTest.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
use Lomkit\Rest\Tests\Support\Models\SoftDeletedModel;
1111
use Lomkit\Rest\Tests\Support\Policies\GreenPolicy;
1212
use Lomkit\Rest\Tests\Support\Policies\RedPolicy;
13+
use Lomkit\Rest\Tests\Support\Policies\RedPolicyButForModel;
1314
use Lomkit\Rest\Tests\Support\Rest\Resources\ModelResource;
1415
use Lomkit\Rest\Tests\Support\Rest\Resources\SoftDeletedModelResource;
1516

@@ -33,6 +34,28 @@ public function test_deleting_a_non_authorized_model(): void
3334
$response->assertJson(['message' => 'This action is unauthorized.']);
3435
}
3536

37+
public function test_deleting_a_non_authorized_model_with_an_authorized_one(): void
38+
{
39+
$model = ModelFactory::new()->count(1)->createOne();
40+
$modelDeletable = ModelFactory::new()->count(1)->createOne();
41+
42+
RedPolicyButForModel::forModel($modelDeletable);
43+
Gate::policy(Model::class, RedPolicyButForModel::class);
44+
45+
$response = $this->delete(
46+
'/api/models',
47+
[
48+
'resources' => [$model->getKey(), $modelDeletable->getKey()],
49+
],
50+
['Accept' => 'application/json']
51+
);
52+
53+
$response->assertStatus(403);
54+
$response->assertJson(['message' => 'This action is unauthorized.']);
55+
$this->assertDatabaseHas('models', $model->only('id'));
56+
$this->assertDatabaseHas('models', $modelDeletable->only('id'));
57+
}
58+
3659
public function test_deleting_a_model(): void
3760
{
3861
$model = ModelFactory::new()->count(1)->createOne();

tests/Feature/Controllers/ForceDeleteOperationsTest.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use Lomkit\Rest\Tests\Support\Models\SoftDeletedModel;
99
use Lomkit\Rest\Tests\Support\Policies\GreenPolicy;
1010
use Lomkit\Rest\Tests\Support\Policies\RedPolicy;
11+
use Lomkit\Rest\Tests\Support\Policies\RedPolicyButForModel;
1112
use Lomkit\Rest\Tests\Support\Rest\Resources\SoftDeletedModelResource;
1213

1314
class ForceDeleteOperationsTest extends TestCase
@@ -30,6 +31,28 @@ public function test_force_deleting_a_non_authorized_model(): void
3031
$response->assertJson(['message' => 'This action is unauthorized.']);
3132
}
3233

34+
public function test_force_deleting_a_non_authorized_model_with_an_authorized_one(): void
35+
{
36+
$model = SoftDeletedModelFactory::new()->count(1)->trashed()->createOne();
37+
$modelForceDeletable = SoftDeletedModelFactory::new()->count(1)->trashed()->createOne();
38+
39+
RedPolicyButForModel::forModel($modelForceDeletable);
40+
Gate::policy(SoftDeletedModel::class, RedPolicyButForModel::class);
41+
42+
$response = $this->delete(
43+
'/api/soft-deleted-models/force',
44+
[
45+
'resources' => [$model->getKey(), $modelForceDeletable->getKey()],
46+
],
47+
['Accept' => 'application/json']
48+
);
49+
50+
$response->assertStatus(403);
51+
$response->assertJson(['message' => 'This action is unauthorized.']);
52+
$this->assertSoftDeleted($model);
53+
$this->assertSoftDeleted($modelForceDeletable);
54+
}
55+
3356
public function test_force_deleting_a_soft_deleted_model(): void
3457
{
3558
$softDeletedModel = SoftDeletedModelFactory::new()->count(1)->trashed()->createOne();

tests/Feature/Controllers/RestoreOperationsTest.php

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,13 @@
44

55
use Illuminate\Support\Facades\Gate;
66
use Lomkit\Rest\Tests\Feature\TestCase;
7+
use Lomkit\Rest\Tests\Support\Database\Factories\ModelFactory;
78
use Lomkit\Rest\Tests\Support\Database\Factories\SoftDeletedModelFactory;
9+
use Lomkit\Rest\Tests\Support\Models\Model;
810
use Lomkit\Rest\Tests\Support\Models\SoftDeletedModel;
911
use Lomkit\Rest\Tests\Support\Policies\GreenPolicy;
1012
use Lomkit\Rest\Tests\Support\Policies\RedPolicy;
13+
use Lomkit\Rest\Tests\Support\Policies\RedPolicyButForModel;
1114
use Lomkit\Rest\Tests\Support\Rest\Resources\SoftDeletedModelResource;
1215

1316
class RestoreOperationsTest extends TestCase
@@ -30,6 +33,34 @@ public function test_restoring_a_non_authorized_model(): void
3033
$response->assertJson(['message' => 'This action is unauthorized.']);
3134
}
3235

36+
public function test_restoring_a_non_authorized_model_with_an_authorized_one(): void
37+
{
38+
$model = SoftDeletedModelFactory::new()->count(1)->trashed()->createOne();
39+
$modelRestorable = SoftDeletedModelFactory::new()->count(1)->trashed()->createOne();
40+
41+
RedPolicyButForModel::forModel($modelRestorable);
42+
Gate::policy(SoftDeletedModel::class, RedPolicyButForModel::class);
43+
44+
$response = $this->post(
45+
'/api/soft-deleted-models/restore',
46+
[
47+
'resources' => [$model->getKey(), $modelRestorable->getKey()],
48+
],
49+
['Accept' => 'application/json']
50+
);
51+
52+
$response->assertStatus(403);
53+
$response->assertJson(['message' => 'This action is unauthorized.']);
54+
$this->assertNotEquals(
55+
null,
56+
$modelRestorable->fresh()->deleted_at,
57+
);
58+
$this->assertNotEquals(
59+
null,
60+
$model->fresh()->deleted_at,
61+
);
62+
}
63+
3364
public function test_restoring_a_soft_deleted_model(): void
3465
{
3566
$softDeletedModel = SoftDeletedModelFactory::new()->count(1)->trashed()->createOne();
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
<?php
2+
3+
namespace Lomkit\Rest\Tests\Support\Policies;
4+
5+
use Illuminate\Auth\Access\HandlesAuthorization;
6+
use Illuminate\Database\Eloquent\Model;
7+
8+
class RedPolicyButForModel
9+
{
10+
use HandlesAuthorization;
11+
12+
static Model $model;
13+
14+
public static function forModel(Model $model) {
15+
static::$model = $model;
16+
}
17+
18+
/**
19+
* Determine whether the user can view the list of models.
20+
*
21+
* @param $user
22+
*
23+
* @return bool
24+
*/
25+
public function viewAny($user)
26+
{
27+
return false;
28+
}
29+
30+
/**
31+
* Determine whether the user can view the model.
32+
*
33+
* @param $user
34+
* @param Model $model
35+
*
36+
* @return bool
37+
*/
38+
public function view($user, Model $model)
39+
{
40+
return static::$model->is($model);
41+
}
42+
43+
/**
44+
* Determine whether the user can create models.
45+
*
46+
* @param $user
47+
*
48+
* @return bool
49+
*/
50+
public function create($user)
51+
{
52+
return false;
53+
}
54+
55+
/**
56+
* Determine whether the user can update the model.
57+
*
58+
* @param $user
59+
* @param Model $model
60+
*
61+
* @return bool
62+
*/
63+
public function update($user, Model $model)
64+
{
65+
return static::$model->is($model);
66+
}
67+
68+
/**
69+
* Determine whether the user can delete the model.
70+
*
71+
* @param $user
72+
* @param Model $model
73+
*
74+
* @return bool
75+
*/
76+
public function delete($user, Model $model)
77+
{
78+
return static::$model->is($model);
79+
}
80+
81+
/**
82+
* Determine whether the user can restore the model.
83+
*
84+
* @param $user
85+
* @param Model $model
86+
*
87+
* @return bool
88+
*/
89+
public function restore($user, Model $model)
90+
{
91+
return static::$model->is($model);
92+
}
93+
94+
/**
95+
* Determine whether the user can permanently delete the model.
96+
*
97+
* @param $user
98+
* @param Model $model
99+
*
100+
* @return bool
101+
*/
102+
public function forceDelete($user, Model $model)
103+
{
104+
return static::$model->is($model);
105+
}
106+
}

0 commit comments

Comments
 (0)