将 Spatie 权限链接到 Backpack UI show/hide

Linking Spatie Permissions to Backpack UI show/hide

这里是 Laravel 和 Backpack 的新手,但正在尝试将 PermissionManager 与 Backpack 集成。我已经全部安装好并在 UI 中显示 Users/Permissions/Roles,但是我无法弄清楚如何 show/hide 背包 UI 中的按钮和功能基于那些权限。我希望有人可以评论我想出的解决方案,或者是否还有其他应该使用的东西。

Note, this is really about showing and hiding UI elements, not the actual policies (which I am handling separately using the "can" functions in my controllers, routes, etc.)

我的解决方案:

在我的 EntityCrudController 中,我使用了一个名为 CrudPermissionsLink 的特征,然后在 setup() 中我调用了我创建的函数:

public function setup()
{
    CRUD::setModel(\App\Models\ProgramUnit::class);
    CRUD::setRoute(config('backpack.base.route_prefix') . '/programunit');
    CRUD::setEntityNameStrings('programunit', 'program_units');

    $this->linkPermissions();
}

然后在我的特点中,我根据命名约定简单地定义了它,用破折号分隔。

<?php

namespace App\Http\Traits;
use Illuminate\Support\Facades\Auth;

/**
 * Properties and methods used by the CrudPermissionsLink trait.
 */
trait CrudPermissionsLink
{
    /**
     * Remove access to all known operations by default, reset them based on permissions defined in the format 
     * entity_name-operation
     *
     */
    public function linkPermissions()
    {
        $ui_ops = ['list','create','delete','update'];
        $user = Auth::user();
        $this->crud->denyAccess($ui_ops);
        foreach($ui_ops as $op){
            $perm_name = "{$this->crud->entity_name}-{$op}";
            if($user->can($perm_name)){
                $this->crud->allowAccess($op);
            }
        }
    }
}

你所拥有的将会起作用。也就是说,我最近为我的应用程序创建了一个类似的解决方案。对于我的解决方案,我使用了一个抽象的 Crud 控制器,如下所示,我所有的特定 Crud 控制器都扩展了这个 class:

<?php

namespace App\Http\Controllers;

use Illuminate\Support\Facades\Gate;
use Illuminate\Database\Eloquent\Model;
use Backpack\CRUD\app\Http\Controllers\Operations\ListOperation;
use Backpack\CRUD\app\Http\Controllers\Operations\CreateOperation;
use Backpack\CRUD\app\Http\Controllers\Operations\UpdateOperation;
use Backpack\CRUD\app\Http\Controllers\Operations\DeleteOperation;
use Backpack\CRUD\app\Http\Controllers\CrudController as BaseCrudController;

abstract class CrudController extends BaseCrudController
{
    use ListOperation, DeleteOperation;
    use CreateOperation { store as traitStore; }
    use UpdateOperation { update as traitUpdate; }

    /**
     * All possible CRUD "actions"
     */
    public const CRUD_ACTION_CREATE    = 'create';
    public const CRUD_ACTION_LIST      = 'list'; // synonymous with "read"
    public const CRUD_ACTION_UPDATE    = 'update';
    public const CRUD_ACTION_DELETE    = 'delete';
    public const CRUD_ACTION_REORDER   = 'reorder';
    public const CRUD_ACTION_REVISIONS = 'revisions';

    /**
     * @var array An array of all possible CRUD "actions"
     */
    public const ACTIONS = [
        self::CRUD_ACTION_CREATE,
        self::CRUD_ACTION_LIST,
        self::CRUD_ACTION_UPDATE,
        self::CRUD_ACTION_DELETE,
        self::CRUD_ACTION_REORDER,
        self::CRUD_ACTION_REVISIONS,
    ];

    /**
     * @var array An array of all CRUD "actions" that are not allowed for this resource
     * Add any of the CRUD_ACTION_X constants to this array to prevent users accessing
     * those actions for the given resource
     */
    public $_prohibitedActions = [
        self::CRUD_ACTION_REORDER,   // not currently using this feature
        self::CRUD_ACTION_REVISIONS, // not currently using this feature
    ];

    /**
     * Protect the operations of the crud controller from access by users without the proper
     * permissions
     *
     * To give a user access to the operations of a CRUD page give that user the permissions below
     * (where X is the name of the table the CRUD page works with)
     *
     * `X.read`      permission: users can view the CRUD page and its records
     * `X.create`    permission: users can create records on the CRUD page
     * `X.update`    permission: users can update records on the CRUD page
     * `X.delete`    permission: users can delete records on the CRUD page
     * `X.reorder`   permission: users can reorder records on the CRUD page
     * `X.revisions` permission: users can manage record revisions on the CRUD page
     *
     * @return void
     */
    public function setupAccess(): void
    {
        // get the name of the table the crud operates on
        $table = null;
        if (isset($this->crud->model) && $this->crud->model instanceof Model) {
            /** @var Model $this->crud->Model; */
            $table = $this->crud->model->getTable();
        }
        // for each action, check if the user has permissions
        // to perform that action and enforce the result
        foreach (self::ACTIONS as $action) {
            $requiredPermission = "$table.$action";
            // If our model has no $table property set deny all access to this CRUD
            if ($table && !$this->isProhibitedAction($action) && Gate::check($requiredPermission)) {
                $this->crud->allowAccess($action);
                continue;
            }
            $this->crud->denyAccess($action);
        }
    }

    /**
     * Check if the given action is allowed for this resource
     * @param string $action One of the CRUD_ACTION_X constants
     * @return bool
     */
    public function isProhibitedAction($action): bool
    {
        return in_array($action, $this->_prohibitedActions, true);
    }

    /**
     * Setup the CRUD page
     * @throws \Exception
     */
    public function setup(): void
    {
        $this->setupAccess();
    }

}