kazak71/nova-permissions

Laravel Nova 4 分组权限

dev-master / 1.0.x-dev 2024-03-14 09:33 UTC

This package is auto-updated.

Last update: 2024-09-14 10:49:05 UTC


README

一个 Laravel Nova 工具,允许您分组权限并将其附加到用户。它使用 Spatie 的 laravel-permission。

我们有一个迁移、种子、策略和资源,为良好的授权体验做好准备。

  1. 安装
  2. 带有组的权限
  3. 自定义
  4. 致谢

安装

您可以通过 composer 在使用 Nova 的 Laravel 应用中安装此包

composer require sereny/nova-permissions

使用以下命令发布迁移:

php artisan vendor:publish --provider="Sereny\NovaPermissions\ToolServiceProvider" --tag="migrations"

迁移数据库

php artisan migrate

接下来,您必须将工具注册到 Nova 中。这通常在 NovaServiceProvidertools 方法中完成。

// in app/Providers/NovaServiceProvider.php

// ...

public function tools()
{
    return [
        // ...
        new \Sereny\NovaPermissions\NovaPermissions(),
    ];
}

如果您想隐藏工具以供某些用户使用,您可以为查看工具的能力编写自定义逻辑

// in app/Providers/NovaServiceProvider.php

// ...

public function tools()
{
    return [
        // ...
        (new \Sereny\NovaPermissions\NovaPermissions())->canSee(function ($request) {
            return $request->user()->isSuperAdmin();
        }),
    ];
}

最后,将 MorphToMany 字段添加到您的 app/Nova/User 资源中

// ...
use Laravel\Nova\Fields\MorphToMany;

public function fields(Request $request)
{
    return [
        // ...
        MorphToMany::make('Roles', 'roles', \Sereny\NovaPermissions\Nova\Role::class),
        MorphToMany::make('Permissions', 'permissions', \Sereny\NovaPermissions\Nova\Permission::class),
    ];
}

将 Spatie\Permission\Traits\HasRoles 特性添加到您的用户模型中

use Illuminate\Foundation\Auth\User as Authenticatable;
use Spatie\Permission\Traits\HasRoles;

class User extends Authenticatable
{
    use HasRoles;

    // ...
}

安装此包后,您的 Nova 应用中会出现一个新的菜单项,名为 角色 & 权限

带有组的权限

索引视图

image

详情视图

image

编辑视图

image

数据库播种

使用以下命令发布我们的播种器:

php artisan vendor:publish --provider="Sereny\NovaPermissions\ToolServiceProvider" --tag="seeders"

这是一个示例,说明如何使用角色和权限对数据库进行播种。在 database/seeders 中修改 RolesAndPermissionsSeeder.php。在 $collection 数组中列出您希望拥有权限的所有模型,并更改超级管理员的电子邮件地址。

<?php

use Illuminate\Database\Seeder;
use Spatie\Permission\Models\Role;
use Spatie\Permission\Models\Permission;

class RolesAndPermissionsSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        // Reset cached roles and permissions
        app()[\Spatie\Permission\PermissionRegistrar::class]->forgetCachedPermissions();

        $collection = collect([
            'Invoice',
            'Client',
            'Contact',
            'Payment',
            'Team',
            'User',
            'Role',
            'Permission'
            // ... your own models/permission you want to crate
        ]);

        $collection->each(function ($item, $key) {
            // create permissions for each collection item
            Permission::create(['group' => $item, 'name' => 'viewAny' . $item]);
            Permission::create(['group' => $item, 'name' => 'view' . $item]);
            Permission::create(['group' => $item, 'name' => 'update' . $item]);
            Permission::create(['group' => $item, 'name' => 'create' . $item]);
            Permission::create(['group' => $item, 'name' => 'delete' . $item]);
            Permission::create(['group' => $item, 'name' => 'destroy' . $item]);
        });

        // Create a Super-Admin Role and assign all permissions to it
        $role = Role::create(['name' => 'super-admin']);
        $role->givePermissionTo(Permission::all());

        // Give User Super-Admin Role
        $user = App\User::whereEmail('your@email.com')->first(); // enter your email here
        $user->assignRole('super-admin');
    }
}

现在您可以播种数据库了。将 $this->call(RolesAndPermissionsSeeder::class); 添加到 DatabaseSeeder

注意:如果不起作用,请运行 composer dumpautoload 以自动加载播种器。

创建模型策略

您可以扩展 Sereny\NovaPermissions\Policies\BasePolicy 并拥有一个非常干净的与 Nova 一起工作的模型策略。

例如:使用以下代码创建一个新的联系人策略 php artisan make:policy ContactPolicy

<?php

namespace App\Policies;

use Sereny\NovaPermissions\Policies\BasePolicy;

class ContactPolicy extends BasePolicy
{
    /**
     * The Permission key the Policy corresponds to.
     *
     * @var string
     */
    public $key = 'contact';
}

现在它应该按预期工作。只需创建一个角色,修改其权限,策略就会处理剩下的工作。

注意:不要忘记将您的策略添加到 App\Providers\AuthServiceProvider$policies 中。

注意:只有根据我们的播种示例创建了您的权限,才需要扩展策略。否则,请确保在您的表中具有 viewAnyContact, viewContact, createContact, updateContact, deleteContact, restoreContact, destroyContact 作为权限,以便扩展我们的策略。

超级管理员

超级管理员可以做任何事情。如果您扩展我们的策略,请确保在您的 App\User 模型中添加 isSuperAdmin() 函数。

<?php

namespace App;

class User {

    /**
     * Determines if the User is a Super admin
     * @return null
    */
    public function isSuperAdmin()
    {
        return $this->hasRole('super-admin');
    }
}

自定义

// in app/Providers/NovaServiceProvider.php

use App\Nova\Permission;
use App\Nova\Role;

// ...

public function tools()
{
    return [
        // ...
        \Sereny\NovaPermissions\NovaPermissions::make()
            ->roleResource(Role::class)
            ->permissionResource(Permission::class)
            ->disablePermissions()
            ->disableMenu();
            ->hideFieldsFromRole([
                'id',
                'guard_name'
            ])
            ->hideFieldsFromPermission([
                'id',
                'guard_name',
                'users',
                'roles'
            ])
            ->resolveGuardsUsing(function($request) {
                return [ 'web' ];
            })
            ->resolveModelForGuardUsing(function($request) {
                /** @var App\Auth\CustomGuard $guard */
                $guard = auth()->guard();
                return $guard->getProvider()->getModel();
            })
    ];
}

重要

要自定义 Role 模型,您需要使用 Sereny\NovaPermissions\Traits\SupportsRole 特性

// Role using UUID primary key

namespace App\Models;

use Illuminate\Support\Str;
use Sereny\NovaPermissions\Traits\SupportsRole;
use Spatie\Permission\Models\Role as BaseRole;

class Role extends BaseRole
{
    use SupportsRole; // REQUIRED TRAIT

     /**
     * The "booted" method of the model.
     *
     * @return void
     */
    protected static function booted(): void
    {
        static::saving(function (Role $role) {
            if ($role->id === null) {
                $role->id = Str::uuid()->toString();
            }
        });
    }

    /**
     * Force key type as string
     *
     * @return string
     */
    public function getKeyType()
    {
        return 'string';
    }

    /**
     * Disable incrementing
     *
     * @return bool
     */
    public function getIncrementing()
    {
        return false;
    }
}

致谢

此包受到 eminiarts/nova-permissions 的启发。

向 Spatie spatie/laravel-permission 表示衷心的感谢,他们的工作非常出色!