rosalana/roles
Composer 安装命令:
composer require rosalana/roles
包简介
Rosalana package for managing user roles and permissions.
README 文档
README
Part of the Rosalana ecosystem. Provides two complementary role systems for Laravel applications:
- Global Roles — application-wide roles stored in context (e.g.
admin,moderator,user). Managed by Rosalana Basecamp and synced on login. - Model Roles — context-aware roles tied to specific Eloquent models (e.g. a user can be
ownerin one team andviewerin another).
Both systems are independent and can be used together.
Requires
rosalana/coreandrosalana/accounts.
Table of Contents
- Installation
- Configuration
- Global Roles
- Model Roles
- Laravel Gate Integration
- Suspended Users
- Exceptions
- May Show in the Future
- License
Installation
Install via the Rosalana CLI:
php artisan rosalana:add
# select rosalana/roles
Then publish assets:
php artisan rosalana:publish
Publishing the configuration is required. Publishing the Role enum is recommended to customize global roles.
Configuration
The rosalana.php config file (shared across Rosalana packages) accepts:
| Key | Description |
|---|---|
roles.enum |
FQCN of your RoleEnum implementation. Defaults to the built-in Rosalana\Roles\Enums\Roles. |
roles.banned |
Array of role values treated as suspended (e.g. ['banned']). Leave empty to disable auto-suspension. |
Global Roles
Global roles are application-wide. A user has exactly one global role (e.g. admin, user, banned). They are sourced from Rosalana Basecamp and stored in the application context on login — there is no local database column.
Role Enum
Global roles are defined as a PHP enum implementing the RoleEnum contract:
interface RoleEnum { public function level(): int; // numeric hierarchy public function isAtLeast(self|string $role): bool; public function is(self|string $role): bool; }
Publish and customize the default enum:
php artisan rosalana:publish
# choose rosalana-roles-role-enum
The published enum (app/Enums/Roles.php) ships with ADMIN, MODERATOR, USER, BANNED, and UNKNOWN. Each case has a numeric level() which drives isAtLeast() comparisons.
Register your custom enum in config:
// config/rosalana.php 'roles' => [ 'enum' => \App\Enums\Roles::class, ],
HasRoles Trait
Add HasRoles to your User model to enable global role access:
use Rosalana\Roles\Traits\HasRoles; class User extends Authenticatable { use HasRoles; }
Available methods for global role checks:
$user->role(); // returns RoleEnum|null from context $user->isSuspended(); // true if role is in 'roles.banned' config
The role is automatically populated from Basecamp's response on UserLogin, UserRefresh, and UserRegister events.
Global Role Middleware
Protect routes by requiring a minimum global role level:
Route::middleware('role.is:admin')->group(function () { // only users with role level >= admin });
The parameter is the enum case value (string), e.g. admin, moderator, user. Uses isAtLeast() — a moderator passes role.is:user but not role.is:admin.
Throws InsufficientRoleException (HTTP 403) on failure.
Model Roles
Model roles are context-aware. A user holds a named role (e.g. owner, editor, viewer) within the scope of a specific model instance. Each role carries a set of permissions.
Roleable Models
Add the Roleable trait to any model that should have role-managed members:
use Rosalana\Roles\Traits\Roleable; class Team extends Model { use Roleable; }
This gives the model:
$team->users(); // BelongsToMany — users with a role in this team $team->roles(); // MorphMany — all Role records for this team $team->roleOf($user); // ?Role — the user's current role $team->join($user, 'owner'); // assign a role $team->leave($user); // remove the user $team->newRole('editor', ['edit', 'view']); // create a new role definition $team->hasRole('editor'); // true if the role exists on this model $team->removeRole('editor'); // delete the role (detaches all users first)
When a Roleable model is created, default roles are seeded automatically. When deleted, all role records are cleaned up.
Configuring a Roleable Model
Override static methods to customize the model's role behavior:
class Team extends Model { use Roleable; // Pivot table between teams and users (default: '{model}_users') public static function getUsersPivotTable(): string { return 'team_users'; } // All valid permissions for this model public static function permissions(): array { return ['view', 'edit', 'delete', 'manage-members']; } // Permission aliases — map a shorthand to a group of permissions public static function permissionsAlias(): array { return [ 'editor' => ['view', 'edit'], ]; } // Roles seeded when a new Team instance is created public static function defaultRoles(): array { return [ 'owner' => ['*'], // wildcard = all permissions 'member' => ['view', 'edit'], ]; } // Role assigned to a user when they join without an explicit role public static function defaultRole(): string { return 'member'; } }
Model Role Methods on User
The HasRoles trait also provides model-scoped methods:
$user->join($team, 'owner'); // assign user to team with role $user->leave($team); // remove user from team $user->roleIn($team); // ?Role — the Role model instance $user->changeRole('editor', $team); // update role $user->hasRole('owner', $team); // bool — exact role name match $user->doesNotHaveRole('owner', $team); // bool $user->hasPermission('edit', $team); // bool $user->doesNotHavePermission('delete', $team); // bool $user->hasAnyPermission(['edit', 'delete'], $team); // bool
Roles Manager
The Roles facade exposes the RolesManager directly for low-level operations:
use Rosalana\Roles\Facades\Roles; $manager = Roles::on($team)->for($user); // equivalent: Roles::context($team, $user) $manager->assign('editor'); // assign or replace role $manager->detach(); // remove from model $manager->get(); // ?Role $manager->is('editor'); // bool — exact match $manager->isNot('owner'); // bool $manager->can('edit'); // bool $manager->cannot('delete'); // bool $manager->canAny(['edit', 'delete']); // bool $manager->permissions(); // Collection of permission strings
assign() is idempotent — it replaces the current role if one already exists.
Role Model
A Role record represents a single named role scoped to one model instance. It stores:
name— unique within the model instance (e.g.owner)permissions— JSON array of permission stringsroleable_type/roleable_id— the owning model
Do not create roles via Role::create() directly — use $model->newRole() or let default roles be seeded automatically.
Direct permission management:
$role->addPermission('publish'); $role->removePermission('delete'); $role->setPermissions(['view', 'edit']); // replaces all $role->hasPermission('edit'); $role->hasAnyPermission(['view', 'delete']); $role->hasAllPermissions(['view', 'edit']);
Permissions are validated against the model's permissions() array. Wildcards (*) expand to all available permissions. Aliases are resolved automatically.
Model Role Middlewares
Protect routes that use route model binding:
// Require exact role name in model bound to route parameter Route::middleware('role.in:team,owner')->group(function () { // $team route param must have role 'owner' for the current user }); // Require specific permission in model bound to route parameter Route::middleware('permission.in:team,edit')->group(function () { // $team route param must grant 'edit' permission to the current user });
Both middlewares expect the model to be resolved via Laravel's route model binding (e.g. Route::get('/teams/{team}/settings', ...)). The first argument is the route parameter name, the second is the role or permission name.
Both throw InsufficientRoleException (HTTP 403) on failure.
Laravel Gate Integration
All permissions from every Roleable model are automatically registered with Laravel's Gate. This means you can use standard Laravel authorization anywhere:
// Controller $this->authorize('edit', $team); // Blade @can('edit', $team) // Manual check Gate::allows('edit', $team);
No manual policy registration is required. The package scans all models using the Roleable trait and registers each permission as a Gate ability.
In production, the model scan result is cached forever. Clear it after deploying changes to roles or permissions:
php artisan cache:clear
Or use the provided commands:
php artisan roles:cache # warm the cache php artisan roles:clear # clear the cache
Suspended Users
If a user's global role is listed in roles.banned config, they are treated as suspended. The EnsureUserIsNotSuspended middleware is automatically added to the web group and throws AccountSuspendedException (HTTP 403) on every request.
Handle the exception in bootstrap/app.php to log the user out:
use Rosalana\Roles\Exceptions\AccountSuspendedException; $exceptions->render( fn(AccountSuspendedException $e) => Accounts::logout() );
Exceptions
| Exception | Default status | Thrown by |
|---|---|---|
AccountSuspendedException |
403 | EnsureUserIsNotSuspended middleware |
InsufficientRoleException |
403 | role.is, role.in, permission.in middlewares |
Both extend Symfony\Component\HttpKernel\Exception\HttpException and can be caught and customized in your exception handler. The default message and HTTP status code can be overridden by catching the exception and returning a custom response.
May Show in the Future
- Auto-migration: Automatically migrate database if deprecated permissions are detected.
Stay tuned — we're actively shaping the foundation of the Rosalana ecosystem.
License
Rosalana Roles is open-source under the MIT license, allowing you to freely use, modify, and distribute it with minimal restrictions.
You may not be able to use our systems but you can use our code to build your own.
For details on how to contribute or how the Rosalana ecosystem is maintained, please refer to each repository’s individual guidelines.
Questions or feedback?
Feel free to open an issue or contribute with a pull request. Happy coding with Rosalana!
rosalana/roles 适用场景与选型建议
rosalana/roles 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 42 次下载、GitHub Stars 达 1, 最近一次更新时间为 2025 年 06 月 27 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「package」 「laravel」 「roles」 「permissions」 「rosalana」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 rosalana/roles 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 rosalana/roles 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 rosalana/roles 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
Laravel Multiauth package
This package provides a flexible way to add Role-based Permissions to Laravel 6.x
This package provides a flexible way to add Role-based Permissions to Laravel
Simple ASCII output of array data
Alfabank REST API integration
统计信息
- 总下载量: 42
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 1
- 点击次数: 10
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2025-06-27