sourcefli/laravel-permission-name-generator

使用约定和非常简单的配置创建和检索权限

1.0.2 2022-06-20 07:39 UTC

This package is auto-updated.

Last update: 2024-09-21 07:24:29 UTC


README

Latest Version on Packagist Total Downloads

简介

使用方法:使用方法代替字符串创建和检索权限字符串,并使用非常简单的配置。

配置中列出的每个项目都会获得一个'权限集',每个项目都有一个

  • 浏览
  • 读取
  • 编辑
  • 添加
  • 删除
  • 恢复
  • 强制删除
  • * (使用'通配符'方法引用)

快速示例

在您的配置文件中的resources数组中添加一个项目,例如...

//=> config.php
<?php

return [
    'resources' => [
        'billing'
    ]
];

生成以下权限字符串... 注意:括号内的每个项目都将后来被引用为'作用域'

'billing.[owned].browse'
'billing.[owned].read' 
'billing.[owned].edit' 
'billing.[owned].add' 
'billing.[owned].delete' 
'billing.[owned].restore' 
'billing.[owned].force_delete'
'billing.[owned].*'
//and
'billing.[team].browse'
'billing.[team].read' 
'billing.[team].edit' 
'billing.[team].add' 
'billing.[team].delete' 
'billing.[team].restore' 
'billing.[team].force_delete'
'billing.[team].*'

一个示例,说明如何在您的Laravel应用程序中访问这些权限字符串之一...

OwnedPermission::billing()->edit(); 
/**
* returns: 
*   'billing.[owned].edit'
*/ 

//Or, with global helper functions..

ownedPermission('billing')->read(); 
/**
* returns: 
*   'billing.[owned].read'
*/ 

获取resource的子集权限的示例

//Or, 'only' a subset for a specific scope..

teamPermission('billing')->only(['browse', 'edit']);
/**
* returns: 
*    Illuminate\Support\Collection
*    {
*        'billing.[team].browse',
*        'billing.[team].edit'
*    }
*/ 

//Or, 'except' a subset for a specific scope..

teamPermission('billing')->except(['force_delete', 'restore']);
/**
* returns: 
*   Illuminate\Support\Collection 
*   { 
*        'billing.[team].browse',
*        'billing.[team].read',
*        'billing.[team].edit',
*        'billing.[team].add',
*        'billing.[team].delete',
*        'billing.[team].*'
*    }
*/ 

授权说明

所有包逻辑都与非常容易生成'权限字符串'以及在应用程序中非常容易检索它们相关。约定、可预测性和减少样板代码是我所追求的核心。

概述

我总是对总是需要记住哪些权限是复数的、哪种语法允许用户查看'team'权限以及哪些权限仅适用于用户的资源而感到非常烦恼。此外,还需要在应用程序中硬编码权限字符串或每次都创建一个包装器。这些似乎是非常常见的常规操作,所以我决定冒险创建一个用于此目的的包。

安装

composer require jhavenz/laravel-permission-name-generator

发布配置

php artisan vendor:publish --provider="Jhavenz\PermissionName\PermissionNameServiceProvider"

详细用法

将资源/设置添加到配置文件

//=> config/permission-name-generator

//For the quickstart, just add a couple resources
return [

    'resources' => [
        'user',
        'billing',
        '...'
    ],

    'settings' => [
        //explained in next section
        '...'
    ]

];

注意:请参阅此readme的底部QA部分,了解为什么使用括号以及您可能有的其他问题

现在开始使用它

此示例可能是您想知道以下情况时使用的权限:

当前用户是否可以编辑应用程序中他们拥有的计费设置

//=> routes/web.php
use Jhavenz\PermissionName\Facades\OwnedPermission;

Route::get('permissions', function () {
    OwnedPermission::billing()->edit();
    //returns 'billing.[owned].edit'
});

//or, get all 'resources' now available to you:
Route::get('permissions', function () {
    return collect([OwnedPermission::all(), TeamPermission::all()])->toArray();
});

或者

此示例可能是您想知道以下情况时使用的权限:

当前用户是否可以编辑他们团队拥有的计费设置,或者他们团队中的任何人拥有的(仅举几个例子)

//=> routes/web.php

//note the Facade change
use Jhavenz\PermissionName\Facades\TeamPermission;

Route::get('permissions', function () {
    TeamPermission::billing()->edit();
    //returns 'billing.[team].edit' 
});

'设置'项目

配置文件中的settings部分是可选的。在您有与资源分开的settings相关权限的情况下添加此部分。

//=> config/permission-name-generator

return [

    'resources' => [
        ...
    ],

    'settings' => [
        'user', //can be 'settings' related to a model in your app...
        'smtp', //or any random 'settings' that your app uses..
    ]
];

现在开始使用它

此示例可能是您想知道以下情况时使用的权限:

当前用户可以编辑他们拥有的SMTP设置...

//=> routes/web.php

//note the Facade change
use Jhavenz\PermissionName\Facades\OwnedSettingPermission;

Route::get('permissions', function () {
    OwnedSettingPermission::smtp()->edit();
    //returns 'smtp.[owned_setting].edit' 
});

//or, get all 'settings' now available to you:
Route::get('permissions', function () {
    return collect([OwnedSettingPermission::all(), TeamSettingPermission::all()])->toArray();
});

此示例可能是您想知道以下情况时使用的权限:

当前用户可以编辑他们团队拥有的SMTP设置

//=> routes/web.php

//note the Facade change
use Jhavenz\PermissionName\Facades\TeamSettingPermission;

Route::get('permissions', function () {
    TeamSettingPermission::smtp()->edit();
    //returns 'smtp.[team_setting].edit' 
});

“团队”作用域和“拥有”作用域之间的任何区别都取决于您的应用程序需要,当然。我只是列出了一些我在之前使用这些权限字符串的示例。

全局助手

有4个全局“助手”函数可用。它们是

ownedPermission();
ownedSettingPermission();
teamPermission();
teamSettingPermission();

助手函数参数

选项A。

如果您将资源或设置(与您要调用的函数相关的任何内容)作为参数传递,所有这些函数都将返回相应的适配器——这意味着您可以将任何检索方法链接到它,就像Facade行为一样,如下所示

ownedPermission('billing')->read();
//returns 'billing.[owned].read'

//or 

teamSettingPermission('smtp')->restore();
//returns 'smtp.[team_setting].restore'

//the 'only' and 'except' methods (explained below) can be chained here as well...
ownedSettingPermission('smtp')->only('browse', 'add', 'delete');
//returns a Illuminate\Support\Collection only containing these 3 permission strings

teamPermission('billing')->except('*', 'force_delete');
//returns a Illuminate\Support\Collection with all permissions in the 'billing.[team]' prefix, 
//excluding '*' and 'force_delete'

选项B

如果您没有向任何这些方法传递任何参数,您将获得与该“作用域”相关的所有权限的集合

teamSettingPermission();
//returns all 'settings' permissions within the [team_setting] scope

ownedPermission();
//return all 'resources' permissions within the [owned] scope

//etc..
 

ONLY 和 EXCEPT 方法

如上所述简要介绍,当您正在定义角色以及与它们关联的权限时,您需要告诉应用程序在配置文件中定义的每一组“资源”或“设置”中应包含/排除哪些权限。为此,您可以使用only()方法或except()方法。这些方法接受以逗号分隔的字符串或数组形式的权限列表。

例如,如果使用上述相同的配置

OwnedPermission::billing()->only('browse', 'edit');
/** returns:
*   Illuminate\Support\Collection {
*     'billing.[owned].browse',
*     'billing.[owned].edit'
*   }
*/

//or 

TeamPermission::user()->except(['edit','delete', 'force_delete', '*']);
/** returns:
*   Illuminate\Support\Collection {
*     'user.[team].browse',
*     'user.[team].read',
*     'user.[team].add',
*     'user.[team].restore',
*   }
*/

!! 重要提示 !!

使用except()方法时要小心,因为返回的集合中始终存在*权限,除非另有说明,否则它将保持存在。

类似于在Laravel中解析请求,最安全的方法是坚持使用only()方法,以确保您选择的是您正在寻找的确切权限。

由于所有门面都在全局命名空间中别名为All Facades,因此在使用视图中的门面时也不会造成混乱。

//=> dashboard.blade.php (for example)

//If using Laravel Gate or something like 'Spatie Permission' 
@if (Auth::user()->can(TeamPermission::profile()->browse(), $team))
    User CAN browse the profile for their team
@else
    User CAN NOT view the profile for their team
@endif

/* 
* Global Helpers
* You can also use one of the four global helper functions
* that are available... 
*/

@if (Auth::user()->can(teamPermission('profile')->browse(), $team))
    User CAN browse the profile for their team
@else
    User CAN NOT view the profile for their team
@endif

//or
@if (Auth::user()->can(ownedSettingPermission('smtp')->edit(), $team))
    User CAN edit the their own smtp settings
@else
    User CAN NOT edit the their own smtp settings
@endif

//...etc.
//You can use these methods on the 'settings' Facades as well...

OwnedSettingPermission::smtp()->only('browse', 'edit', 'delete');
// returns a Collection with:
// [
//     'smtp.[owned_setting].browse',
//     'smtp.[owned_setting].edit',
//     'smtp.[owned_setting].delete',
// ]


//or for 'team_settings'...

TeamSettingPermission::smtp()->except('browse', 'read', 'force_delete', '*');
// returns a Collection with:
// [
//     'smtp.[team_setting].add',
//     'smtp.[team_setting].edit',
//     'smtp.[team_setting].delete',
//     'smtp.[team_setting].restore',
// ]

检索“所有”权限

此示例提供对所有可用权限的访问(将“资源”和“设置”合并)

//=> routes/web.php
use Jhavenz\PermissionName\Facades\AllPermissions;

Route::get('permissions', function () {
    AllPermissions::all();
    //returns a Laravel Collection of all available permissions that were generated
});

此示例返回“owned”作用域内的所有“资源”

(下面将进一步解释“作用域”)

//=> routes/web.php
use Jhavenz\PermissionName\Facades\OwnedPermission;

Route::get('permissions', function () {
    OwnedPermission::all();
    //returns a Laravel Collection of all 'resource' permissions within the 'owned' scope
});

此软件包包含5个此类门面,每个门面都有自己的“作用域”,我将在下面进一步讨论。

use Jhavenz\PermissionName\Facades\AllPermissions;
use Jhavenz\PermissionName\Facades\OwnedPermission;
use Jhavenz\PermissionName\Facades\OwnedSettingPermission;
use Jhavenz\PermissionName\Facades\TeamPermission;
use Jhavenz\PermissionName\Facades\TeamSettingPermission;

您还可以使用根别名...

use AllPermissions;
use OwnedPermission;
//and so on..

深入了解

“权限集”定义

在配置中,任何“资源”或“设置”都将获得其自己的权限集...例如

//=> config/permission-name-generator.php

//if your config looks like this...
return [
    "resources" => [
        "user",
        "billing"
    ],
    'settings' => [
        'smtp'
    ]
];

将这三个项目添加到您的配置将生成以下“权限集”

[
  "user.[owned].browse",
  "user.[owned].read",
  "user.[owned].edit",
  "user.[owned].add",
  "user.[owned].delete",
  "user.[owned].restore",
  "user.[owned].force_delete",
  "user.[owned].*",
  "billing.[owned].browse",
  "billing.[owned].read",
  "billing.[owned].edit",
  "billing.[owned].add",
  "billing.[owned].delete",
  "billing.[owned].restore",
  "billing.[owned].force_delete",
  "billing.[owned].*",
  "smtp.[owned_setting].browse",
  "smtp.[owned_setting].read",
  "smtp.[owned_setting].edit",
  "smtp.[owned_setting].add",
  "smtp.[owned_setting].delete",
  "smtp.[owned_setting].restore",
  "smtp.[owned_setting].force_delete",
  "smtp.[owned_setting].*",
  "user.[team].browse",
  "user.[team].read",
  "user.[team].edit",
  "user.[team].add",
  "user.[team].delete",
  "user.[team].restore",
  "user.[team].force_delete",
  "user.[team].*",
  "billing.[team].browse",
  "billing.[team].read",
  "billing.[team].edit",
  "billing.[team].add",
  "billing.[team].delete",
  "billing.[team].restore",
  "billing.[team].force_delete",
  "billing.[team].*",
  "smtp.[team_setting].browse",
  "smtp.[team_setting].read",
  "smtp.[team_setting].edit",
  "smtp.[team_setting].add",
  "smtp.[team_setting].delete",
  "smtp.[team_setting].restore",
  "smtp.[team_setting].force_delete",
  "smtp.[team_setting].*"
];

如你所见,配置中列出的每个“资源”将生成一个[owned]权限集和一个[team]权限集。

配置中列出的任何“设置”项目将生成一个[owned_setting]权限集和一个[team_setting]权限集

每个“权限集”包含所有8个权限

  • 浏览
  • 读取
  • 编辑
  • 添加
  • 删除
  • 恢复
  • 强制删除
  • *

在您的应用程序中调用权限

使用与“权限集”定义中提到的相同配置,您可以在每个相关门面上调用同名方法。

**除外的AllPermissions门面,我将在下面解释。

例如,我们现在可以调用这些方法

use OwnedPermission;
use TeamPermission;

/**
 * for 'resource' related items
 */ 

OwnedPermission::user()->delete();
//=> returns 'user.[owned].delete'

//..or 

TeamPermission::billing()->wildcard();
//=> returns 'billing.[team].*'


// or any of the 'retrieval methods' (explained below)

检索方法

“检索方法”是您可以附加到您已经调用门面的任何resourcessettings方法上的方法。

包括以下内容

browse()

read()

edit()

add()

delete()

force_delete()

restore()

wildcard()

例如

对于您的任何“资源”,您可以调用

OwnedPermission::user()->create(); 

TeamPermission::billing()->edit();

...

或者,对于您的“设置”

OwnedSettingPermission::smtp()->read();

TeamSettingPermission::smtp()->delete();

...

AllPermissions门面

此门面与其他门面略有不同,但只是很小的不同。如果您想获取所有权限的集合,您可以调用

 AllPermission::all();
//This will give you a combined Laravel Collection of 'resources' and 'settings' that you've listed in your config file..

AllPermission门面获取单个权限

如果您想从该门面检索权限字符串,与其他门面略有不同。

首先,您需要设置一个scope,然后您可以根据上述列表链式调用标准方法(查看从这里开始的测试以获取示例用法)。

有4个方法用于为AllPermissions门面设置作用域

use AllPermissions;

AllPermissions::forOwned();
AllPermissions::forTeam();
AllPermissions::forOwnedSetting();
AllPermissions::forTeamSetting();

//Once you set the scope, continue chaining like any of the other Facades...

// e.g. for one of your 'resources' 
AllPermissions::forOwned()->billing()->delete();
//returns 'billing.[owned].delete'

// e.g. or one of your 'settings'
AllPermissions::forTeamSetting()->smtp()->edit();
//returns 'smtp.[team_setting].edit'

所有门面上的“all”方法

您可以在任何门面上调用all()方法,以

A. 如果没有设置资源,获取该作用域内所有权限的完整列表。(见以下示例'A')

B. 如果该实例上设置了资源/设置,获取与资源/设置相关的权限集。(见以下示例'B')

ownedteamowned_settingteam_setting

例如

use Jhavenz\PermissionName\Facades\AllPermissions;
use Jhavenz\PermissionName\Facades\OwnedPermission;
use Jhavenz\PermissionName\Facades\TeamSettingPermission;


/**
 * A. 
 * We're in the 'owned' scope here... 
 */
OwnedPermission::all();
// returns all 'resource' permissions that include '[owned]'

/**
 * B. 
 * We're in the '[team_setting]' scope here... 
 */ 
TeamSettingPermission::billing()->all();
// returns all '[team_settings]' permissions related to billing

/**
 * C. 
 * Lastly...the one case were a 'scope' is not required:
 * To get a Collection that combines your 'resources' and 'settings'
 * and every permission your app has...
 */ 
AllPermissions::all();

QA

  1. 每个权限字符串中的括号有什么作用?

这是为了防止与您在配置文件中列出的'resources'和'settings'发生命名冲突。如果您正在查看源代码,这些通常被称为ownershipScopes或简单地称为scopes

  1. 为什么一切都是单数形式?

这是故意的,旨在提供全面统一的可预测格式... AllPermissions外观是唯一不是单数的。

  1. 我可以添加自己的作用域吗?

不,目前只有4个可用。每个都由外观或它们自己的全局帮助器表示

  • 所有者权限
  • 团队权限
  • 所有者设置权限
  • 团队设置权限
  1. 权限能否以某种方式查询?

只有当您已将权限保存到数据库中时,您才能使用您的ORM。此包旨在返回权限的\Illuminate\Support\Collection(使用AllPermissions外观,可以是作用域内的权限或所有权限)。或者检索单个权限作为字符串。我计划添加only()except()方法(如Spatie的数据传输对象包),但方法就到这里了。我打算使此包尽可能简单。

返回顶部

返回顶部

致谢

  • Spatie 因为其权限包中的所有艰苦工作。我还使用了他们的once函数来帮助在此包中提高性能。

安全

许可证

MIT.

有关更多信息,请参阅opensource.org网站定义。