PHPackages                             foothing/laravel-wrappr - 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. foothing/laravel-wrappr

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

foothing/laravel-wrappr
=======================

Bind permissions to Laravel routes.

0.5.1(8y ago)72391MITPHPPHP &gt;=5.4.0

Since Oct 23Pushed 8y ago1 watchersCompare

[ Source](https://github.com/foothing/laravel-wrappr)[ Packagist](https://packagist.org/packages/foothing/laravel-wrappr)[ RSS](/packages/foothing-laravel-wrappr/feed)WikiDiscussions master Synced 1mo ago

READMEChangelogDependencies (8)Versions (21)Used By (1)

Laravel Wrappr
==============

[](#laravel-wrappr)

[![Build Status](https://camo.githubusercontent.com/90096bbcc95f56102bffd3071e0f35664b2b2b0e38004b17718b270e5a0fd319/68747470733a2f2f7472617669732d63692e6f72672f666f6f7468696e672f6c61726176656c2d7772617070722e7376673f6272616e63683d6d6173746572)](https://travis-ci.org/foothing/laravel-wrappr)[![Code Climate](https://camo.githubusercontent.com/f095ca211b29551027bc31af6aaf07eb6e826b9b8a8fb88237f95f10b079a5dd/68747470733a2f2f636f6465636c696d6174652e636f6d2f6769746875622f666f6f7468696e672f6c61726176656c2d7772617070722f6261646765732f6770612e737667)](https://codeclimate.com/github/foothing/laravel-wrappr)[![Test Coverage](https://camo.githubusercontent.com/3f7f96ba1a47d30ee0a271596c184eb9b76e958246126ca5512d6c122829d57a/68747470733a2f2f636f6465636c696d6174652e636f6d2f6769746875622f666f6f7468696e672f6c61726176656c2d7772617070722f6261646765732f636f7665726167652e737667)](https://codeclimate.com/github/foothing/laravel-wrappr/coverage)

> For Laravel 5.1 use 0.4.10 version

> For Laravel 5.2 and up use the latest 0.x version

This is a Laravel 5 package that aims to simplify the process of binding routes to permissions and it is indepentent from a specific permissions handler, allowing to add route checks even if your permissions handler doesn't support this feature natively.

Also, it tries to put some effort in decoupling your app from the permission handler for what concerns basic operations.

There is a [Lock integration](https://github.com/foothing/laravel-lock-routes)ready to use.

I've plans to implement a `Gate` integration as well, feel free to drop a line if you're interested in this.

Usage example
-------------------------------------------------------

[](#usage-example-)

A basic use case where you want to restrict route access to the `read.users` permission

```
Route::get('api/users/{id?}', ['middleware:wrappr.check:read.users,user,{id}', function() {
	// Access is allowed to users with the 'read.users' permission on
	// the 'user' resource with the {id} identifier
}]);
```

Or, you can define custom route patterns that can help with dynamic urls, assuming you have defined a controller and want to split the access logic on its methods.

```
Route::controller('api/v1/{args?}', 'FooController');
```

Assuming your controller provides the following routes

```
GET /api/v1/resources/users
GET /api/v1/resources/posts
POST /api/v1/services/publish/post
```

you can define a rule like the following to restrict access:

```
[
	'verb' => 'put',
	'path' => 'api/v1/resources/posts/{id}',
	'permissions' => ['posts.create', 'posts.update'],
	'resource' => 'post',
],
```

Contents
--------

[](#contents)

- [Concept](#concept)
- [Install and setup](#setup)
- [Configure the providers](#configure)
- [Use within Laravel Router](#route_basic)
- [Use within custom routes](#route_custom)
- [Install routes with config file](#route_install_config)
- [Install routes programmatically](#route_install_prog)
- [Setup the middleware](#middleware)
    - [A note on route processing order](#route_processing)
- [Middleware Response](#middleware_response)
- [How to develop providers](#providers_develop)
- [License](#license)

Concept
---------------------------------------------------

[](#concept-)

As it happens you may need to switch to another acl library at some time, so i've tried to put some effort into adding an abstract layer that would make your app more maintenaible. This package tries to abstract your app from the acl layer in 2 different ways:

- standard approach to route-based checks
- standard api to basic acl manipulation

In order to access permissions checks, a *permissions provider* that acts as a bridge with the acl library must be set. Also, a *users provider*is required in order to retrieve the authenticated user.

While the *route checks* are the main focus of this project, the *acl manipulation* feature tries to stay out of the way so you'll just use it at will.

Install and Setup
-----------------------------------------------------------

[](#install-and-setup-)

Composer install

```
"require": [
	"foothing/laravel-wrappr": "0.*"
]

```

Add the service provider in your`config/app.php` providers array.

```
'providers' => [
	// ...
	Foothing\Wrappr\WrapprServiceProvider::class
]
```

Then publish package configuration and migration files

```
php artisan vendor:publish --provider="Foothing\Wrappr\WrapprServiceProvider"

```

Configure the providers
---------------------------------------------------------------------

[](#configure-the-providers-)

Once you've published the config file you can configure an *users provider* and a *permissions provider* accordingly to your project setup. This sample configuration will enable the integration with `Lock` and `Illuminate\Auth\Guard`.

In your `config/wrappr.php`

```
'permissionsProvider' => 'Foothing\Wrappr\Lock\LockProvider',
'usersProvider' => 'Foothing\Wrappr\Providers\Users\DefaultProvider',
```

Use within Laravel Router
-------------------------------------------------------------------------

[](#use-within-laravel-router-)

There are two use cases for this package, each implemented in its own Middleware. Let's take a look to the default case. First of all you need to setup the Middleware in your `App\Http\Kernel`.

Add the following line:

```
protected $routeMiddleware = [
	'wrappr.check' => 'Foothing\Wrappr\Middleware\CheckRoute',
];
```

Use the CheckRoute Middleware to control access to your routes like the following *routes.php*:

```
Route::get('api/users', ['middleware:wrappr.check:admin.users', function() {
	// Access is allowed for the users with the 'admin.users' permission
}]);
```

The `CheckRoute` Middleware accepts 3 arguments:

- the required permission
- an optional resource name, i.e. 'user'
- an optional resource identifier (integer)

Example:

```
Route::get('api/users/{id?}', ['middleware:wrappr.check:read.users,user,1', function() {
	// Access is allowed for the users with the 'read.users' permission on
	// the 'user' resource with the {id} identifier
}]);
```

Also, the Middleware can handle your route arguments. Consider the following

```
Route::get('api/users/{id?}', ['middleware:wrappr.check:read.users,user,{id}', function() {
	// Access is allowed for the users with the 'read.users' permission on
	// the 'user' resource with the {id} identifier
}]);
```

When you pass a resource identifier within the brackets, the middleware will try to retrieve the value from the http request automatically.

Use with custom routes
-----------------------------------------------------------------------

[](#use-with-custom-routes-)

When you're not able to fine-control at routes definition level, there's an alternative way of handling permissions. Think about a global RESTful controller like the following:

```
Route::controller('api/v1/{args?}', 'FooController');
```

Assume that your controller applies a variable pattern to handle the routes, like for example

```
GET /api/v1/resources/users
GET /api/v1/resources/posts
POST /api/v1/services/publish/post
```

In this case you won't be able to bind permissions with the previous method, so the `CheckPath` middleware comes to help. In order to enable this behaviour you need some additional setup step.

First step is to run the migration you previously published.

```
php artisan migrate

```

then you have the following two choices.

### Install routes with config file

[](#install-routes-with-config-file-)

You can now configure the routes you would like to put under authorization control In your `config/wrappr.php` edit your `routes` section:

```
'routes' => [

	[
		// Allowed values are 'get', 'post', 'put', 'delete'
		// or the '*' wildcard to enable all verbs.
		'verb' => 'post',

		// The url path we want to restrict access to.
		'path' => 'foo',

		// The required permissions for the given path.
		'permissions' => 'bar',
	],

	// This configuration will control the access to the
	// POST:api/v1/resources/users action, which will be
	// only allowed for users with the 'admin.account' permission
	[
		'verb' => 'post',
		'path' => 'api/v1/resources/users',
		'permissions' => 'admin.account',
	],

	// This configuration will control the access to the
	// PUT:api/v1/resources/posts/{id} action, which will be
	// only allowed for users with both the 'posts.create' and
	// 'posts.update' permissions on the 'post' resource with
	// the {id} identifier.
	[
		'verb' => 'put',
		'path' => 'api/v1/resources/posts/{id}',
		'permissions' => ['posts.create', 'posts.update'],
		'resource' => 'post',
	],

	// In this case the 'admin/' nested routes
	// will be granted access only when the 'admin' permission
	// is available to the current auth user.
	[
		'verb' => '*',
		'path' => 'admin/*',
		'permissions' => ['admin'],
	],

	// You can also use the path wildcard in this way,
	// therefore requiring the 'superadmin' permission
	// for each route starting with 'admin'.
	[
		'verb' => '*',
		'path' => 'admin*',
		'permissions' => ['superadmin'],
	],
],
```

Once you're done with your routes setup run the artisan command

```
php artisan wrappr:install

```

> Note that each time you change the routes configuration you should run the artisan command again in order to refresh them.

### Install routes programmatically

[](#install-routes-programmatically-)

Alternatively you can programmatically setup your routes using the `RouteInstaller`. In this case you won't need the artisan command.

```
$installer = \App::make('foothing.wrappr.installer');
$installer
	->route('get', '/api/v1/*')->requires('api.read')
	->route('put', '/api/v1/*')->requires('api.write')
	->route('delete', '/api/v1/users/{id}/*')->requires('api.write,api.read')->on('users')
	->install();

// Use wildcard
$installer->route('*', '/admin')->requires->('admin.access');
```

### Setup the middleware

[](#setup-the-middleware-)

Add the global Middleware to your `App\Http\Kernel` like this

```
protected $middleware = [
	\Foothing\Wrappr\Middleware\CheckPath::class
];
```

and you're all set.

### A note on routes processing order

[](#a-note-on-routes-processing-order-)

The Middleware will parse all incoming http requests to match your installed routes and it will react like the following

- if a route pattern is not found access is **granted**
- if a route pattern is found it will trigger the permissions provider that will perform the check

Once you've got your routes installed keep in mind that they will be processed in a hierarchical order, from the more specific to the more generic. Look at this example

```
api/v1/users/{id}/*
api/v1/users/{id}
api/v1/*
api/v1
api/*

```

This will result in the following behaviour

- if you request `foo/bar` route is not found hence access is allowed
- if you request `api/foo` permissions bound to the `api/*` pattern will be applied
- if you request `api/v1` permission bound to the `api/v1` pattern will be applied

and so on.

Middleware Response
---------------------------------------------------------------------------

[](#middleware-response-)

Both the middleware implementation will return `HTTP 401` on failure with an additional `X-Reason: permission` header that will come handy when dealing with responses on the client side (i.e. an angular interceptor).

If you want your error responses to be redirected when the Middleware check fails, just set the redirect path in your **wrappr.config**

```
'redirect' => '/login'
```

This value will be ignored when the http request is an ajax request.

How to develop providers
------------------------------------------------------------------------------

[](#how-to-develop-providers-)

Extend `Foothing\Wrappr\Providers\Permissions\AbstractProvider`.

You'll have the mandatory `check()` method to implement, and other optional methods you can implement or ignore at your choice.

```
/**
 * Check the given user has access to the given permission.
 *
 * @param      $user
 * @param      $permissions
 * @param null $resourceName
 * @param null $resourceId
 *
 * @return mixed
 */
public function check($user, $permissions, $resourceName = null, $resourceId = null);

/**
 * Check the given subject has access to the given permission.
 *
 * @param      $permissions
 * @param null $resourceName
 * @param null $resourceId
 *
 * @return mixed
 */
public function can($permissions, $resourceName = null, $resourceId = null);

/**
 * Fluent method to work on users.
 * @param $user
 * @return self
 */
public function user($user);

/**
 * Fluent method to work on roles.
 * @param $role
 * @return self
 */
public function role($role);

/**
 * Return all permissions for the given subject.
 * @return mixed
 */
public function all();

/**
 * Grant the given permissions to the given subject.
 *
 * @param      $permissions
 * @param null $resourceName
 * @param null $resourceId
 *
 * @return mixed
 */
public function grant($permissions, $resourceName = null, $resourceId = null);

/**
 * Revoke the given permissions from the given subject.
 *
 * @param      $permissions
 * @param null $resourceName
 * @param null $resourceId
 *
 * @return mixed
 */
public function revoke($permissions, $resourceName = null, $resourceId = null);
```

License
---------------------------------------------------

[](#license-)

[MIT](https://opensource.org/licenses/MIT)

###  Health Score

29

—

LowBetter than 60% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity16

Limited adoption so far

Community11

Small or concentrated contributor base

Maturity57

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 98.7% 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.

###  Release Activity

Cadence

Every ~34 days

Recently: every ~84 days

Total

19

Last Release

3241d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/9ebf3a4938226620036760ed05bf0d6801b7bc2c383a1fd7dd1a4c48ba84145d?d=identicon)[brazorf](/maintainers/brazorf)

---

Top Contributors

[![brazorf](https://avatars.githubusercontent.com/u/3330031?v=4)](https://github.com/brazorf "brazorf (75 commits)")[![crynobone](https://avatars.githubusercontent.com/u/172966?v=4)](https://github.com/crynobone "crynobone (1 commits)")

---

Tags

laravelroutespermissions

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/foothing-laravel-wrappr/health.svg)

```
[![Health](https://phpackages.com/badges/foothing-laravel-wrappr/health.svg)](https://phpackages.com/packages/foothing-laravel-wrappr)
```

###  Alternatives

[spatie/laravel-permission

Permission handling for Laravel 12 and up

12.9k89.8M1.0k](/packages/spatie-laravel-permission)[silber/bouncer

Eloquent roles and abilities.

3.6k4.4M25](/packages/silber-bouncer)[wnikk/laravel-access-rules

Simple system of ACR (access control rules) for Laravel, with roles, groups, unlimited inheritance and possibility of multiplayer use.

103.6k1](/packages/wnikk-laravel-access-rules)[hasinhayder/tyro

Tyro - The ultimate Authentication, Authorization, and Role &amp; Privilege Management solution for Laravel 12 &amp; 13

6712.1k2](/packages/hasinhayder-tyro)[beatswitch/lock-laravel

A Laravel Driver for Lock.

15529.1k1](/packages/beatswitch-lock-laravel)[pingpong/trusty

Roles and Permissions for Laravel 4

2680.0k9](/packages/pingpong-trusty)

PHPackages © 2026

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