PHPackages                             parsidev/lmp - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Authentication &amp; Authorization](/categories/authentication)
4. /
5. parsidev/lmp

ActiveLibrary[Authentication &amp; Authorization](/categories/authentication)

parsidev/lmp
============

Permission handling for Laravel 6.0 and up using mongodb

09PHP

Since Oct 11Pushed 6y ago1 watchersCompare

[ Source](https://github.com/parsidev/lmp)[ Packagist](https://packagist.org/packages/parsidev/lmp)[ RSS](/packages/parsidev-lmp/feed)WikiDiscussions master Synced 2d ago

READMEChangelogDependenciesVersions (1)Used By (0)

laravel-permission-mongodb
==========================

[](#laravel-permission-mongodb)

This package allows you to manage user permissions and roles in a database. It is inspired from [laravel-permission](https://github.com/spatie/laravel-permission). Same code same every thing but it is compatible with [laravel-mongodb](https://github.com/jenssegers/laravel-mongodb)

Once installed you can do stuff like this:

```
// 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](#using-multiple-guards) section of the readme.

Because all permissions will be registered on [Laravel's gate](https://laravel.com/docs/6.0/authorization), you can test if a user has a permission with Laravel's default `can` function:

```
$user->can('edit articles');
```

Table of contents
-----------------

[](#table-of-contents)

- [Installation](#installation)
    - [Laravel](#laravel)
- [Usage](#usage)
    - [Using "direct" permissions](#using-direct-permissions)
    - [Using permissions via roles](#using-permissions-via-roles)
    - [Using Blade directives](#using-blade-directives)
- [Using multiple guards](#using-multiple-guards)
    - [Using permissions and roles with multiple guards](#using-permissions-and-roles-with-multiple-guards)
    - [Assigning permissions and roles to guard users](#assigning-permissions-and-roles-to-guard-users)
    - [Using blade directives with multiple guards](#using-blade-directives-with-multiple-guards)
- [Using a middleware](#using-a-middleware)
- [Using artisan commands](#using-artisan-commands)
- [Database Seeding](#database-seeding)
- [Extending](#extending)
- [Cache](#cache)
    - [Manual cache reset](#manual-cache-reset)
    - [Cache Identifier](#cache-identifier)

Installation
------------

[](#installation)

### Laravel

[](#laravel)

This package can be used in Laravel 5.2 and up.

You can install the package via composer:

```
composer require parsidev/lmp
```

In Laravel 6.0 the service provider will automatically get registered. In older versions of the framework just add the service provider in `config/app.php` file:

```
'providers' => [
    // ...
    Parsidev\Permission\PermissionServiceProvider::class,
];
```

You can publish [the migration](database/migrations/create_permission_collections.php.stub) with:

```
php artisan vendor:publish --provider="Parsidev\Permission\PermissionServiceProvider" --tag="migrations"
```

```
php artisan migrate
```

You can publish the config file with:

```
php artisan vendor:publish --provider="Parsidev\Permission\PermissionServiceProvider" --tag="config"
```

When published, the [`config/permission.php`](config/permission.php) config file contains:

```
return [

    'models' => [

        /*
         * When using the "HasRoles" trait from this package, we need to know which
         * Moloquent model should be used to retrieve your permissions. Of course, it
         * is often just the "Permission" model but you may use whatever you like.
         *
         * The model you want to use as a Permission model needs to implement the
         * `Parsidev\Permission\Contracts\Permission` contract.
         */

        'permission' => Parsidev\Permission\Models\Permission::class,

        /*
         * When using the "HasRoles" trait from this package, we need to know which
         * Moloquent model should be used to retrieve your roles. Of course, it
         * is often just the "Role" model but you may use whatever you like.
         *
         * The model you want to use as a Role model needs to implement the
         * `Parsidev\Permission\Contracts\Role` contract.
         */

        'role' => Parsidev\Permission\Models\Role::class,

    ],

    'collection_names' => [

        /*
         * When using the "HasRoles" trait from this package, we need to know which
         * table should be used to retrieve your roles. We have chosen a basic
         * default value but you may easily change it to any table you like.
         */

        'roles' => 'roles',

        /*
         * When using the "HasRoles" trait from this package, we need to know which
         * table should be used to retrieve your permissions. We have chosen a basic
         * default value but you may easily change it to any table you like.
         */

        'permissions' => 'permissions',
    ],

    /*
     * By default all permissions will be cached for 24 hours unless a permission or
     * role is updated. Then the cache will be flushed immediately.
     */

    'cache_expiration_time' => 60 * 24,

    /*
     * By default we'll make an entry in the application log when the permissions
     * could not be loaded. Normally this only occurs while installing the packages.
     *
     * If for some reason you want to disable that logging, set this value to false.
     */

    'log_registration_exception' => true,

    /*
     * When set to true, the required permission/role names are added to the exception
     * message. This could be considered an information leak in some contexts, so
     * the default setting is false here for optimum safety.
     */

    'display_permission_in_exception' => false,
];
```

Usage
-----

[](#usage)

First, add the `Parsidev\Permission\Traits\HasRoles` trait to your `User` model(s):

```
use Illuminate\Auth\Authenticatable;
use Jenssegers\Mongodb\Eloquent\Model as Model;
use Illuminate\Foundation\Auth\Access\Authorizable;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\Access\Authorizable as AuthorizableContract;
use Parsidev\Permission\Traits\HasRoles;

class User extends Model implements AuthenticatableContract, AuthorizableContract
{
    use Authenticatable, Authorizable, HasRoles;

    // ...
}
```

> Note: that if you need to use `HasRoles` trait with another model ex.`Page` you will also need to add `protected $guard_name = 'web';` as well to that model or you would get an error

```
use Jenssegers\Mongodb\Eloquent\Model as Model;
use Parsidev\Permission\Traits\HasRoles;

class Page extends Model
{
    use HasRoles;

    protected $guard_name = 'web'; // or whatever guard you want to use

    // ...
}
```

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 Moloquent models. They require a `name` and can be created like this:

```
use Parsidev\Permission\Models\Role;
use Parsidev\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:

```
$role->givePermissionTo($permission);
$permission->assignRole($role);
```

Multiple permissions can be synced to a role using 1 of these methods:

```
$role->syncPermissions($permissions);
$permission->syncRoles($roles);
```

A permission can be removed from a role using 1 of these methods:

```
$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](#using-multiple-guards) section of the readme.

The `HasRoles` trait adds Moloquent relationships to your models, which can be accessed directly or used as a base query:

```
// get a list of all permissions directly assigned to the user
$permissions = $user->permissions; // Returns a collection

// get all permissions inherited by the user via roles
$permissions = $user->getAllPermissions(); // Returns a collection

// get all permissions names
$permissions = $user->getPermissionNames(); // Returns a collection

// get a collection of all defined roles
$roles = $user->roles->pluck('name'); // Returns a collection

// get all role names
$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:

```
$users = User::role('writer')->get(); // Returns only users with the role 'writer'
$users = User::permission('edit articles')->get(); // Returns only users with the permission 'edit articles'
```

The scope can accept a string, a `\Parsidev\Permission\Models\Role` object, a `\Parsidev\Permission\Models\Permission` object or an `\Illuminate\Support\Collection` object.

### Using "direct" permissions

[](#using-direct-permissions)

A permission can be given to any user with the `HasRoles` trait:

```
$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:

```
$user->revokePermissionTo('edit articles');
```

Or revoke &amp; add new permissions in one go:

```
$user->syncPermissions(['edit articles', 'delete articles']);
```

You can test if a user has a permission:

```
$user->hasPermissionTo('edit articles');
```

...or if a user has multiple permissions:

```
$user->hasAnyPermission(['edit articles', 'publish articles', 'unpublish articles']);
```

Saved permissions will be registered with the `Illuminate\Auth\Access\Gate` class for the default guard. So you can test if a user has a permission with Laravel's default `can` function:

```
$user->can('edit articles');
```

### Using permissions via roles

[](#using-permissions-via-roles)

A role can be assigned to any user:

```
$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:

```
$user->removeRole('writer');
```

Roles can also be synced:

```
// 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:

```
$user->hasRole('writer');
```

You can also determine if a user has any of a given list of roles:

```
$user->hasAnyRole(Role::all());
```

You can also determine if a user has all of a given list of roles:

```
$user->hasAllRoles(Role::all());
```

The `assignRole`, `hasRole`, `hasAnyRole`, `hasAllRoles` and `removeRole` functions can accept a string, a `\Parsidev\Permission\Models\Role` object or an `\Illuminate\Support\Collection` object.

A permission can be given to a role:

```
$role->givePermissionTo('edit articles');
```

You can determine if a role has a certain permission:

```
$role->hasPermissionTo('edit articles');
```

A permission can be revoked from a role:

```
$role->revokePermissionTo('edit articles');
```

The `givePermissionTo` and `revokePermissionTo` functions can accept a string or a `Parsidev\Permission\Models\Permission` object.

Permissions are inherited from roles automatically. Additionally, individual permissions can be assigned to the user too.

For instance:

```
$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 list all of these permissions:

```
// 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 `Parsidev\Permission\Models\Permission` objects.

If we follow the previous example, the first response will be a collection with the `delete article` permission, the second will be a collection with the `edit article` permission and the third will contain both.

### Using Blade directives

[](#using-blade-directives)

This package also adds 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

[](#blade-and-roles)

Test for a specific role:

```
@role('writer')
    I am a writer!
@else
    I am not a writer...
@endrole
```

is the same as

```
@hasrole('writer')
    I am a writer!
@else
    I am not a writer...
@endhasrole
```

Test for any role in a list:

```
@hasanyrole(Role::all())
    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
```

Test for all roles:

```
@hasallroles(Role::all())
    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
```

#### Blade and Permissions

[](#blade-and-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.

```
@can('edit articles')
  //
@endcan
```

or

```
@if(auth()->user()->can('edit articles') && $some_other_condition)
  //
@endif
```

Using multiple guards
---------------------

[](#using-multiple-guards)

When using the default Laravel auth configuration all of the above methods 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.

### Using permissions and roles with multiple guards

[](#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. When creating permissions and roles for specific guards you'll have to specify their `guard_name` on the model:

```
// Create a superadmin role for the admin users

$user->hasPermissionTo('publish articles', 'admin');
```

> **Note**: When determining whether a role/permission is valid on a given model, it chooses the guard in this order: first the `$guard_name` property of the model; then the guard in the config (through a provider); then the first-defined guard in the `auth.guards` config array; then the `auth.defaults.guard` config.

### Assigning permissions and roles to guard users

[](#assigning-permissions-and-roles-to-guard-users)

You can use the same methods to assign permissions and roles to users as described above in [using permissions via roles](#using-permissions-via-roles). Just make sure the `guard_name` on the permission or role matches the guard of the user, otherwise a `GuardDoesNotMatch` exception will be thrown.

### Using blade directives with multiple guards

[](#using-blade-directives-with-multiple-guards)

You can use all of the blade directives listed in [using blade directives](#using-blade-directives) by passing in the guard you wish to use as the second argument to the directive:

```
@role('super-admin', 'admin')
    I am a super-admin!
@else
    I am not a super-admin...
@endrole
```

Using a middleware
------------------

[](#using-a-middleware)

This package comes with `RoleMiddleware` and `PermissionMiddleware` middleware. You can add them inside your `app/Http/Kernel.php` file.

```
protected $routeMiddleware = [
    // ...
    'role' => \Parsidev\Permission\Middlewares\RoleMiddleware::class,
    'permission' => \Parsidev\Permission\Middlewares\PermissionMiddleware::class,
];
```

Then you can protect your routes using middleware rules:

```
Route::group(['middleware' => ['role:super-admin']], function () {
    //
});

Route::group(['middleware' => ['permission:publish articles']], function () {
    //
});

Route::group(['middleware' => ['role:super-admin','permission:publish articles']], function () {
    //
});
```

You can protect your controllers similarly, by setting desired middleware in the constructor:

```
public function __construct()
{
    $this->middleware(['role:super-admin','permission:publish articles|edit articles']);
}
```

You can add something in Laravel exception handler:

```
public function render($request, Exception $exception)
{
    if ($exception instanceof \Parsidev\Permission\Exceptions\UnauthorizedException) {
        // Code here ...
    }

    return parent::render($request, $exception);
}
```

Using artisan commands
----------------------

[](#using-artisan-commands)

You can create a role or permission from a console with artisan commands.

```
php artisan permission:create-role writer
```

```
php artisan permission:create-permission 'edit articles'
```

When creating permissions and roles for specific guards you can specify the guard names as a second argument:

```
php artisan permission:create-role writer web
```

```
php artisan permission:create-permission 'edit articles' web
```

Database Seeding
----------------

[](#database-seeding)

Two notes about Database Seeding:

1. It is best to flush the `parsidev.permission.cache` before seeding, to avoid cache conflict errors. This can be done from an Artisan command (see Troubleshooting: Cache section, later) or directly in a seeder class (see example below).
2. Here's a sample seeder, which clears the cache, creates permissions, and then assigns permissions to roles:

```
use Illuminate\Database\Seeder;
use Parsidev\Permission\Models\Role;
use Parsidev\Permission\Models\Permission;

class RolesAndPermissionsSeeder extends Seeder
{
    public function run()
    {
        // Reset cached roles and permissions
        app()['cache']->forget('parsidev.permission.cache');

        // create permissions
        Permission::firstOrCreate(['name' => 'edit articles']);
        Permission::firstOrCreate(['name' => 'delete articles']);
        Permission::firstOrCreate(['name' => 'publish articles']);
        Permission::firstOrCreate(['name' => 'unpublish articles']);

        // create roles and assign existing permissions
        $role = Role::firstOrCreate(['name' => 'writer']);
        $role->givePermissionTo('edit articles');
        $role->givePermissionTo('delete articles');

        $role = Role::firstOrCreate(['name' => 'admin']);
        $role->givePermissionTo(['publish articles', 'unpublish articles']);
    }
}
```

Extending
---------

[](#extending)

If you need to EXTEND the existing `Role` or `Permission` models note that:

- Your `Role` model needs to extend the `Parsidev\Permission\Models\Role` model
- Your `Permission` model needs to extend the `Parsidev\Permission\Models\Permission` model

If you need to extend or replace the existing `Role` or `Permission` models you just need to keep the following things in mind:

- Your `Role` model needs to implement the `Parsidev\Permission\Contracts\Role` contract
- Your `Permission` model needs to implement the `Parsidev\Permission\Contracts\Permission` contract

In BOTH cases, whether extending or replacing, you will need to specify your new models in the configuration. To do this you must update the `models.role` and `models.permission` values in the configuration file after publishing the configuration with this command:

```
php artisan vendor:publish --provider="Parsidev\Permission\PermissionServiceProvider" --tag="config"
```

Cache
-----

[](#cache)

Role and Permission data are cached to speed up performance.

When you use the supplied methods for manipulating roles and permissions, the cache is automatically reset for you:

```
$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.

### Manual cache reset

[](#manual-cache-reset)

To manually reset the cache for this package, run:

```
php artisan cache:forget parsidev.permission.cache
```

### Cache Identifier

[](#cache-identifier)

> Note: 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. It is prudent to set your own cache `prefix` in `/config/cache.php` for each application uniquely. This will prevent other applications from accidentally using/changing your cached data.

###  Health Score

18

—

LowBetter than 8% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity4

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity35

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/11275201?v=4)[Mohammad Reza](/maintainers/parsidev)[@parsidev](https://github.com/parsidev)

---

Top Contributors

[![parsidev](https://avatars.githubusercontent.com/u/11275201?v=4)](https://github.com/parsidev "parsidev (4 commits)")

### Embed Badge

![Health badge](/badges/parsidev-lmp/health.svg)

```
[![Health](https://phpackages.com/badges/parsidev-lmp/health.svg)](https://phpackages.com/packages/parsidev-lmp)
```

###  Alternatives

[namshi/jose

JSON Object Signing and Encryption library for PHP.

1.8k99.6M101](/packages/namshi-jose)[league/oauth1-client

OAuth 1.0 Client Library

99698.8M106](/packages/league-oauth1-client)[bezhansalleh/filament-shield

Filament support for `spatie/laravel-permission`.

2.8k2.9M88](/packages/bezhansalleh-filament-shield)[gesdinet/jwt-refresh-token-bundle

Implements a refresh token system over Json Web Tokens in Symfony

70516.4M35](/packages/gesdinet-jwt-refresh-token-bundle)[league/oauth2-google

Google OAuth 2.0 Client Provider for The PHP League OAuth2-Client

41721.2M118](/packages/league-oauth2-google)[illuminate/auth

The Illuminate Auth package.

9327.3M1.0k](/packages/illuminate-auth)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
