Skip to content

Commit

Permalink
Restrict users from updating and deleting all posts but their own
Browse files Browse the repository at this point in the history
  • Loading branch information
antimech committed Nov 8, 2023
1 parent 975f48b commit 011a03e
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 34 deletions.
14 changes: 13 additions & 1 deletion app/Http/Controllers/Posts/UserController.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class UserController extends Controller
public function index(): View
{
return view('posts.index', [
'posts' => Post::orderBy('id', 'desc')->paginate(10)
'posts' => request()->user()->posts()->orderBy('id', 'desc')->paginate(10)
]);
}

Expand Down Expand Up @@ -58,19 +58,27 @@ public function show(Post $post): View

/**
* Show the form for editing the specified resource.
*
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function edit(Post $post): View
{
$this->authorize('update', $post);

return view('posts.edit', [
'post' => $post
]);
}

/**
* Update the specified resource in storage.
*
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function update(Request $request, Post $post): RedirectResponse
{
$this->authorize('update', $post);

$this->validate($request, [
'title' => 'required|string|max:255',
'body' => 'required|string'
Expand All @@ -85,9 +93,13 @@ public function update(Request $request, Post $post): RedirectResponse

/**
* Remove the specified resource from storage.
*
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function destroy(Post $post): RedirectResponse
{
$this->authorize('forceDelete', $post);

$post->delete();

return redirect()->route('posts.index');
Expand Down
66 changes: 66 additions & 0 deletions app/Policies/PostPolicy.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<?php

namespace App\Policies;

use App\Models\Post;
use App\Models\User;
use Illuminate\Auth\Access\Response;

class PostPolicy
{
/**
* Determine whether the user can view any models.
*/
public function viewAny(User $user): bool
{
//
}

/**
* Determine whether the user can view the model.
*/
public function view(User $user, Post $post): bool
{
//
}

/**
* Determine whether the user can create models.
*/
public function create(User $user): bool
{
//
}

/**
* Determine whether the user can update the model.
*/
public function update(User $user, Post $post): bool
{
return $user->id === $post->user_id;
}

/**
* Determine whether the user can delete the model.
*/
public function delete(User $user, Post $post): bool
{
return $user->id === $post->user_id;
}

/**
* Determine whether the user can restore the model.
*/
public function restore(User $user, Post $post): bool
{
return $user->id === $post->user_id;
}

/**
* Determine whether the user can permanently delete the model.
*/
public function forceDelete(User $user, Post $post): bool
{
return $user->id === $post->user_id;
}
}
70 changes: 37 additions & 33 deletions resources/views/posts/show.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,39 +20,43 @@
</p>
</div>

<a href="{{ route('posts.edit', $post) }}" class="inline-flex items-center px-4 py-2 bg-blue-600 border border-transparent rounded-md font-semibold text-xs text-white uppercase tracking-widest hover:bg-blue-500 active:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 dark:focus:ring-offset-gray-800 transition ease-in-out duration-150">
{{ __('Edit') }}
</a>

<x-danger-button
x-data=""
x-on:click.prevent="$dispatch('open-modal', 'confirm-post-deletion')"
>{{ __('Delete') }}</x-danger-button>

<x-modal name="confirm-post-deletion" :show="$errors->userDeletion->isNotEmpty()" focusable>
<form method="post" action="{{ route('posts.destroy', $post) }}" class="p-6">
@csrf
@method('delete')

<h2 class="text-lg font-medium text-gray-900 dark:text-gray-100">
{{ __('Are you sure you want to delete this post?') }}
</h2>

<p class="mt-1 text-sm text-gray-600 dark:text-gray-400">
{{ __('Once this post is deleted, all of its resources and data will be permanently deleted.') }}
</p>

<div class="mt-6 flex justify-end">
<x-secondary-button x-on:click="$dispatch('close')">
{{ __('Cancel') }}
</x-secondary-button>

<x-danger-button class="ml-3">
{{ __('Delete Post') }}
</x-danger-button>
</div>
</form>
</x-modal>
@can('update', $post)
<a href="{{ route('posts.edit', $post) }}" class="inline-flex items-center px-4 py-2 bg-blue-600 border border-transparent rounded-md font-semibold text-xs text-white uppercase tracking-widest hover:bg-blue-500 active:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 dark:focus:ring-offset-gray-800 transition ease-in-out duration-150">
{{ __('Edit') }}
</a>
@endcan

@can('delete', $post)
<x-danger-button
x-data=""
x-on:click.prevent="$dispatch('open-modal', 'confirm-post-deletion')"
>{{ __('Delete') }}</x-danger-button>

<x-modal name="confirm-post-deletion" :show="$errors->userDeletion->isNotEmpty()" focusable>
<form method="post" action="{{ route('posts.destroy', $post) }}" class="p-6">
@csrf
@method('delete')

<h2 class="text-lg font-medium text-gray-900 dark:text-gray-100">
{{ __('Are you sure you want to delete this post?') }}
</h2>

<p class="mt-1 text-sm text-gray-600 dark:text-gray-400">
{{ __('Once this post is deleted, all of its resources and data will be permanently deleted.') }}
</p>

<div class="mt-6 flex justify-end">
<x-secondary-button x-on:click="$dispatch('close')">
{{ __('Cancel') }}
</x-secondary-button>

<x-danger-button class="ml-3">
{{ __('Delete Post') }}
</x-danger-button>
</div>
</form>
</x-modal>
@endcan
</div>
</div>
</div>
Expand Down

0 comments on commit 011a03e

Please sign in to comment.