update inbox list

This commit is contained in:
manhlab
2021-04-07 19:25:18 -04:00
parent fda7245f7c
commit 436de2efd6
8576 changed files with 1013325 additions and 3 deletions

View File

@@ -0,0 +1,6 @@
---
title: v3
slogan: Associate users with roles and permissions
githubUrl: https://github.com/spatie/laravel-permission
branch: master
---

View File

@@ -0,0 +1,16 @@
---
title: About us
---
[Spatie](https://spatie.be) is a webdesign agency based in Antwerp, Belgium.
Open source software is used in all projects we deliver. Laravel, Nginx, Ubuntu are just a few
of the free pieces of software we use every single day. For this, we are very grateful.
When we feel we have solved a problem in a way that can help other developers,
we release our code as open source software [on GitHub](https://spatie.be/opensource).
This package is heavily based on [Jeffrey Way](https://twitter.com/jeffrey_way)'s awesome [Laracasts](https://laracasts.com) lessons
on [permissions and roles](https://laracasts.com/series/whats-new-in-laravel-5-1/episodes/16). His original code
can be found [in this repo on GitHub](https://github.com/laracasts/laravel-5-roles-and-permissions-demo).
Special thanks to [Alex Vanderbist](https://github.com/AlexVanderbist) who greatly helped with `v2`, and to [Chris Brown](https://github.com/drbyte) for his longtime support helping us maintain the package.

View File

@@ -0,0 +1,4 @@
---
title: Advanced usage
weight: 3
---

View File

@@ -0,0 +1,47 @@
---
title: Cache
weight: 5
---
Role and Permission data are cached to speed up performance.
While we recommend not changing the cache "key" name, if you wish to alter the expiration time you may do so in the `config/permission.php` file, in the `cache` array.
When you use the built-in functions for manipulating roles and permissions, the cache is automatically reset for you, and relations are automatically reloaded for the current model record:
```php
$user->assignRole('writer');
$user->removeRole('writer');
$user->syncRoles(params);
$role->givePermissionTo('edit articles');
$role->revokePermissionTo('edit articles');
$role->syncPermissions(params);
$permission->assignRole('writer');
$permission->removeRole('writer');
$permission->syncRoles(params);
```
HOWEVER, if you manipulate permission/role data directly in the database instead of calling the supplied methods, then you will not see the changes reflected in the application unless you manually reset the cache.
Additionally, because the Role and Permission models are Eloquent models which implement the `RefreshesPermissionCache` trait, creating and deleting Roles and Permissions will automatically clear the cache. If you have created your own models which do not extend the default models then you will need to implement the trait yourself.
### Manual cache reset
To manually reset the cache for this package, you can run the following in your app code:
```php
app()->make(\Spatie\Permission\PermissionRegistrar::class)->forgetCachedPermissions();
```
Or you can use an Artisan command:
```bash
php artisan permission:cache-reset
```
### Cache Identifier
TIP: If you are leveraging a caching service such as `redis` or `memcached` and there are other sites
running on your server, you could run into cache clashes between apps. It is prudent to set your own
cache `prefix` in Laravel's `/config/cache.php` to something unique for each application.
This will prevent other applications from accidentally using/changing your cached data.

View File

@@ -0,0 +1,26 @@
---
title: Exceptions
weight: 3
---
If you need to override exceptions thrown by this package, you can simply use normal [Laravel practices for handling exceptions](https://laravel.com/docs/errors#render-method).
An example is shown below for your convenience, but nothing here is specific to this package other than the name of the exception.
You can find all the exceptions added by this package in the code here: https://github.com/spatie/laravel-permission/tree/master/src/Exceptions
**app/Exceptions/Handler.php**
```php
public function render($request, Throwable $exception)
{
if ($exception instanceof \Spatie\Permission\Exceptions\UnauthorizedException) {
return response()->json([
'responseMessage' => 'You do not have the required authorization.',
'responseStatus' => 403,
]);
}
return parent::render($request, $exception);
}
```

View File

@@ -0,0 +1,35 @@
---
title: Extending
weight: 4
---
## Extending User Models
Laravel's authorization features are available in models which implement the `Illuminate\Foundation\Auth\Access\Authorizable` trait.
By default Laravel does this in `\App\User` by extending `Illuminate\Foundation\Auth\User`, in which the trait and `Illuminate\Contracts\Auth\Access\Authorizable` contract are declared.
If you are creating your own User models and wish Authorization features to be available, you need to implement `Illuminate\Contracts\Auth\Access\Authorizable` in one of those ways as well.
## Extending Role and Permission Models
If you are extending or replacing the role/permission models, you will need to specify your new models in this package's `config/permission.php` file.
First be sure that you've published the configuration file (see the Installation instructions), and edit it to update the `models.role` and `models.permission` values to point to your new models.
Note the following requirements when extending/replacing the models:
### Extending
If you need to EXTEND the existing `Role` or `Permission` models note that:
- Your `Role` model needs to extend the `Spatie\Permission\Models\Role` model
- Your `Permission` model needs to extend the `Spatie\Permission\Models\Permission` model
### Replacing
If you need to REPLACE the existing `Role` or `Permission` models you need to keep the following things in mind:
- Your `Role` model needs to implement the `Spatie\Permission\Contracts\Role` contract
- Your `Permission` model needs to implement the `Spatie\Permission\Contracts\Permission` contract
## Migrations - Adding fields to your models
You can add your own migrations to make changes to the role/permission tables, as you would for adding/changing fields in any other tables in your Laravel project.
Following that, you can add any necessary logic for interacting with those fields into your custom/extended Models.

View File

@@ -0,0 +1,8 @@
---
title: Other
weight: 8
---
Schema Diagram:
You can find a schema diagram at https://drawsql.app/templates/laravel-permission

View File

@@ -0,0 +1,92 @@
---
title: Extending PhpStorm
weight: 7
---
# Extending PhpStorm to support Blade Directives of this package
1. In PhpStorm, open Preferences, and navigate to **Languages and Frameworks -> PHP -> Blade**
(File | Settings | Languages & Frameworks | PHP | Blade)
2. Uncheck "Use default settings", then click on the `Directives` tab.
3. Add the following new directives for the laravel-permission package:
**role**
- has parameter = YES
- Prefix: `<?php if(auth()->check() && auth()->user()->hasRole(`
- Suffix: `)); ?>`
--
**endrole**
- has parameter = NO
- Prefix: blank
- Suffix: blank
--
**hasrole**
- has parameter = YES
- Prefix: `<?php if(auth()->check() && auth()->user()->hasRole(`
- Suffix: `)); ?>`
--
**endhasrole**
- has parameter = NO
- Prefix: blank
- Suffix: blank
--
**hasanyrole**
- has parameter = YES
- Prefix: `<?php if(auth()->check() && auth()->user()->hasAnyRole(`
- Suffix: `)); ?>`
--
**endhasanyrole**
- has parameter = NO
- Prefix: blank
- Suffix: blank
--
**hasallroles**
- has parameter = YES
- Prefix: `<?php if(auth()->check() && auth()->user()->hasAllRoles(`
- Suffix: `)); ?>`
--
**endhasallroles**
- has parameter = NO
- Prefix: blank
- Suffix: blank
--
**unlessrole**
- has parameter = YES
- Prefix: `<?php if(auth()->check() && !auth()->user()->hasRole(`
- Suffix: `)); ?>`
--
**endunlessrole**
- has parameter = NO
- Prefix: blank
- Suffix: blank
--

View File

@@ -0,0 +1,40 @@
---
title: Database Seeding
weight: 2
---
You may discover that it is best to flush this package's cache before seeding, to avoid cache conflict errors. This can be done directly in a seeder class. Here is a sample seeder, which first clears the cache, creates permissions and then assigns permissions to roles (the order of these steps is intentional):
```php
use Illuminate\Database\Seeder;
use Spatie\Permission\Models\Role;
use Spatie\Permission\Models\Permission;
class RolesAndPermissionsSeeder extends Seeder
{
public function run()
{
// Reset cached roles and permissions
app()[\Spatie\Permission\PermissionRegistrar::class]->forgetCachedPermissions();
// create permissions
Permission::create(['name' => 'edit articles']);
Permission::create(['name' => 'delete articles']);
Permission::create(['name' => 'publish articles']);
Permission::create(['name' => 'unpublish articles']);
// create roles and assign created permissions
// this can be done as separate statements
$role = Role::create(['name' => 'writer']);
$role->givePermissionTo('edit articles');
// or may be done by chaining
$role = Role::create(['name' => 'moderator'])
->givePermissionTo(['publish articles', 'unpublish articles']);
$role = Role::create(['name' => 'super-admin']);
$role->givePermissionTo(Permission::all());
}
}
```

View File

@@ -0,0 +1,20 @@
---
title: Timestamps
weight: 8
---
### Excluding Timestamps from JSON
If you want to exclude timestamps from JSON output of role/permission pivots, you can extend the Role and Permission models into your own App namespace and mark the pivot as hidden:
```php
protected $hidden = ['pivot'];
```
### Adding Timestamps to Pivots
If you want to add timestamps to your pivot tables, you can do it with a few steps:
- update the tables by calling `$table->timestamps();` in a migration
- extend the Permission and Role models and add `->withTimestamps();` to the BelongsToMany relationshps for `roles()` and `permissions()`
- update your User models (wherever you use the HasRoles or HasPermissions traits) by adding `->withTimestamps();` to the BelongsToMany relationshps for `roles()` and `permissions()`

View File

@@ -0,0 +1,18 @@
---
title: UI Options
weight: 10
---
## Need a UI?
The package doesn't come with any screens out of the box, you should build that yourself. Here are some options to get you started:
- If you'd like to build your own UI, and understand the underlying logic for Gates and Roles and Users, the [Laravel 6 User Login and Management With Roles](https://www.youtube.com/watch?v=7PpJsho5aak&list=PLxFwlLOncxFLazmEPiB4N0iYc3Dwst6m4) video series by Mark Twigg of Penguin Digital gives thorough coverage to the topic, the theory, and implementation of a basic Roles system, independent of this Permissions Package.
- [Laravel Nova package by @vyuldashev for managing Roles and Permissions](https://github.com/vyuldashev/nova-permission)
- [Laravel Nova package by @paras-malhotra for managing Roles and Permissions and permissions based authorization for Nova Resources](https://github.com/insenseanalytics/laravel-nova-permission)
- [How to create a UI for managing the permissions and roles](http://www.qcode.in/easy-roles-and-permissions-in-laravel-5-4/)
- [Laravel User Management for managing users, roles, permissions, departments and authorization](https://github.com/Mekaeil/LaravelUserManagement) by [Mekaeil](https://github.com/Mekaeil)

View File

@@ -0,0 +1,18 @@
---
title: Unit testing
weight: 1
---
In your application's tests, if you are not seeding roles and permissions as part of your test `setUp()` then you may run into a chicken/egg situation where roles and permissions aren't registered with the gate (because your tests create them after that gate registration is done). Working around this is simple: In your tests simply add a `setUp()` instruction to re-register the permissions, like this:
```php
public function setUp(): void
{
// first include all the normal setUp operations
parent::setUp();
// now re-register all the roles and permissions
$this->app->make(\Spatie\Permission\PermissionRegistrar::class)->registerPermissions();
}
```

View File

@@ -0,0 +1,119 @@
---
title: UUID
weight: 6
---
If you're using UUIDs or GUIDs for your User models there are a few considerations to note.
> THIS IS NOT A FULL LESSON ON HOW TO IMPLEMENT UUIDs IN YOUR APP.
Since each UUID implementation approach is different, some of these may or may not benefit you. As always, your implementation may vary.
### Migrations
You will probably want to update the `create_permission_tables.php` migration:
If your User models are using `uuid` instead of `unsignedBigInteger` then you'll need to reflect the change in the migration provided by this package. Something like this would be typical, for both `model_has_permissions` and `model_has_roles` tables:
```diff
- $table->unsignedBigInteger($columnNames['model_morph_key'])
+ $table->uuid($columnNames['model_morph_key'])
```
OPTIONAL: If you also want the roles and permissions to use a UUID for their `id` value, then you'll need to also change the id fields accordingly, and manually set the primary key. LEAVE THE FIELD NAME AS `id` unless you also change it in dozens of other places.
```diff
Schema::create($tableNames['permissions'], function (Blueprint $table) {
- $table->bigIncrements('id');
+ $table->uuid('id');
$table->string('name');
$table->string('guard_name');
$table->timestamps();
+ $table->primary('id');
});
Schema::create($tableNames['roles'], function (Blueprint $table) {
- $table->bigIncrements('id');
+ $table->uuid('id');
$table->string('name');
$table->string('guard_name');
$table->timestamps();
+ $table->primary('id');
});
Schema::create($tableNames['model_has_permissions'], function (Blueprint $table) use ($tableNames, $columnNames) {
- $table->bigIncrements('permission_id');
+ $table->uuid('permission_id');
...
Schema::create($tableNames['model_has_roles'], function (Blueprint $table) use ($tableNames, $columnNames) {
- $table->bigIncrements('role_id');
+ $table->uuid('role_id');
...
Schema::create($tableNames['role_has_permissions'], function (Blueprint $table) use ($tableNames) {
- $table->bigIncrements('permission_id');
- $table->bigIncrements('role_id');
+ $table->uuid('permission_id');
+ $table->uuid('role_id');
```
### Configuration (OPTIONAL)
You might want to change the pivot table field name from `model_id` to `model_uuid`, just for semantic purposes.
For this, in the configuration file edit `column_names.model_morph_key`:
- OPTIONAL: Change to `model_uuid` instead of the default `model_id`. (The default of `model_id` is shown in this snippet below. Change it to match your needs.)
'column_names' => [
/*
* Change this if you want to name the related model primary key other than
* `model_id`.
*
* For example, this would be nice if your primary keys are all UUIDs. In
* that case, name this `model_uuid`.
*/
'model_morph_key' => 'model_id',
],
- If you extend the models into your app, be sure to list those models in your configuration file. See the Extending section of the documentation and the Models section below.
### Models
If you want all the role/permission objects to have a UUID instead of an integer, you will need to Extend the default Role and Permission models into your own namespace in order to set some specific properties. (See the Extending section of the docs, where it explains requirements of Extending, as well as the configuration settings you need to update.)
- You may want to set `protected $keyType = 'string';` so Laravel handles joins as strings and doesn't cast to integer.
- OPTIONAL: If you changed the field name in your migrations, you must set `protected $primaryKey = 'uuid';` to match.
- Usually for UUID you will also set `public $incrementing = false;`. Remove it if it causes problems for you.
It is common to use a trait to handle the $keyType and $incrementing settings, as well as add a boot event trigger to ensure new records are assigned a uuid. You would `use` this trait in your User and extended Role/Permission models. An example `UuidTrait` is shown here for inspiration. Adjust to suit your needs.
```php
<?php
namespace App;
use Facades\Str;
trait UuidTrait
{
public $incrementing = false;
protected $keyType = 'string';
protected static function boot()
{
parent::boot();
static::creating(function ($model) {
$model->{$model->getKeyName()} = $model->{$model->getKeyName()} ?: (string) Str::orderedUuid();
});
}
}
```
### User Models
> Troubleshooting tip: In the ***Prerequisites*** section of the docs we remind you that your User model must implement the `Illuminate\Contracts\Auth\Access\Authorizable` contract so that the Gate features are made available to the User object.
In the default User model provided with Laravel, this is done by extending another model (aliased to `Authenticatable`), which extends the base Eloquent model.
However, your app's UUID implementation may need to override that in order to set some of the properties mentioned in the Models section above.
If you are running into difficulties, you may want to double-check whether your User model is doing UUIDs consistent with other parts of your app.

View File

@@ -0,0 +1,4 @@
---
title: Basic Usage
weight: 1
---

View File

@@ -0,0 +1,54 @@
---
title: Using artisan commands
weight: 7
---
## Creating roles and permissions with Artisan Commands
You can create a role or permission from the console with artisan commands.
```bash
php artisan permission:create-role writer
```
```bash
php artisan permission:create-permission "edit articles"
```
When creating permissions/roles for specific guards you can specify the guard names as a second argument:
```bash
php artisan permission:create-role writer web
```
```bash
php artisan permission:create-permission "edit articles" web
```
When creating roles you can also create and link permissions at the same time:
```bash
php artisan permission:create-role writer web "create articles|edit articles"
```
## Displaying roles and permissions in the console
There is also a `show` command to show a table of roles and permissions per guard:
```bash
php artisan permission:show
```
## Resetting the Cache
When you use the built-in functions for manipulating roles and permissions, the cache is automatically reset for you, and relations are automatically reloaded for the current model record.
See the Advanced-Usage/Cache section of these docs for detailed specifics.
If you need to manually reset the cache for this package, you may use the following artisan command:
```bash
php artisan permission:cache-reset
```
Again, it is more efficient to use the API provided by this package, instead of manually clearing the cache.

View File

@@ -0,0 +1,97 @@
---
title: Basic Usage
weight: 1
---
First, add the `Spatie\Permission\Traits\HasRoles` trait to your `User` model(s):
```php
use Illuminate\Foundation\Auth\User as Authenticatable;
use Spatie\Permission\Traits\HasRoles;
class User extends Authenticatable
{
use HasRoles;
// ...
}
```
This package allows for users to be associated with permissions and roles. Every role is associated with multiple permissions.
A `Role` and a `Permission` are regular Eloquent models. They require a `name` and can be created like this:
```php
use Spatie\Permission\Models\Role;
use Spatie\Permission\Models\Permission;
$role = Role::create(['name' => 'writer']);
$permission = Permission::create(['name' => 'edit articles']);
```
A permission can be assigned to a role using 1 of these methods:
```php
$role->givePermissionTo($permission);
$permission->assignRole($role);
```
Multiple permissions can be synced to a role using 1 of these methods:
```php
$role->syncPermissions($permissions);
$permission->syncRoles($roles);
```
A permission can be removed from a role using 1 of these methods:
```php
$role->revokePermissionTo($permission);
$permission->removeRole($role);
```
If you're using multiple guards the `guard_name` attribute needs to be set as well. Read about it in the [using multiple guards](../multiple-guards) section of the readme.
The `HasRoles` trait adds Eloquent relationships to your models, which can be accessed directly or used as a base query:
```php
// get a list of all permissions directly assigned to the user
$permissionNames = $user->getPermissionNames(); // collection of name strings
$permissions = $user->permissions; // collection of permission objects
// get all permissions for the user, either directly, or from roles, or from both
$permissions = $user->getDirectPermissions();
$permissions = $user->getPermissionsViaRoles();
$permissions = $user->getAllPermissions();
// get the names of the user's roles
$roles = $user->getRoleNames(); // Returns a collection
```
The `HasRoles` trait also adds a `role` scope to your models to scope the query to certain roles or permissions:
```php
$users = User::role('writer')->get(); // Returns only users with the role 'writer'
```
The `role` scope can accept a string, a `\Spatie\Permission\Models\Role` object or an `\Illuminate\Support\Collection` object.
The same trait also adds a scope to only get users that have a certain permission.
```php
$users = User::permission('edit articles')->get(); // Returns only users with the permission 'edit articles' (inherited or directly)
```
The scope can accept a string, a `\Spatie\Permission\Models\Permission` object or an `\Illuminate\Support\Collection` object.
### Eloquent
Since Role and Permission models are extended from Eloquent models, basic Eloquent calls can be used as well:
```php
$all_users_with_all_their_roles = User::with('roles')->get();
$all_users_with_all_direct_permissions = User::with('permissions')->get();
$all_roles_in_database = Role::all()->pluck('name');
$users_without_any_roles = User::doesntHave('roles')->get();
```

View File

@@ -0,0 +1,91 @@
---
title: Blade directives
weight: 4
---
## Permissions
This package doesn't add any **permission**-specific Blade directives.
Instead, use Laravel's native `@can` directive to check if a user has a certain permission.
```php
@can('edit articles')
//
@endcan
```
or
```php
@if(auth()->user()->can('edit articles') && $some_other_condition)
//
@endif
```
You can use `@can`, `@cannot`, `@canany`, and `@guest` to test for permission-related access.
## Roles
As discussed in the Best Practices section of the docs, **it is strongly recommended to always use permission directives**, instead of role directives.
Additionally, if your reason for testing against Roles is for a Super-Admin, see the *Defining A Super-Admin* section of the docs.
If you actually need to test for Roles, this package offers some Blade directives to verify whether the currently logged in user has all or any of a given list of roles.
Optionally you can pass in the `guard` that the check will be performed on as a second argument.
#### Blade and Roles
Check for a specific role:
```php
@role('writer')
I am a writer!
@else
I am not a writer...
@endrole
```
is the same as
```php
@hasrole('writer')
I am a writer!
@else
I am not a writer...
@endhasrole
```
Check for any role in a list:
```php
@hasanyrole($collectionOfRoles)
I have one or more of these roles!
@else
I have none of these roles...
@endhasanyrole
// or
@hasanyrole('writer|admin')
I am either a writer or an admin or both!
@else
I have none of these roles...
@endhasanyrole
```
Check for all roles:
```php
@hasallroles($collectionOfRoles)
I have all of these roles!
@else
I do not have all of these roles...
@endhasallroles
// or
@hasallroles('writer|admin')
I am both a writer and an admin!
@else
I do not have all of these roles...
@endhasallroles
```
Alternatively, `@unlessrole` gives the reverse for checking a singular role, like this:
```php
@unlessrole('does not have this role')
I do not have the role
@else
I do have the role
@endunlessrole
```

View File

@@ -0,0 +1,67 @@
---
title: Direct Permissions
weight: 2
---
A permission can be given to any user:
```php
$user->givePermissionTo('edit articles');
// You can also give multiple permission at once
$user->givePermissionTo('edit articles', 'delete articles');
// You may also pass an array
$user->givePermissionTo(['edit articles', 'delete articles']);
```
A permission can be revoked from a user:
```php
$user->revokePermissionTo('edit articles');
```
Or revoke & add new permissions in one go:
```php
$user->syncPermissions(['edit articles', 'delete articles']);
```
You can check if a user has a permission:
```php
$user->hasPermissionTo('edit articles');
```
Or you may pass an integer representing the permission id
```php
$user->hasPermissionTo('1');
$user->hasPermissionTo(Permission::find(1)->id);
$user->hasPermissionTo($somePermission->id);
```
You can check if a user has Any of an array of permissions:
```php
$user->hasAnyPermission(['edit articles', 'publish articles', 'unpublish articles']);
```
...or if a user has All of an array of permissions:
```php
$user->hasAllPermissions(['edit articles', 'publish articles', 'unpublish articles']);
```
You may also pass integers to lookup by permission id
```php
$user->hasAnyPermission(['edit articles', 1, 5]);
```
Saved permissions will be registered with the `Illuminate\Auth\Access\Gate` class for the default guard. So you can
check if a user has a permission with Laravel's default `can` function:
```php
$user->can('edit articles');
```

View File

@@ -0,0 +1,83 @@
---
title: Using a middleware
weight: 7
---
## Default Middleware
For checking against a single permission (see Best Practices) using `can`, you can use the built-in Laravel middleware provided by `\Illuminate\Auth\Middleware\Authorize::class` like this:
```php
Route::group(['middleware' => ['can:publish articles']], function () {
//
});
```
## Package Middleware
This package comes with `RoleMiddleware`, `PermissionMiddleware` and `RoleOrPermissionMiddleware` middleware. You can add them inside your `app/Http/Kernel.php` file.
```php
protected $routeMiddleware = [
// ...
'role' => \Spatie\Permission\Middlewares\RoleMiddleware::class,
'permission' => \Spatie\Permission\Middlewares\PermissionMiddleware::class,
'role_or_permission' => \Spatie\Permission\Middlewares\RoleOrPermissionMiddleware::class,
];
```
Then you can protect your routes using middleware rules:
```php
Route::group(['middleware' => ['role:super-admin']], function () {
//
});
Route::group(['middleware' => ['permission:publish articles']], function () {
//
});
Route::group(['middleware' => ['role:super-admin','permission:publish articles']], function () {
//
});
Route::group(['middleware' => ['role_or_permission:super-admin|edit articles']], function () {
//
});
Route::group(['middleware' => ['role_or_permission:publish articles']], function () {
//
});
```
Alternatively, you can separate multiple roles or permission with a `|` (pipe) character:
```php
Route::group(['middleware' => ['role:super-admin|writer']], function () {
//
});
Route::group(['middleware' => ['permission:publish articles|edit articles']], function () {
//
});
Route::group(['middleware' => ['role_or_permission:super-admin|edit articles']], function () {
//
});
```
You can protect your controllers similarly, by setting desired middleware in the constructor:
```php
public function __construct()
{
$this->middleware(['role:super-admin','permission:publish articles|edit articles']);
}
```
```php
public function __construct()
{
$this->middleware(['role_or_permission:super-admin|edit articles']);
}
```

View File

@@ -0,0 +1,60 @@
---
title: Using multiple guards
weight: 6
---
When using the default Laravel auth configuration all of the core methods of this package will work out of the box, no extra configuration required.
However, when using multiple guards they will act like namespaces for your permissions and roles. Meaning every guard has its own set of permissions and roles that can be assigned to their user model.
### The Downside To Multiple Guards
Note that this package requires you to register a permission name for each guard you want to authenticate with. So, "edit-article" would have to be created multiple times for each guard your app uses. An exception will be thrown if you try to authenticate against a non-existing permission+guard combination. Same for roles.
> **Tip**: If your app uses only a single guard, but is not `web` (Laravel's default, which shows "first" in the auth config file) then change the order of your listed guards in your `config/auth.php` to list your primary guard as the default and as the first in the list of defined guards. While you're editing that file, best to remove any guards you don't use, too.
### Using permissions and roles with multiple guards
When creating new permissions and roles, if no guard is specified, then the **first** defined guard in `auth.guards` config array will be used.
```php
// Create a manager role for users authenticating with the admin guard:
$role = Role::create(['guard_name' => 'admin', 'name' => 'manager']);
// Define a `publish articles` permission for the admin users belonging to the admin guard
$permission = Permission::create(['guard_name' => 'admin', 'name' => 'publish articles']);
// Define a *different* `publish articles` permission for the regular users belonging to the web guard
$permission = Permission::create(['guard_name' => 'web', 'name' => 'publish articles']);
```
To check if a user has permission for a specific guard:
```php
$user->hasPermissionTo('publish articles', 'admin');
```
> **Note**: When determining whether a role/permission is valid on a given model, it checks against the first matching guard in this order (it does NOT check role/permission for EACH possibility, just the first match):
- first the guardName() method if it exists on the model;
- then the `$guard_name` property if it exists on the model;
- then the first-defined guard/provider combination in the `auth.guards` config array that matches the logged-in user's guard;
- then the `auth.defaults.guard` config (which is the user's guard if they are logged in, else the default in the file).
### Assigning permissions and roles to guard users
You can use the same core methods to assign permissions and roles to users; just make sure the `guard_name` on the permission or role matches the guard of the user, otherwise a `GuardDoesNotMatch` or `Role/PermissionDoesNotExist` exception will be thrown.
### Using blade directives with multiple guards
You can use all of the blade directives offered by this package by passing in the guard you wish to use as the second argument to the directive:
```php
@role('super-admin', 'admin')
I am a super-admin!
@else
I am not a super-admin...
@endrole
```

View File

@@ -0,0 +1,169 @@
---
title: Example App
weight: 90
---
## Creating A Demo App
If you want to just try out the features of this package you can get started with the following.
The examples on this page are primarily added for assistance in creating a quick demo app for troubleshooting purposes, to post the repo on github for convenient sharing to collaborate or get support.
If you're new to Laravel or to any of the concepts mentioned here, you can learn more in the [Laravel documentation](https://laravel.com/docs/) and in the free videos at Laracasts such as this series: https://laracasts.com/series/laravel-6-from-scratch/
### Initial setup:
```sh
cd ~/Sites
laravel new mypermissionsdemo
cd mypermissionsdemo
git init
git add .
git commit -m "Fresh Laravel Install"
# Environment
cp -n .env.example .env
sed -i '' 's/DB_CONNECTION=mysql/DB_CONNECTION=sqlite/' .env
sed -i '' 's/DB_DATABASE=laravel/#DB_DATABASE=laravel/' .env
touch database/database.sqlite
# Package
composer require spatie/laravel-permission
php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider"
git add .
git commit -m "Add Spatie Laravel Permissions package"
php artisan migrate:fresh
# Add `HasRoles` trait to User model
sed -i '' $'s/use Notifiable;/use Notifiable;\\\n use \\\\Spatie\\\\Permission\\\\Traits\\\\HasRoles;/' app/User.php
git add . && git commit -m "Add HasRoles trait"
# Add Laravel's basic auth scaffolding
composer require laravel/ui --dev
php artisan ui bootstrap --auth
# npm install && npm run prod
git add . && git commit -m "Setup auth scaffold"
```
### Add some basic permissions
- Add a new file, `/database/seeds/PermissionsDemoSeeder.php` such as the following (You could create it with `php artisan make:seed` and then edit the file accordingly):
```php
<?php
use Illuminate\Database\Seeder;
use Spatie\Permission\Models\Permission;
use Spatie\Permission\Models\Role;
use Spatie\Permission\PermissionRegistrar;
class PermissionsDemoSeeder extends Seeder
{
/**
* Create the initial roles and permissions.
*
* @return void
*/
public function run()
{
// Reset cached roles and permissions
app()[PermissionRegistrar::class]->forgetCachedPermissions();
// create permissions
Permission::create(['name' => 'edit articles']);
Permission::create(['name' => 'delete articles']);
Permission::create(['name' => 'publish articles']);
Permission::create(['name' => 'unpublish articles']);
// create roles and assign existing permissions
$role1 = Role::create(['name' => 'writer']);
$role1->givePermissionTo('edit articles');
$role1->givePermissionTo('delete articles');
$role2 = Role::create(['name' => 'admin']);
$role2->givePermissionTo('publish articles');
$role2->givePermissionTo('unpublish articles');
$role3 = Role::create(['name' => 'super-admin']);
// gets all permissions via Gate::before rule; see AuthServiceProvider
// create demo users
$user = Factory(App\User::class)->create([
'name' => 'Example User',
'email' => 'test@example.com',
]);
$user->assignRole($role1);
$user = Factory(App\User::class)->create([
'name' => 'Example Admin User',
'email' => 'admin@example.com',
]);
$user->assignRole($role2);
$user = Factory(App\User::class)->create([
'name' => 'Example Super-Admin User',
'email' => 'superadmin@example.com',
]);
$user->assignRole($role3);
}
}
```
- re-migrate and seed the database:
```sh
composer dump-autoload
php artisan migrate:fresh --seed --seeder=PermissionsDemoSeeder
```
### Grant Super-Admin access
Super-Admins are a common feature. Using the following approach allows that when your Super-Admin user is logged in, all permission-checks in your app which call `can()` or `@can()` will return true.
- Add a Gate::before check in your `AuthServiceProvider`:
```diff
public function boot()
{
$this->registerPolicies();
//
+ // Implicitly grant "Super Admin" role all permission checks using can()
+ Gate::before(function ($user, $ability) {
+ if ($user->hasRole('Super-Admin')) {
+ return true;
+ }
+ });
}
```
### Application Code
The permissions created in the seeder above imply that there will be some sort of Posts or Article features, and that various users will have various access control levels to manage/view those objects.
Your app will have Models, Controllers, routes, Views, Factories, Policies, Tests, middleware, and maybe additional Seeders.
You can see examples of these in the demo app at https://github.com/drbyte/spatie-permissions-demo/
## Sharing
To share your app on Github for easy collaboration:
- create a new public repository on Github, without any extras like readme/etc.
- follow github's sample code for linking your local repo and uploading the code. It will look like this:
```sh
git remote add origin git@github.com:YOURUSERNAME/REPONAME.git
git push -u origin master
```
The above only needs to be done once.
- then add the rest of your code by making new commits:
```sh
git add .
git commit -m "Explain what your commit is about here"
git push origin master
```
Repeat the above process whenever you change code that you want to share.
Those are the basics!

View File

@@ -0,0 +1,140 @@
---
title: Using permissions via roles
weight: 3
---
A role can be assigned to any user:
```php
$user->assignRole('writer');
// You can also assign multiple roles at once
$user->assignRole('writer', 'admin');
// or as an array
$user->assignRole(['writer', 'admin']);
```
A role can be removed from a user:
```php
$user->removeRole('writer');
```
Roles can also be synced:
```php
// All current roles will be removed from the user and replaced by the array given
$user->syncRoles(['writer', 'admin']);
```
You can determine if a user has a certain role:
```php
$user->hasRole('writer');
// or at least one role from an array of roles:
$user->hasRole(['editor', 'moderator']);
```
You can also determine if a user has any of a given list of roles:
```php
$user->hasAnyRole(['writer', 'reader']);
// or
$user->hasAnyRole('writer', 'reader');
```
You can also determine if a user has all of a given list of roles:
```php
$user->hasAllRoles(Role::all());
```
The `assignRole`, `hasRole`, `hasAnyRole`, `hasAllRoles` and `removeRole` functions can accept a
string, a `\Spatie\Permission\Models\Role` object or an `\Illuminate\Support\Collection` object.
A permission can be given to a role:
```php
$role->givePermissionTo('edit articles');
```
You can determine if a role has a certain permission:
```php
$role->hasPermissionTo('edit articles');
```
A permission can be revoked from a role:
```php
$role->revokePermissionTo('edit articles');
```
The `givePermissionTo` and `revokePermissionTo` functions can accept a
string or a `Spatie\Permission\Models\Permission` object.
Permissions are inherited from roles automatically.
Additionally, individual permissions can be assigned to the user too.
For instance:
```php
$role = Role::findByName('writer');
$role->givePermissionTo('edit articles');
$user->assignRole('writer');
$user->givePermissionTo('delete articles');
```
In the above example, a role is given permission to edit articles and this role is assigned to a user.
Now the user can edit articles and additionally delete articles. The permission of 'delete articles' is the user's direct permission because it is assigned directly to them.
When we call `$user->hasDirectPermission('delete articles')` it returns `true`,
but `false` for `$user->hasDirectPermission('edit articles')`.
This method is useful if one builds a form for setting permissions for roles and users in an application and wants to restrict or change inherited permissions of roles of the user, i.e. allowing to change only direct permissions of the user.
You can check if the user has All or Any of a set of permissions directly assigned:
```php
// Check if the user has All direct permissions
$user->hasAllDirectPermissions(['edit articles', 'delete articles']);
// Check if the user has Any permission directly
$user->hasAnyDirectPermission(['create articles', 'delete articles']);
```
By following the previous example, when we call `$user->hasAllDirectPermissions(['edit articles', 'delete articles'])`
it returns `true`, because the user has all these direct permissions.
When we call
`$user->hasAnyDirectPermission('edit articles')`, it returns `true` because the user has one of the provided permissions.
You can list all of these permissions:
```php
// Direct permissions
$user->getDirectPermissions() // Or $user->permissions;
// Permissions inherited from the user's roles
$user->getPermissionsViaRoles();
// All permissions which apply on the user (inherited and direct)
$user->getAllPermissions();
```
All these responses are collections of `Spatie\Permission\Models\Permission` objects.
If we follow the previous example, the first response will be a collection with the `delete article` permission and
the second will be a collection with the `edit article` permission and the third will contain both.
If we follow the previous example, the first response will be a collection with the `delete article` permission and
the second will be a collection with the `edit article` permission and the third will contain both.
### NOTE about using permission names in policies
When calling `authorize()` for a policy method, if you have a permission named the same as one of those policy methods, your permission "name" will take precedence and not fire the policy. For this reason it may be wise to avoid naming your permissions the same as the methods in your policy. While you can define your own method names, you can read more about the defaults Laravel offers in Laravel's documentation at https://laravel.com/docs/authorization#writing-policies

View File

@@ -0,0 +1,49 @@
---
title: Defining a Super-Admin
weight: 5
---
We strongly recommend that a Super-Admin be handled by setting a global `Gate::before` or `Gate::after` rule which checks for the desired role.
Then you can implement the best-practice of primarily using permission-based controls (@can and $user->can, etc) throughout your app, without always having to check for "is this a super-admin" everywhere. Best not to use role-checking (ie: `hasRole`) when you have Super Admin features like this.
## `Gate::before`
If you want a "Super Admin" role to respond `true` to all permissions, without needing to assign all those permissions to a role, you can use Laravel's `Gate::before()` method. For example:
```php
use Illuminate\Support\Facades\Gate;
class AuthServiceProvider extends ServiceProvider
{
public function boot()
{
$this->registerPolicies();
// Implicitly grant "Super Admin" role all permissions
// This works in the app by using gate-related functions like auth()->user->can() and @can()
Gate::before(function ($user, $ability) {
return $user->hasRole('Super Admin') ? true : null;
});
}
}
```
NOTE: `Gate::before` rules need to return `null` rather than `false`, else it will interfere with normal policy operation. [See more.](https://laracasts.com/discuss/channels/laravel/policy-gets-never-called#reply=492526)
Jeffrey Way explains the concept of a super-admin (and a model owner, and model policies) in the [Laravel 6 Authorization Filters](https://laracasts.com/series/laravel-6-from-scratch/episodes/51) video and some related lessons in that chapter.
## `Gate::after`
Alternatively you might want to move the Super Admin check to the `Gate::after` phase instead, particularly if your Super Admin shouldn't be allowed to do things your app doesn't want "anyone" to do, such as writing more than 1 review, or bypassing unsubscribe rules, etc.
The following code snippet is inspired from [Freek's blog article](https://murze.be/when-to-use-gateafter-in-laravel) where this topic is discussed further.
```php
// somewhere in a service provider
Gate::after(function ($user, $ability) {
return $user->hasRole('Super Admin'); // note this returns boolean
});
```

View File

@@ -0,0 +1,68 @@
---
title: Wildcard permissions
weight: 3
---
Wildcard permissions can be enabled in the permission config file:
```php
// config/permission.php
'enable_wildcard_permission' => true,
```
When enabled, wildcard permissions offers you a flexible representation for a variety of permission schemes. The idea
behind wildcard permissions is inspired by the default permission implementation of
[Apache Shiro](https://shiro.apache.org/permissions.html).
A wildcard permission string is made of one or more parts separated by dots (.).
```php
$permission = 'posts.create.1';
```
The meaning of each part of the string depends on the application layer.
> You can use as many parts as you like. So you are not limited to the three-tiered structure, even though
this is the common use-case, representing {resource}.{action}.{target}.
> NOTE: You must actually create the permissions (eg: `posts.create.1`) before you can assign them, and must also create any wildcard permission patterns (eg: `posts.create.*`) before you can check for them.
### Using Wildcards
Each part can also contain wildcards (*). So let's say we assign the following permission to a user:
```php
Permission::create(['name'=>'posts.*']);
$user->givePermissionTo('posts.*');
// is the same as
Permission::create(['name'=>'posts']);
$user->givePermissionTo('posts');
```
Everyone who is assigned to this permission will be allowed every action on posts. It is not necessary to use a
wildcard on the last part of the string. This is automatically assumed.
```php
// will be true
$user->can('posts.create');
$user->can('posts.edit');
$user->can('posts.delete');
```
### Subparts
Besides the use of parts and wildcards, subparts can also be used. Subparts are divided with commas (,). This is a
powerful feature that lets you create complex permission schemes.
```php
// user can only do the actions create, update and view on both resources posts and users
$user->givePermissionTo('posts,users.create,update,view');
// user can do the actions create, update, view on any available resource
$user->givePermissionTo('*.create,update,view');
// user can do any action on posts with ids 1, 4 and 6
$user->givePermissionTo('posts.*.1,4,6');
```
> As said before, the meaning of each part is determined by the application layer! So, you are free to use each part as you like. And you can use as many parts and subparts as you want.

View File

@@ -0,0 +1,4 @@
---
title: Best Practices
weight: 2
---

View File

@@ -0,0 +1,23 @@
---
title: Performance Tips
weight: 10
---
Often we think in terms of "roles have permissions" so we lookup a Role, and call `$role->givePermissionTo()`
to indicate what users with that role are allowed to do. This is perfectly fine!
And yet, in some situations, particularly if your app is deleting and adding new permissions frequently,
you may find that things are more performant if you lookup the permission and assign it to the role, like:
`$permission->assignRole($role)`.
The end result is the same, but sometimes it runs quite a lot faster.
Also, because of the way this package enforces some protections for you, on large databases you may find
that instead of creating permissions with `Permission::create([attributes])` it might be faster to
`$permission = Permission::make([attributes]); $permission->saveOrFail();`
On small apps, most of the above will be moot, and unnecessary.
As always, if you choose to bypass the provided object methods for adding/removing/syncing roles and permissions
by manipulating Role and Permission objects directly in the database,
you will need to manually reset the cache with the PermissionRegistrar's method for that,
as described in the Cache section of the docs.

View File

@@ -0,0 +1,11 @@
---
title: Roles vs Permissions
weight: 1
---
It is generally best to code your app around `permissions` only. That way you can always use the native Laravel `@can` and `can()` directives everywhere in your app.
Roles can still be used to group permissions for easy assignment, and you can still use the role-based helper methods if truly necessary. But most app-related logic can usually be best controlled using the `can` methods, which allows Laravel's Gate layer to do all the heavy lifting.
eg: `users` have `roles`, and `roles` have `permissions`, and your app always checks for `permissions`, not `roles`.

View File

@@ -0,0 +1,12 @@
---
title: Model Policies
weight: 2
---
The best way to incorporate access control for application features is with [Laravel's Model Policies](https://laravel.com/docs/authorization#creating-policies).
Using Policies allows you to simplify things by abstracting your "control" rules into one place, where your application logic can be combined with your permission rules.
Jeffrey Way explains the concept simply in the [Laravel 6 Authorization Filters](https://laracasts.com/series/laravel-6-from-scratch/episodes/51) and [policies](https://laracasts.com/series/laravel-6-from-scratch/episodes/63) videos and in other related lessons in that chapter. He also mentions how to set up a super-admin, both in a model policy and globally in your application.
You can find an example of implementing a model policy with this Laravel Permissions package in this demo app: https://github.com/drbyte/spatie-permissions-demo/blob/master/app/Policies/PostPolicy.php

View File

@@ -0,0 +1,6 @@
---
title: Changelog
weight: 10
---
All notable changes to laravel-permission are documented [on GitHub](https://github.com/spatie/laravel-permission/blob/master/CHANGELOG.md)

Binary file not shown.

After

Width:  |  Height:  |  Size: 383 KiB

View File

@@ -0,0 +1,44 @@
---
title: Installation in Laravel
weight: 4
---
This package can be used with Laravel 5.8 or higher.
1. Consult the Prerequisites page for important considerations regarding your User models!
2. This package publishes a `config/permission.php` file. If you already have a file by that name, you must rename or remove it.
3. You can install the package via composer:
composer require spatie/laravel-permission
4. Optional: The service provider will automatically get registered. Or you may manually add the service provider in your `config/app.php` file:
```
'providers' => [
// ...
Spatie\Permission\PermissionServiceProvider::class,
];
```
5. You should publish [the migration](https://github.com/spatie/laravel-permission/blob/master/database/migrations/create_permission_tables.php.stub) and the [`config/permission.php` config file](https://github.com/spatie/laravel-permission/blob/master/config/permission.php) with:
```
php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider"
```
6. NOTE: If you are using UUIDs, see the Advanced section of the docs on UUID steps, before you continue. It explains some changes you may want to make to the migrations and config file before continuing. It also mentions important considerations after extending this package's models for UUID capability.
7. Run the migrations: After the config and migration have been published and configured, you can create the tables for this package by running:
php artisan migrate
8. Add the necessary trait to your User model: Consult the Basic Usage section of the docs for how to get started using the features of this package.
### Default config file contents
You can view the default config file contents at:
https://github.com/spatie/laravel-permission/blob/master/config/permission.php

View File

@@ -0,0 +1,71 @@
---
title: Installation in Lumen
weight: 5
---
NOTE: Lumen is not officially supported by this package. However, the following are some steps which may help get you started.
First, install the package via Composer:
``` bash
composer require spatie/laravel-permission
```
Copy the required files:
```bash
mkdir -p config
cp vendor/spatie/laravel-permission/config/permission.php config/permission.php
cp vendor/spatie/laravel-permission/database/migrations/create_permission_tables.php.stub database/migrations/2018_01_01_000000_create_permission_tables.php
```
You will also need the `config/auth.php` file. If you don't already have it, copy it from the vendor folder:
```bash
cp vendor/laravel/lumen-framework/config/auth.php config/auth.php
```
Then, in `bootstrap/app.php`, uncomment the `auth` middleware, and register this package's middleware:
```php
$app->routeMiddleware([
'auth' => App\Http\Middleware\Authenticate::class,
'permission' => Spatie\Permission\Middlewares\PermissionMiddleware::class,
'role' => Spatie\Permission\Middlewares\RoleMiddleware::class,
]);
```
... and in the same file, in the ServiceProviders section, register the package configuration, service provider, and cache alias:
```php
$app->configure('permission');
$app->alias('cache', \Illuminate\Cache\CacheManager::class); // if you don't have this already
$app->register(Spatie\Permission\PermissionServiceProvider::class);
```
... and in the same file, since the Authorization layer uses guards you will need to uncomment the AuthServiceProvider line:
```php
$app->register(App\Providers\AuthServiceProvider::class);
```
Ensure your database configuration is set in your `.env` (or `config/database.php` if you have one).
Run the migrations to create the tables for this package:
```bash
php artisan migrate
```
---
### User Model
NOTE: Remember that Laravel's authorization layer requires that your `User` model implement the `Illuminate\Contracts\Auth\Access\Authorizable` contract. In Lumen you will then also need to use the `Laravel\Lumen\Auth\Authorizable` trait.
---
### User Table
NOTE: If you are working with a fresh install of Lumen, then you probably also need a migration file for your Users table. You can create your own, or you can copy a basic one from Laravel:
https://github.com/laravel/laravel/blob/master/database/migrations/2014_10_12_000000_create_users_table.php
(You will need to run `php artisan migrate` after adding this file.)
Remember to update your ModelFactory.php to match the fields in the migration you create/copy.

View File

@@ -0,0 +1,34 @@
---
title: Introduction
weight: 1
---
This package allows you to manage user permissions and roles in a database.
Once installed you can do stuff like this:
```php
// Adding permissions to a user
$user->givePermissionTo('edit articles');
// Adding permissions via a role
$user->assignRole('writer');
$role->givePermissionTo('edit articles');
```
If you're using multiple guards we've got you covered as well. Every guard will have its own set of permissions and roles that can be assigned to the guard's users. Read about it in the [using multiple guards](https://docs.spatie.be/laravel-permission/v3/basic-usage/multiple-guards/) section of the readme.
Because all permissions will be registered on [Laravel's gate](https://laravel.com/docs/authorization), you can check if a user has a permission with Laravel's default `can` function:
```php
$user->can('edit articles');
```
and Blade directives:
```blade
@can('edit articles')
...
@endcan
```

View File

@@ -0,0 +1,33 @@
---
title: Prerequisites
weight: 3
---
This package can be used in Laravel 5.8 or higher.
This package uses Laravel's Gate layer to provide Authorization capabilities.
The Gate/authorization layer requires that your `User` model implement the `Illuminate\Contracts\Auth\Access\Authorizable` contract.
Otherwise the `can()` and `authorize()` methods will not work in your controllers, policies, templates, etc.
In the `Installation` instructions you'll see that the `HasRoles` trait must be added to the User model to enable this package's features.
Thus, a typical basic User model would have these basic minimum requirements:
```php
use Illuminate\Foundation\Auth\User as Authenticatable;
use Spatie\Permission\Traits\HasRoles;
class User extends Authenticatable
{
use HasRoles;
// ...
}
```
Additionally, your `User` model/object MUST NOT have a `role` or `roles` property (or field in the database), nor a `roles()` method on it. Those will interfere with the properties and methods added by the `HasRoles` trait provided by this package, thus causing unexpected outcomes when this package's methods are used to inspect roles and permissions.
Similarly, your `User` model/object MUST NOT have a `permission` or `permissions` property (or field in the database), nor a `permissions()` method on it. Those will interfere with the properties and methods added by the `HasPermissions` trait provided by this package (which is invoked via the `HasRoles` trait).
This package publishes a `config/permission.php` file. If you already have a file by that name, you must rename or remove it, as it will conflict with this package. You could optionally merge your own values with those required by this package, as long as the keys that this package expects are present. See the source file for more details.

View File

@@ -0,0 +1,8 @@
---
title: Questions and issues
weight: 9
---
Find yourself stuck using the package? Found a bug? Do you have general questions or suggestions for improving the package? Feel free to [create an issue on GitHub](https://github.com/spatie/laravel-permission/issues), we'll try to address it as soon as possible.
If you've found a bug regarding security please mail [freek@spatie.be](mailto:freek@spatie.be) instead of using the issue tracker.

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

@@ -0,0 +1,8 @@
---
title: Support us
weight: 2
---
We invest a lot of resources into creating [best in class open source packages](https://spatie.be/open-source). You can support us by [buying one of our paid products](https://spatie.be/open-source/support-us).
We highly appreciate you sending us a postcard from your hometown, mentioning which of our package(s) you are using. You'll find our address on [our contact page](https://spatie.be/about-us). We publish all received postcards on [our virtual postcard wall](https://spatie.be/open-source/postcards).

View File

@@ -0,0 +1,15 @@
---
title: Upgrading
weight: 6
---
### Upgrading from v2 to v3
There are no special requirements for upgrading from v2 to v3, other than changing `^2.xx` (xx can vary) to `^3.0` in your `composer.json` and running `composer update`. Of course, your app must meet the minimum requirements as well.
### Upgrading from v1 to v2
If you're upgrading from v1 to v2, there's no built-in automatic migration/conversion of your data.
You will need to carefully adapt your code and your data manually.
Tip: @fabricecw prepared [a gist which may make your data migration easier](https://gist.github.com/fabricecw/58ee93dd4f99e78724d8acbb851658a4).
You will also need to remove your old `laravel-permission.php` config file and publish the new one `permission.php`, and edit accordingly (setting up your custom settings again in the new file, where relevant).