diff --git a/app/Http/Controllers/PlanController.php b/app/Http/Controllers/PlanController.php index 3de2390..cca200a 100644 --- a/app/Http/Controllers/PlanController.php +++ b/app/Http/Controllers/PlanController.php @@ -7,6 +7,7 @@ use App\Models\User; use Illuminate\Contracts\View\Factory as ViewFactory; use Illuminate\Contracts\View\View; use Illuminate\Http\Request; +use Illuminate\Support\Facades\Gate; class PlanController extends Controller { @@ -41,6 +42,15 @@ class PlanController extends Controller public function edit(Plan $plan): View|ViewFactory { + if (! $this->canEditPlan($plan)) { + abort(403, 'Unauthorized action.'); + } + return view('plan/edit_form', ['plan' => $plan]); } + + private function canEditPlan(Plan $plan): bool + { + return Gate::allows('edit', $plan); + } } diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php index d714ca7..ed8cdac 100644 --- a/app/Http/Kernel.php +++ b/app/Http/Kernel.php @@ -38,7 +38,6 @@ class Kernel extends HttpKernel \App\Http\Middleware\VerifyCsrfToken::class, \Illuminate\Routing\Middleware\SubstituteBindings::class, ], - 'api' => [ // \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class, 'throttle:api', @@ -68,5 +67,8 @@ class Kernel extends HttpKernel 'localeSessionRedirect' => \Mcamara\LaravelLocalization\Middleware\LocaleSessionRedirect::class, 'localeCookieRedirect' => \Mcamara\LaravelLocalization\Middleware\LocaleCookieRedirect::class, 'localeViewPath' => \Mcamara\LaravelLocalization\Middleware\LaravelLocalizationViewPath::class, + 'role' => \Spatie\Permission\Middleware\RoleMiddleware::class, + 'permission' => \Spatie\Permission\Middleware\PermissionMiddleware::class, + 'role_or_permission' => \Spatie\Permission\Middleware\RoleOrPermissionMiddleware::class, ]; } diff --git a/app/Livewire/Plan/Create.php b/app/Livewire/Plan/Create.php index 4fd3d68..695833f 100644 --- a/app/Livewire/Plan/Create.php +++ b/app/Livewire/Plan/Create.php @@ -77,7 +77,7 @@ class Create extends Component $this->isVisibleState = false; } - public function addPacketOption(array $options_type, array $options_type_input): void + public function addPacketOption(string $options_type, string $options_type_input): void { $this->$options_type['short'] = $this->$options_type_input['short']; $this->$options_type['price'] = $this->$options_type_input['price']; diff --git a/app/Policies/PlanPolicy.php b/app/Policies/PlanPolicy.php new file mode 100755 index 0000000..8fb8047 --- /dev/null +++ b/app/Policies/PlanPolicy.php @@ -0,0 +1,19 @@ +isAuthorPlan($user, $plan) || $user->hasRole('admin') || $user->hasRole('moderator'); + } + + private function isAuthorPlan(User $user, Plan $plan): bool + { + return $user->id === $plan->author->first()->id; + } +} diff --git a/app/Providers/AuthServiceProvider.php b/app/Providers/AuthServiceProvider.php index d7e6b4a..060f28c 100644 --- a/app/Providers/AuthServiceProvider.php +++ b/app/Providers/AuthServiceProvider.php @@ -2,6 +2,8 @@ namespace App\Providers; +use App\Models\Plan; +use App\Policies\PlanPolicy; use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider; class AuthServiceProvider extends ServiceProvider @@ -12,6 +14,7 @@ class AuthServiceProvider extends ServiceProvider * @var array */ protected $policies = [ + Plan::class => PlanPolicy::class, // 'App\Models\Model' => 'App\Policies\ModelPolicy', ]; diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php index f58c5d8..6bfdf4f 100644 --- a/database/seeders/DatabaseSeeder.php +++ b/database/seeders/DatabaseSeeder.php @@ -21,5 +21,6 @@ class DatabaseSeeder extends Seeder $this->call(DietsSeeder::class); $this->call(BlogPostSeeder::class); $this->call(ProductNutritionalSeeder::class); + $this->call(RolesAndPermissionsSeeder::class); } } diff --git a/database/seeders/RolesAndPermissionsSeeder.php b/database/seeders/RolesAndPermissionsSeeder.php new file mode 100644 index 0000000..61e8112 --- /dev/null +++ b/database/seeders/RolesAndPermissionsSeeder.php @@ -0,0 +1,26 @@ +forgetCachedPermissions(); + + Permission::create(['name' => 'edit_plan']); + + $role = Role::create(['name' => 'admin']); + $role->givePermissionTo(Permission::all()); + + $role = Role::create(['name' => 'moderator']); + $role->givePermissionTo(Permission::all()); + + $role = Role::create(['name' => 'consultant']); + $role->givePermissionTo(Permission::all()); + } +} diff --git a/tests/Feature/Plan/EditTest.php b/tests/Feature/Plan/EditTest.php index e15121a..a75bd88 100644 --- a/tests/Feature/Plan/EditTest.php +++ b/tests/Feature/Plan/EditTest.php @@ -32,11 +32,14 @@ class EditTest extends TestCase $this->plan = Plan::factory()->create(); } - public function test_show_form_edit_plan(): void + public function test_show_form_edit_plan_success_for_author(): void { + $plan = $this->plan; + $plan->author()->attach($this->user->id); + $response = $this ->actingAs($this->user) - ->get(route('plan.edit', $this->plan)); + ->get(route('plan.edit', $plan)); $response->assertSuccessful(); }