diff --git a/.env.example b/.env.example index 92866ac..0e8c791 100644 --- a/.env.example +++ b/.env.example @@ -8,12 +8,12 @@ LOG_CHANNEL=stack LOG_DEPRECATIONS_CHANNEL=null LOG_LEVEL=debug -DB_CONNECTION=mysql -DB_HOST=127.0.0.1 -DB_PORT=3306 -DB_DATABASE=laravel -DB_USERNAME=root -DB_PASSWORD= +DB_CONNECTION=sqlite +#DB_HOST=127.0.0.1 +#DB_PORT=3306 +#DB_DATABASE=laravel +#DB_USERNAME=root +#DB_PASSWORD= BROADCAST_DRIVER=log CACHE_DRIVER=file diff --git a/README.md b/README.md index 13cdf6a..2423756 100644 --- a/README.md +++ b/README.md @@ -4,8 +4,21 @@ This is a simple app to demonstrate implementing the spatie/laravel-permission p Many of the code examples used in this demo also come from the examples in the Spatie package README. +## Running Demo +``` +composer install +npm install +# Setup your .env file, provided .env.example will work for sqlite +cp -n .env.example .env +touch database/database.sqlite +php artisan key:generate +php artisan db:seed + +# Run Dev Server +php artisan serve +``` -## Creating Your Own Demo +## Creating Your Own Demo From Scratch You could create your own with the following steps: Initial setup: diff --git a/app/Http/Controllers/ExamplesController.php b/app/Http/Controllers/ExamplesController.php index 7c3d228..107353b 100644 --- a/app/Http/Controllers/ExamplesController.php +++ b/app/Http/Controllers/ExamplesController.php @@ -9,9 +9,8 @@ class ExamplesController extends Controller { public function show_my_roles() { -// $user = auth()->user(); -// or - $user = User::first(); + + $user = auth()->user(); $roles = $user->getRoleNames(); return var_export($roles, true); diff --git a/app/Models/Post.php b/app/Models/Post.php index 694c1de..44a415e 100644 --- a/app/Models/Post.php +++ b/app/Models/Post.php @@ -18,7 +18,12 @@ class Post extends Model public function scopePublished(Builder $query) { - return $query->where('published', 1); + //view unpublished posts if user has permission to + if(!auth()->user()?->getAllPermissions()->pluck('name')->contains('view unpublished posts')) + { + return $query->where('published', 1); + } + } public function author() diff --git a/app/Policies/PostPolicy.php b/app/Policies/PostPolicy.php index 60015ad..4748435 100644 --- a/app/Policies/PostPolicy.php +++ b/app/Policies/PostPolicy.php @@ -70,8 +70,8 @@ public function create(User $user) */ public function update(User $user, Post $post) { - if ($user->can('edit own posts')) { - return $user->id == $post->user_id; + if ($user->id == $post->user_id) { + return true; } if ($user->can('edit all posts')) { diff --git a/database/seeders/PermissionsDemoSeeder.php b/database/seeders/PermissionsDemoSeeder.php index 4375e03..c2a1dd3 100644 --- a/database/seeders/PermissionsDemoSeeder.php +++ b/database/seeders/PermissionsDemoSeeder.php @@ -3,6 +3,8 @@ namespace Database\Seeders; // use Illuminate\Database\Console\Seeds\WithoutModelEvents; +use App\Models\Post; +use App\Models\User; use Illuminate\Database\Seeder; use Spatie\Permission\Models\Permission; use Spatie\Permission\Models\Role; @@ -10,46 +12,94 @@ class PermissionsDemoSeeder extends Seeder { + protected User $author; + protected User $admin; + protected User $member; + /** - * Create some roles and permissions. + * Create some roles and permissions, users, posts */ public function run(): void + { + + $this->setupPermissions(); + $this->setupUsers(); + $this->setupPosts(); + + } + + protected function setupPermissions(): void { // Reset cached roles and permissions app()[PermissionRegistrar::class]->forgetCachedPermissions(); - // create permissions - Permission::create(['name' => 'edit articles']); - Permission::create(['name' => 'delete articles']); - Permission::create(['name' => 'publish articles']); - Permission::create(['name' => 'unpublish articles']); - - // create roles and assign existing permissions - $role1 = Role::create(['name' => 'Writer']); - $role1->givePermissionTo('edit articles'); - $role1->givePermissionTo('delete articles'); - - $role2 = Role::create(['name' => 'Admin']); - $role2->givePermissionTo('publish articles'); - $role2->givePermissionTo('unpublish articles'); - - // create a demo user - $user = \App\Models\User::factory()->create([ - 'name' => 'Example User', - 'email' => 'test@example.com', - ]); - $user->assignRole($role1); - - - // super admin - Permission::create(['name' => 'assign roles']); - $role3 = Role::create(['name' => 'Super-Admin']); - $role3->givePermissionTo('assign roles'); - $admin = \App\Models\User::factory()->create([ - 'name' => 'Admin User', - 'email' => 'admin@example.com', - ]); - $admin->assignRole('Super-Admin'); + Permission::findOrCreate('view unpublished posts'); + Permission::findOrCreate('create posts'); + Permission::findOrCreate('edit own posts'); + Permission::findOrCreate('edit all posts'); + Permission::findOrCreate('delete own posts'); + Permission::findOrCreate('delete any post'); + + Role::findOrCreate('author') + ->givePermissionTo(['create posts', 'edit own posts', 'delete own posts']); + + Role::findOrCreate('admin') + ->givePermissionTo(['view unpublished posts', 'create posts', 'edit all posts', 'delete any post']); + } + + protected function setupUsers(): void + { + + + $this->author = User::factory()->create([ + 'name' => 'Example Author', + 'email' => 'author@example.com', + ]); + $this->author->assignRole('author'); + + $this->admin = User::factory()->create([ + 'name' => 'Admin User', + 'email' => 'admin@example.com', + ]); + $this->admin->assignRole('admin'); + + $this->member = User::factory()->create([ + 'name' => 'Example Member', + 'email' => 'member@example.com', + ]); + } + + protected function setupPosts() + { + Post::factory()->create([ + 'title' => 'This is the first post. (author)', + 'published' => 1, + 'user_id' => $this->author->id, + ]); + + Post::factory()->create([ + 'title' => 'This is the second post. (admin)', + 'published' => 1, + 'user_id' => $this->admin->id, + ]); + + Post::factory()->create([ + 'title' => 'This is the third post. (author)', + 'published' => 1, + 'user_id' => $this->author->id, + ]); + + Post::factory()->create([ + 'title' => 'This is the fourth post. (admin, unpublished)', + 'published' => 0, + 'user_id' => $this->admin->id, + ]); + + Post::factory()->create([ + 'title' => 'This is the fifth post. (member)', + 'published' => 1, + 'user_id' => $this->member->id, + ]); } } diff --git a/resources/views/permissions-demo.blade.php b/resources/views/permissions-demo.blade.php index 9577137..b1dc8f9 100644 --- a/resources/views/permissions-demo.blade.php +++ b/resources/views/permissions-demo.blade.php @@ -1,11 +1,20 @@ -@hasrole('writer') -

You have been assigned the [writer] role.

+@hasrole('author') +

You have been assigned the [author] role.

@else -

You do NOT have the writer role.

+

You do NOT have the author role.

@endhasrole -@can('edit articles') +@can('edit all posts')

You have permission to [edit articles].

@else

Sorry, you may NOT edit articles.

@endcan + + +
+ +
diff --git a/resources/views/posts/edit.blade.php b/resources/views/posts/edit.blade.php index e6bb02c..19a1527 100644 --- a/resources/views/posts/edit.blade.php +++ b/resources/views/posts/edit.blade.php @@ -1,2 +1,4 @@ This would be the edit form for the post: {{ $post->title }} + +

If you didn't have the edit articles PERMISSION that the "Writer" ROLE provides you would get a 403 error instead of this page. Try that out by logging in as admin account which won't have this permission and will return a 403 error.

diff --git a/resources/views/posts/index.blade.php b/resources/views/posts/index.blade.php index 395c798..dc4300c 100644 --- a/resources/views/posts/index.blade.php +++ b/resources/views/posts/index.blade.php @@ -1,3 +1,13 @@ +@can('edit all posts') +

You have permission to [edit all posts]. Clicking Edit Post below will return a edit page

+@else +

You do NOT have permission to [edit all posts]. Clicking edit below will return a 403 Error UNLESS you own the post. For guests they will get a redirect to login page

+@endcan + @foreach($posts as $p) -

{{ $p->id }}. {{ $p->title }}

+

{{ $p->id }}. {{ $p->title }} (Edit Post)

@endforeach + +

+ Back to Demo Home Page +

diff --git a/resources/views/posts/show.blade.php b/resources/views/posts/show.blade.php index 6dcdee1..5aaa12c 100644 --- a/resources/views/posts/show.blade.php +++ b/resources/views/posts/show.blade.php @@ -1 +1,10 @@ -{{ $post->title }} +

Title: {{ $post->title }}

+

{{ $post->body }}

+ +@can('edit articles') +

Edit Post

+@endcan + +

+ Back to Demo Home Page +

diff --git a/resources/views/welcome.blade.php b/resources/views/welcome.blade.php index 4352a54..d4377d0 100644 --- a/resources/views/welcome.blade.php +++ b/resources/views/welcome.blade.php @@ -16,7 +16,7 @@ -
+
@if (Route::has('login'))
@auth @@ -41,10 +41,48 @@
- @include('permissions-demo') + @hasrole('admin') +

You have been assigned the [admin] role.

+ @else +

You do NOT have the admin role.

+ @endhasrole + + @can('edit all posts') +

You have permission to [edit all posts].

+ @else +

Sorry, you may NOT edit [edit all posts].

+ @endcan
+ +
+
+

Example Accounts:

+
+

Admin Account with [admin] role

+

User: admin@example.com

+

Password: password

+
+
+

Author Account with [author] role

+

User: author@example.com

+

Password: password

+
+
+

Normal Account with No Permissions

+

User: member@example.com

+

Password: password

+
+ +
+

+ View Demo +

+ +

+ View Posts As Guest User +

diff --git a/tests/Feature/ExamplesTest.php b/tests/Feature/ExamplesTest.php index 6875770..63770d7 100644 --- a/tests/Feature/ExamplesTest.php +++ b/tests/Feature/ExamplesTest.php @@ -21,6 +21,6 @@ public function it_responds_to_show_my_roles() $response->assertStatus(200); $response->assertSee('Collection'); - $response->assertSee('Writer'); + $response->assertSee('author'); } } diff --git a/tests/Feature/PermissionsDemoTest.php b/tests/Feature/PermissionsDemoTest.php index 6a42f07..ece9c19 100644 --- a/tests/Feature/PermissionsDemoTest.php +++ b/tests/Feature/PermissionsDemoTest.php @@ -16,8 +16,8 @@ public function setUp(): void { parent::setUp(); - $permission = Permission::create(['name' => 'edit articles']); - $role1 = Role::create(['name' => 'writer']); + $permission = Permission::create(['name' => 'edit all posts']); + $role1 = Role::create(['name' => 'admin']); $role1->givePermissionTo($permission->name); } @@ -28,7 +28,7 @@ public function it_recognizes_blade_hasrole_directive() { $response = $this->get('/'); - $response->assertSeeText('writer'); + $response->assertSeeText('admin'); $response->assertDontSeeText('@hasrole'); } @@ -39,7 +39,7 @@ public function it_shows_message_confirming_permission_is_not_granted() { $response = $this->get('/'); - $response->assertSeeText('Sorry, you may NOT edit articles.'); + $response->assertSeeText('Sorry, you may NOT edit [edit all posts]'); } /** @@ -48,13 +48,13 @@ public function it_shows_message_confirming_permission_is_not_granted() public function it_shows_message_confirming_permission_is_granted() { $user = \App\Models\User::factory()->create(); - $user->assignRole('writer'); + $user->assignRole('admin'); $response = $this->actingAs(\App\Models\User::find($user->id))->get('/'); $response->assertDontSeeText('@hasrole'); - $response->assertSeeText("You have permission to [edit articles]."); + $response->assertSeeText("You have permission to [edit all posts]."); } }