sourcefli / laravel-permission-name-generator
使用约定和非常简单的配置创建和检索权限
Requires
- php: ^7.4|^8.0
- spatie/once: ^3.0
Requires (Dev)
- orchestra/testbench: ^6.0
- phpunit/phpunit: ^9.5
README
简介
使用方法:使用方法代替字符串创建和检索权限字符串,并使用非常简单的配置。
配置中列出的每个项目都会获得一个'权限集',每个项目都有一个
- 浏览
- 读取
- 编辑
- 添加
- 删除
- 恢复
- 强制删除
*(使用'通配符'方法引用)
快速示例
在您的配置文件中的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)
检索方法
“检索方法”是您可以附加到您已经调用门面的任何resources或settings方法上的方法。
包括以下内容
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')
owned、team、owned_setting、team_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
- 每个权限字符串中的括号有什么作用?
这是为了防止与您在配置文件中列出的'resources'和'settings'发生命名冲突。如果您正在查看源代码,这些通常被称为
ownershipScopes或简单地称为scopes
- 为什么一切都是单数形式?
这是故意的,旨在提供全面统一的可预测格式...
AllPermissions外观是唯一不是单数的。
- 我可以添加自己的作用域吗?
不,目前只有4个可用。每个都由外观或它们自己的全局帮助器表示
- 所有者权限
- 团队权限
- 所有者设置权限
- 团队设置权限
- 权限能否以某种方式查询?
只有当您已将权限保存到数据库中时,您才能使用您的ORM。此包旨在返回权限的\Illuminate\Support\Collection(使用
AllPermissions外观,可以是作用域内的权限或所有权限)。或者检索单个权限作为字符串。我计划添加only()和except()方法(如Spatie的数据传输对象包),但方法就到这里了。我打算使此包尽可能简单。
返回顶部
致谢
安全
- 请尽快通过mail@jhavens.tech告知我任何与安全相关的问题。
许可证
MIT.
有关更多信息,请参阅opensource.org网站定义。