samoylenko/teams

Laravel包用于管理团队功能以及与用户权限操作。

dev-main 2023-08-11 08:28 UTC

This package is auto-updated.

Last update: 2024-09-11 10:37:38 UTC


README

"Teams"是一个Laravel包,用于管理团队功能,并操作用户权限和能力,支持多租户,为每个团队提供动态角色和权限。

团队内的用户可以被组合成具有自身权利和权限的组,分配给用户组的访问权限将覆盖分配给团队中用户的权利

该包的文档正在编写中,目前请使用此readme文件

该包已在Laravel 8.x和9.x上进行了测试

安装

composer require samoylenko/teams

为了完成安装,您需要运行artisan:publish命令以添加配置和为包工作的附加文件。

以下命令可能会覆盖您的实际目录和文件,请在执行前考虑备份。

php artisan teams:install

如果您还想添加预配置的UserTeam模型,请将--models选项传递给上述命令,否则您需要扩展自己的模型。

此包支持包发现,但运行artisan:publish命令后,您需要将App\Providers\TeamsServiceProvider::class放入app.php配置文件中的providers部分,此文件由stub发布,需要用于可扩展性。

操作

可以通过修改您的app/Actions/Teams目录中的相关操作类来自定义团队创建、删除和其他逻辑。

这些操作包括CreateTeamUpdateTeamNameDeleteTeam。当用户执行相应的任务时,会调用这些操作。您可以根据应用程序的需要自由修改这些操作。

用户

该包提供了Samoylenko\Teams\Traits\HasTeams特性,在安装期间应用于应用程序的App\Models\User模型,并提供检查用户团队的方法。

// Access all of the team's (including owned teams) that a user belongs to...
$user->teams : Illuminate\Support\Collection

// Access all of a user's owned teams...
$user->ownedTeams : Illuminate\Database\Eloquent\Collection

// Determine if a user owns a given team...
$user->ownsTeam($team) : bool

// Determine if a user belongs to a given team...
$user->belongsToTeam($team) : bool

// Get the role that the user is assigned on the team...
$user->teamRole($team) : \Samoylenko\Teams\Role

// Determine if the user has the given role on the given team...
$user->hasTeamRole($team, 'admin') : bool

// Access an array of all permissions a user has for a given team...
$user->teamPermissions($team) : array

// Determine if a user has a given team permission...
$user->hasTeamPermission($team, 'server:create') : bool

// Get list of abilities or forbidden abilities for users on certain model
$user->teamAbilities($team, \App\Models\Server $server) : mixed

// Determine if a user has a given ability on certain model...
$user->hasTeamAbility($team, 'server:edit', \App\Models\Server $server) : bool

// Add an ability for user to action on certain model, if permission is not found, will create a new one
$user->allowTeamAbility($team, 'server:edit', \App\Models\Server $server) : bool

// Forbid an ability for user to action on certain model, used in case if global permission or role allowing this action
$user->forbidTeamAbility($team, 'server:edit', \App\Models\Server $server) : bool

团队

可以通过$user->team访问团队,它提供了检查团队属性和关系的方法。

// Access the team's owner...
$team->owner

// Get all the abilities belong to the team.
$team->abilities()

// Get all the team's users, excluding owner
$team->users()

// Get all the team's users, including the owner...
$team->allUsers()

// Get all the team's roles.
$team->roles()

// Add new role to the team
$team->addRole(string $name, array $capabilities)

// Update the role in the team
$team->updateRole(string $name, array $capabilities)

// Deletes the given role from team
$team->deleteRole(string $name)

// Get all groups of the team.
$team->groups()

// Add new group to the team
$team->addGroup(string $name)

// Delete group from the team
$team->deleteGroup(string $name)

// Get the role from the team by role id 
$team->findRole(string $id)

// Return the user role object from the team
$team->userRole($user)

// Determine if the given user is a team member...
$team->hasUser($user)

// Determine if the team has a member with the given email address...
$team->hasUserWithEmail($emailAddress)

// Determine if the given user is a team member with the given permission...
$team->userHasPermission($user, $permission)

// Determine if the team has a member with the given email address...
$team->invitations()

// Remove the given user from the team.
$team->removeUser();

成员管理

只有所有者可以管理团队成员,这种限制在App\Policies\TeamPolicy中定义。当然,您可以自由修改此策略。

与其他包功能的自定义过程类似,可以通过修改App\Actions\Teams\AddTeamMember操作类来自定义团队成员添加逻辑。

此操作负责验证用户是否可以实际添加到团队,然后添加用户到团队。您可以根据特定应用程序的需求自定义此操作。

可以通过修改操作App\Actions\Teams\RemoveTeamMember来自定义团队member removal

邀请

默认情况下,包会简单地将您指定的任何现有应用程序用户添加到您的团队。然而,许多应用程序会选择向被邀请到团队的用户发送邀请邮件。如果用户没有账户,邀请邮件可以指导他们创建账户并接受邀请。或者,如果用户已经有账户,他们可以接受或忽略邀请。

幸运的是,这个包允许您通过几行代码就能为您的应用程序启用团队成员邀请功能。要开始使用,请将 invitations 选项传递到配置中。

一旦您启用了邀请功能,被邀请加入团队的用户将收到一封带有接受团队邀请链接的邀请邮件。用户只有在接受邀请后才能成为团队的全权成员。

邀请操作

当用户被邀请加入团队时,您的应用程序的 App\Actions\Teams\InviteTeamMember 操作将会被调用,调用时会传递当前认证的用户、被邀请加入的新用户所属的团队、被邀请用户的电子邮件地址,以及可选的,用户加入团队后应分配的角色。您可以自由地审查或修改此操作以满足您应用程序的需求。

邀请邮件

在使用团队邀请功能之前,您应该确保您的 Laravel 应用程序已配置为 发送邮件 。否则,Laravel 将无法向您的应用程序用户发送团队邀请邮件。

角色/权限

每个被添加到团队中的成员都可以分配一个特定的角色,每个角色都分配了一组权限。

角色和权限存储在您的应用程序数据库中。这允许广泛地使用角色和权限,例如,您可以在应用程序的管理页面上实现角色和权限的管理。

您可以使用通过安装命令发布的 App/Models/RoleApp/Model/Permission,来创建新的角色和权限,从数据库中获取它们,并以通常的模型方式与它们交互。

但是,您可以直接从 App\Models\Team 与角色和权限交互。

例如,要创建新的 Team 并将其与某些 RolePermission 关联

$team = new Team();

$team->name = 'Example Team';
$team->code = 'example_team';

if ($team->save()) {

    $team->addRole('admin', [
        'employees.*',
        'sections.*',
        'articles.*',
        'tags.*',
        'comments.*',
        'team.edit',
        'stores.*',
        'plan.edit',
    ]);
    
    $team->addRole('user', [
        'employees.view',
        'articles.view',
        'articles.add',
        'sections.view',
        'sections.add',
        'comments.add',
        'tags.view',
        'stores.add',
        'stores.delete',
        'tags.add',
    ]);
}

$team->addRole 函数的第二个参数是 capabilities 数组,它们存储在数据库中,并决定了将附加到角色中的整个应用程序的能力

授权

当然,您需要一个方式来授权团队成员发起的请求实际上是由该用户执行的。您可以使用通过 Samoylenko\Teams\Traits\HasTeams 特性提供的 hasTeamPermission 方法来检查用户的团队权限。

通常不需要检查用户的角色。您只需要检查用户是否具有特定的细粒度权限。 角色只是用来分组细粒度权限的表示概念。通常,您将在应用程序的 授权策略 中执行对此方法的调用

return $user->hasTeamPermission($server->team, 'server:update');

能力

向用户添加能力变得简单。您不必预先创建角色或能力。只需传递能力的名称,如果不存在,则包会创建它。

让我们给某些用户赋予在团队中编辑文章的能力,我们需要传递实体,在这个例子中是文章对象和团队对象

User::allowTeamAbility('edit', $article, $team));

例如,要在此功能中检查此能力,请使用

User::hasTeamAbility('edit', $article, $team);

要禁止用户执行某些能力(如果角色能力允许此能力)

User::forbidTeamAbility('edit', $article, $team);

要创建不附加到用户的权限,请使用在安装时发布的 Ability 模型

Ability::firstOrCreate([ 'name' => 'edit', 'title' => 'Edit' ]);

中间件

中间件配置

中间件会自动注册为 rolepermissionability。如果您想更改或自定义它们,请转到您的 config/teams.php 并将 middleware.register 的值设置为 false,然后在 app/Http/Kernel.php 中的 routeMiddleware 数组中添加以下内容

'role'       => \Samoylenko\Teams\Middleware\Role::class, 
'permission' => \Samoylenko\Teams\Middleware\Permission::class,
'ability'    => \Samoylenko\Teams\Middleware\Ability::class,

中间件路由

您可以使用中间件来根据权限或角色过滤路由和路由组

Route::group(['prefix' => 'admin', 'middleware' => ['role:admin,#team_id#']], function() {
    Route::get('/', 'CommonController@commonIndex');
    Route::get('/users', ['middleware' => ['permission:views-users,#team_id#'], 'uses' => 'CommonController@commonUsers']);
});

其中 #team_id# 是数据库中团队的实际 ID。

如果您想更改或自定义此变量的名称,请转到您的 config/teams.php 并将 foreign_keys.team_id 的值设置为遵循您的数据库结构。

注意,中间件逻辑可能会有所不同,具体取决于你如何传递 team_id 变量

您可以将 team_id 变量作为路由参数传递

Route::get('/{team_id}/users', ['middleware' => ['permission:views-users'], 'uses' => 'CommonController@commonUsers']);

您可以直接将 team_id 变量作为中间件选项传递

'middleware' => ['role:admin|root,#team_id#']

您可以在每个 GET/POST/PUT 或其他类型请求中传递 team_id 变量。

中间件使用

如果您想使用 OR 操作,可以使用管道符号

'middleware' => ['role:admin|root,{team_id}']
// $user->hasTeamRole($team, ['admin', 'root']);

'middleware' => ['permission:edit-post|edit-user']
// $user->hasTeamPermission($team, ['edit-post', 'edit-user']);

如果您想使用 AND 功能,可以这样做

'middleware' => ['role:admin|root,{team_id},require']
// $user->hasTeamRole($team, ['admin', 'root'], '{team_id}', true);

'middleware' => ['permission:edit-post|edit-user,{team_id},require']
// $user->hasTeamPermission($team, ['edit-post', 'edit-user'], '{team_id}', true);

要检查对特定模型项的操作 ability,可以使用 ability 中间件

'middleware' => ['ability:edit,App\Models\Article,atricle_id']
// $user->hasTeamAbility($team, 'edit', $article);

在这种情况下,您需要将 atricle_id 作为 请求参数路由参数 传递,以允许包识别模型对象

许可证

此软件包是开源软件,遵循 MIT 许可协议