├── .gitignore ├── .travis.yml ├── LICENSE.txt ├── README.md ├── composer.json ├── phpunit.xml ├── src ├── Volicon │ └── Acl │ │ ├── Acl.php │ │ ├── AclPermission.php │ │ ├── AclRole.php │ │ ├── AclRoute.php │ │ ├── AclServiceProvider.php │ │ ├── AclUser.php │ │ ├── Commands │ │ ├── InstallCommand.php │ │ └── UpdateCommand.php │ │ ├── Exceptions │ │ └── NoPermissionsException.php │ │ ├── Facades │ │ └── Acl.php │ │ ├── Models │ │ ├── AclModel.php │ │ ├── GroupResources.php │ │ ├── Role.php │ │ ├── RolePermission.php │ │ └── UserRole.php │ │ ├── RoleProviders │ │ ├── AclRoleProvider.php │ │ ├── AdminRoleProvider.php │ │ └── UsersRoleProvider.php │ │ └── Support │ │ ├── AclInterface.php │ │ ├── AclTrait.php │ │ ├── DataObject.php │ │ └── MicrotimeDate.php ├── config │ ├── .gitkeep │ ├── config.php │ └── testing │ │ └── config.php └── migrations │ ├── .gitkeep │ ├── 2013_10_03_110631_create_user_role_table.php │ ├── 2013_10_06_112820_create_role_permission_table.php │ ├── 2013_10_09_120304_create_roles_table.php │ └── 2014_07_27_084049_create_group_resources_table.php └── tests ├── .gitkeep └── TestCase.php /.gitignore: -------------------------------------------------------------------------------- 1 | /vendor 2 | composer.phar 3 | composer.lock 4 | .DS_Store -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: php 2 | 3 | php: 4 | - 5.3 5 | - 5.4 6 | - 5.5 7 | 8 | before_script: 9 | - curl -s http://getcomposer.org/installer | php 10 | - php composer.phar install --dev 11 | 12 | script: phpunit -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Volicon ACL (RBAC) 2 | =========== 3 | 4 | ACL - Access Control List. 5 | More precisely this is an RBAC - Role Based Access Control - package for Laravel 4. 6 | 7 | **Introduction:** 8 | 9 | This RBAC plug-in defines permissions for users through roles or set/check permissions to routes. 10 | Each role has an array of defined permissions. 11 | Each user is assigned 1 or more roles, the returned permission is a union of his assigned roles. 12 | 13 | Example of roles: admin, user, limited user, guest, etc. 14 | 15 | 16 | 1. [Installation](#installation) 17 | 2. [Configuration](#configuration) 18 | 3. [Hook callbacks](#hook) 19 | 4. [Routing](#routing) 20 | 5. [Api](#api) 21 | 6. [using with Models](#using-with-models) 22 | 7. [Examples](#examples) 23 | 24 | 25 | ##Installation 26 | 27 | To install this package use Composer. 28 | Edit your project's composer.json file 29 | 30 | ```php 31 | "require": { 32 | "volicon/laravel-acl-rbac": "dev-master", 33 | }, 34 | "minimum-stability": "dev" 35 | ``` 36 | 37 | Next, update Composer from Terminal: 38 | 39 | ```php 40 | composer update 41 | ``` 42 | 43 | Once this operation is complete, add the package into your app with the service provider. 44 | Open app/config/app.php, edit providers array. 45 | 46 | ```php 47 | 'providers' => array( 48 | 'Volicon\Acl\AclServiceProvider', 49 | ), 50 | ``` 51 | 52 | Recommended to add new alias into aliases array. 53 | 54 | ```php 55 | 'aliases' => array( 56 | 'Acl' => 'Volicon\Acl\Facades\Acl', 57 | 'AclUser' => 'Volicon\Acl\AclUser', 58 | 'AclRole' => 'Volicon\Acl\AclRole', 59 | ) 60 | ``` 61 | 62 | Last step is to install ACL. You can easy do this by running artisan command: 63 | 64 | ```php 65 | php artisan acl:install 66 | ``` 67 | this will create 4 new tables in your db. 68 | 69 | ##Configuration 70 | 71 | **group_resources**: 72 | you can put resources into a group for optimization. 73 | each resource in the group is referred to as a sub resource of the group. 74 | when checking permission of a sub resource, the group's permission will be returned. 75 | 76 | for the following example, any query of users.show or users.select will return the users.view permission. 77 | ```php 78 | 'group_resources' => 79 | 'users.view' => [ // group 80 | 'users.index', 81 | 'users.show', 82 | 'User.select', 83 | ], 84 | 'role.view' => [ // another group 85 | 'role.index', 86 | 'role.show', 87 | 'Role.select', 88 | ] 89 | ``` 90 | 91 | 92 | **allways_allow_resources**: 93 | any resource listed here will always return true without a database query for any logged in user. 94 | 95 | ```php 96 | 'allways_allow_resources' => [ 97 | 'local.viewCalendar' 98 | ] 99 | ``` 100 | 101 | **cache** 102 | its possible to use laravel's cache with Acl. 103 | set the prefix key for caching. 104 | 105 | ```php 106 | 'using_cache' => true 107 | 'cache_key' => '_volicon_acl_' 108 | ``` 109 | 110 | 111 | 112 | 113 | **roleProviders** 114 | Class which defines the permission behaviour for the role. 115 | For example AdminRoleProvider will not allow to add permissions to role and will always return permission true without querying the db. 116 | You can create a custom roleProviders which has a defined set of permissions or checks permission from a config file. 117 | The default UsersRoleProvider will return the role as is. 118 | 119 | The roleProviders Class controls add,remove and update of the role. 120 | For example: Limit users in a role. Security feature against: creating a new admin role, adding a user to admin, deleting admin role etc. 121 | 122 | you may add a custom roleProviders through extending the \Volicon\Acl\RoleProviders\AclRoleProvider Class and overriding the methods: addRole, removeRole, updateRole, getPermission etc. 123 | 124 | Role is assigned its roleProviders by role type. 125 | UsersRoleProvider and AdminRoleProvider role types are provided as default. 126 | 127 | ```php 128 | 'roleProviders' => [ 129 | 0 => '\Volicon\Acl\RoleProviders\UsersRoleProvider', 130 | 1 => '\Volicon\Acl\RoleProviders\AdminRoleProvider' 131 | ], 132 | ``` 133 | 134 | 135 | **Roles**: 136 | A model which holds a set of permissions. 137 | The model behaviour and control is defined by the roleProviders Class. 138 | The model holds an array of every user its assigned too. 139 | 140 | ```php 141 | role format: 142 | [ 'name' => 'role name', 143 | 'permissions' => array of permissions, //(optional, default defined by 'default_permission', unless permission is set by 'type') 144 | 'type' => 0, // (optional default 0) - roleProviders id, more on this later 145 | 'default' => 1 // (optional default 0), if => 1 can not remove this role. 146 | ] 147 | 148 | permissions format: 149 | [ "resource" => "permission name", 150 | "values" => [], // (optional), array of resources ids 151 | "allowed" => 1 // (optional, default set by 'default_permission' ) 152 | ] 153 | // "allowed": 1 means **incdule all**, 0 means **exclude all**. 154 | // "allowed" => 0 -- allow action **except** for resource with id in array, if 'values' array is empty dont allow. 155 | // "allowed" => 1 -- allow action **only** for resource with id in array, if 'values' array is empty allow action. 156 | ``` 157 | example: 158 | Here we will define a role for a group admin who can create, and edit users except for user with id === 1, however he cannot delete any users. 159 | 160 | ```php 161 | // Note: permission values may have been overridden in roleProviders. 162 | // for example if 'type' => 1, then role provider admin would override resource permissions limitation. 163 | 164 | 'roles' => [ 165 | [ 'name' => 'GroupAdmin', 166 | 'permissions' => [ 167 | ["resource" => "user.create", "values" => [] ,"allowed" => 1 ], 168 | ["resource" => "user.edit", "values" => [1] ,"allowed" => 0 ], 169 | ["resource" => "user.delete", "values" => [] ,"allowed" => 0 ], 170 | ], 171 | 'type' => 0, // value of roleProviders: 0 - user, 1 - Admin ( or custom if changed or added another roleProviders ). 172 | 'default' => 0 // (optional) if ( 'default' => 1 ) can not delete role. 173 | ], 174 | [ 175 | 'name' => 'Admin', 176 | 'type' => 1, // AdminRoleProvider 177 | 'default' => 1 // can not delete role. 178 | ] 179 | ] 180 | ``` 181 | 182 | **default_permission:** 183 | boolean behaviour unknown resource and values. 184 | ```php 185 | 'default_permission' => false 186 | ``` 187 | 188 | 189 | ##Hook 190 | Dynamically change permissions. 191 | **registerHook** -- you can attach a callback to resource which will return a dynamically calculated permission. 192 | callback function argument is Volicon\Acl\AclPermission. 193 | 194 | ```php 195 | Acl::registerHook('media.list', function($permission){ 196 | if(geoIp() !== 'Europe') { 197 | return new Volicon\Acl\AclPermission($permission->resource, [], false); // dont allow 198 | } 199 | 200 | return $permission; // else return defined role permission. 201 | }); 202 | 203 | Acl::registerHook('ufo.list', function($permission){ 204 | if(geoIp() === 'OuterSpace') { 205 | $permission->allow = true; // manually set a permission. 206 | $permission->values[] = Auth::getUser()->user_id; 207 | return $permission; 208 | }); 209 | 210 | ``` 211 | 212 | ##Routing: 213 | (optional) In order to check every network request add the following code. 214 | Dont forget to define the resource in the 'group_resources', and assign the permission in the role. 215 | 216 | in routes.php: 217 | ```php 218 | Route::group(array('before' => 'auth'), function() { 219 | Route::resource('users', 'UsersController'); 220 | Route::get('data', 'dataController@getData'); 221 | }); 222 | ``` 223 | 224 | Add filter in filters.php 225 | ```php 226 | Route::filter('auth', function() 227 | { 228 | if (Auth::guest()) { 229 | return Redirect::to('/login.html'); 230 | } 231 | try { 232 | \Volicon\Acl\AclRoute::validateRoute(); 233 | } catch (\Volicon\Acl\Exceptions\NoPermissionsException $ex) { 234 | return Response::make (json_encode($ex->getMessage()), 403); 235 | } 236 | }); 237 | ``` 238 | 239 | ##Api 240 | Boolean Acl::check($resource, array $ids = []); // [] is optional, ids of resource. 241 | //check() returns boolean, can perform the action of resource for all ids. 242 | //if check($resource) without [], returns true if $resource is not blocked. 243 | 244 | Array Acl::filter($resource, array $ids = []) // returns [] of authorized id from within the $ids []. 245 | Volicon\Acl\AclPermission Acl::getPermission($resource) // returns permission of resource. permission is an object with params: resource, values, and allow. 246 | 247 | void Acl::registerHook($resource, $callback) 248 | void Acl::reguard() // check permissions with acl. 249 | void Acl::unguard() // remove acl security check 250 | Boolean Acl::isGuard() 251 | Volicon\Acl\RoleProviders\AclRoleProvider Acl::getRoleProvider($role_type) // returns instants of 'role provider' 252 | array Acl::getRoleProvidersTypes() // array of ids 253 | Illuminate\Support\Collection Acl::getRoles($roleIds = []) // ($roleIds optional), returns all roles or roles for ids in array. 254 | Volicon\Acl\AclUser Acl::getAuthUser() // returns logged in user. 255 | 256 | ##AclUser 257 | * @property int user_id 258 | * @property int role_id 259 | * @property array roles // id of all roles assigned to this user. 260 | * @property array user_types 261 | AclUser AclUser::find(id) // returns a user. 262 | AclUser AclUser::findWithPermissions(id) // returns a user with an array of the users' permissions. 263 | void $aclUser->setRoles(array $ids = []) // sets 1 or more role to the user, previous roles will be removed. 264 | 265 | AclUser implements Acl method: check, filter, getPermission mentioned above. 266 | when going through AclUser permission does not go through hooks, therefore the returned db result may vary from reality. 267 | 268 | ##AclRole 269 | * @property int $role_id 270 | * @property string $name 271 | * @property int $type 272 | * @property bool $default prevent deleting the role or change its name 273 | * @property Collection $permissions 274 | * @property Collection $users users ID's 275 | 276 | **methods:** 277 | * $acRole->getPermission 278 | * $acRole->add() // add $acRole to databse. 279 | * $acRole->update() // save $acRole to databse. 280 | * $acRole->remove // delete $acRole from databse. 281 | 282 | #using with models 283 | Inheriting from Volicon\Acl\Models\AclModel will automatically check permissions. 284 | AclModel listens to laravel events and checks permission for add, delete, and update. For select event AclModel will add 'where' in query. 285 | 286 | 287 | 288 | Add role through api: 289 | #Examples: 290 | ```php 291 | //Example 1: 292 | $role = new AclRole(); 293 | $role->name = 'Users'; 294 | $role->permissions = [ 295 | [ 296 | 'resource' => 'products.view', 297 | 'values' => [], 298 | 'allow' => true 299 | ] 300 | ] 301 | $role->users = [1,2]; 302 | $role->add(); 303 | 304 | //Example 2: 305 | $role = new AclRole([ 306 | 'name' => 'product managers', 307 | 'permissions' => [ 308 | new AclPermission('products.manage',[],true) 309 | ] 310 | ]); 311 | $role->add(); 312 | 313 | $user = User::create(['username' => 'laravel', 'password' => 'strong']); 314 | $aclUser = new AclUser($user); 315 | $aclUser->setRoles(3); 316 | ``` 317 | 318 | AclModel example: 319 | 320 | ```php 321 | use Volicon\Acl\Models\AclMode as Eloquent; 322 | 323 | class Product extends Eloquent { 324 | protected $acl_field_key = 'product_id'; // if not defined use primary key 325 | 326 | } 327 | 328 | $products = Product::where('category', '=', 'good')->get(); //Acl add where depend of the permission of the resource Product.select 329 | ``` 330 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "volicon/laravel-acl-rbac", 3 | "description": "ACL / RBAC - package for Laravel 4. Can work with Models or routes", 4 | "authors": [ 5 | { 6 | "name": "Nadav Vinik", 7 | "email": "nadav.v@volicon.com" 8 | } 9 | ], 10 | "require": { 11 | "php": ">=5.4.0", 12 | "illuminate/support": "4.*" 13 | }, 14 | "require-dev": { 15 | "phpunit/phpunit": "3.7.*", 16 | "orchestra/testbench": "2.0.*", 17 | "mockery/mockery": "dev-master@dev" 18 | }, 19 | "autoload": { 20 | "classmap": [ 21 | "src/migrations" 22 | ], 23 | "psr-0": { 24 | "Volicon\\Acl\\": "src/" 25 | } 26 | }, 27 | "minimum-stability": "dev" 28 | } 29 | -------------------------------------------------------------------------------- /phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 13 | 14 | 15 | ./tests/ 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/Volicon/Acl/Acl.php: -------------------------------------------------------------------------------- 1 | group_resources = Config::get ( 'acl::config.group_resources' ); 35 | $this->allways_allow_resources = \Config::get ( 'acl::allways_allow_resources', [ ] ); 36 | 37 | $roleProviders = Config::get('acl::config.roleProviders'); 38 | 39 | foreach($roleProviders as $role_type => $roleProvider) { 40 | if(is_subclass_of($roleProvider, 'Volicon\Acl\RoleProviders\AclRoleProvider')) { 41 | $this->registerRoleProvider($role_type, new $roleProvider); 42 | } 43 | } 44 | 45 | if(Config::get('acl::using_cache', false)) { 46 | $this->use_cache = true; 47 | $this->cache_prefix = Config::get('acl::cache_key', $this->cache_prefix); 48 | } 49 | 50 | } 51 | 52 | public function registerRoleProvider($role_type, AclRoleProvider $roleProvider) { 53 | if (! is_int ( $role_type )) { 54 | throw new \Exception ( "role_type should be number $role_type given" ); 55 | } 56 | 57 | if (isset ( $this->registersRoleProviders [$role_type] )) { 58 | throw new \Exception ( "role_type $role_type already register" ); 59 | } 60 | 61 | $this->registersRoleProviders [$role_type] = $roleProvider; 62 | $roleProvider->setRoleType($role_type); 63 | $this->registersHooks[$role_type] = []; 64 | 65 | } 66 | 67 | public function registerHook($resource, $callback) { 68 | 69 | if(!is_array($resource)) { 70 | $resource = [$resource]; 71 | } 72 | 73 | foreach($resource as $res) { 74 | 75 | if(!isset($this->registersHooks[$res])) { 76 | $this->registersHooks[$res] = []; 77 | } 78 | 79 | $this->registersHooks[$res][] = $callback; 80 | } 81 | } 82 | 83 | public function getPermission($resource, array $ids = []) { 84 | 85 | if(! $this->_guard) { 86 | return new AclPermission($resource, $ids, true); 87 | } 88 | 89 | if(in_array($resource, Config::get('acl::allways_allow_resources'))) { 90 | return new AclPermission($resource, $ids, true); 91 | } 92 | 93 | $authUser = $this->getAuthUser(); 94 | if(!$authUser) { 95 | return new AclPermission($resource, [], false); 96 | } 97 | 98 | $groupResource = GroupResources::getResourceGroup($resource); 99 | if($groupResource) { 100 | $resource = $groupResource; 101 | } 102 | 103 | if(isset($authUser->permissions[$resource])) { 104 | $permission = $authUser->getPermission($resource, $ids); 105 | return $this->applyHook($permission, $ids); 106 | } 107 | 108 | $result = new AclPermission ( $resource ); 109 | foreach ( $authUser->user_types as $type ) { 110 | if (isset ( $this->registersRoleProviders [$type] )) { 111 | $permission = $this->registersRoleProviders [$type]->getPermission ( $resource, $ids ); 112 | $result = $result->mergePermission ( $permission ); 113 | } 114 | 115 | if($result->isAllowAll()) { 116 | break; 117 | } 118 | } 119 | 120 | return $this->applyHook($result, $ids); 121 | } 122 | 123 | public function reguard() { 124 | $this->_guard = true; 125 | } 126 | public function unguard() { 127 | $this->_guard = false; 128 | } 129 | 130 | public function isGuard() { 131 | return $this->_guard; 132 | } 133 | 134 | /** 135 | * run function without ACL restictions. 136 | * @param Closure $closure 137 | * @return mix closure result 138 | */ 139 | public function runUnguardCallback(Closure $closure) { 140 | $isGuard = $this->isGuard(); 141 | $this->unguard(); 142 | $result = $closure(); 143 | if($isGuard) { 144 | $this->reguard(); 145 | } 146 | return $result; 147 | } 148 | 149 | public function getRoleProvider($role_type) { 150 | return $this->registersRoleProviders[$role_type]; 151 | } 152 | 153 | public function getRoleProvidersTypes() { 154 | return array_keys($this->registersRoleProviders); 155 | } 156 | 157 | public function getRoles($roleIds = []) { 158 | $result = new Collection(); 159 | 160 | /* @var $role_provider \Volicon\Acl\RoleProviders\AclRoleProvider */ 161 | foreach($this->registersRoleProviders as $role_provider) { 162 | $roles = $role_provider->getRoles($roleIds); 163 | $result = $result->merge($roles); 164 | } 165 | 166 | return $result; 167 | } 168 | 169 | public function getAuthUser() { 170 | $auth_user = NULL; 171 | if(!Auth::id()) { 172 | return $auth_user; 173 | } 174 | 175 | if($this->use_cache) { 176 | $auth_user_cached_time = Cache::get($this->cache_prefix.'_mt_authUser_'.Auth::id(), null); 177 | $role_mt = Cache::get($this->cache_prefix.'_last_role_update', null); 178 | if($auth_user_cached_time && $role_mt && $role_mt->compare($auth_user_cached_time)) { 179 | $auth_user = Cache::get($this->cache_prefix.'_authUser_'.Auth::id()); 180 | } 181 | } 182 | 183 | if(!$auth_user) { 184 | $auth_user = AclUser::findWithPermissions(Auth::id()); 185 | if($this->use_cache) { 186 | Cache::forever($this->cache_prefix.'_authUser_'.Auth::id(), $auth_user); 187 | Cache::forever($this->cache_prefix.'_mt_authUser_'.Auth::id(), new MicrotimeDate()); 188 | } 189 | } 190 | 191 | return $auth_user; 192 | } 193 | 194 | public function applyHook(AclPermission $permission, $ids=[], $acl = null) { 195 | 196 | if(!isset($this->registersHooks[$permission->resource])) { 197 | return $permission; 198 | } 199 | 200 | if(!$acl) { 201 | $acl = $this; 202 | } 203 | 204 | if(!in_array('Volicon\Acl\Support\AclTrait', class_uses($acl))) { 205 | throw new \InvalidArgumentException("Argument 3 passed to Volicon\Acl\Acl::applyHook() must be use AclTrait"); 206 | } 207 | 208 | foreach ($this->registersHooks[$permission->resource] as $callback) { 209 | $handler_result = $callback($permission, $ids, $acl); 210 | if($handler_result instanceof AclPermission) { 211 | $permission = $permission->mergePermission($handler_result); 212 | } 213 | } 214 | 215 | return $permission; 216 | } 217 | 218 | } 219 | -------------------------------------------------------------------------------- /src/Volicon/Acl/AclPermission.php: -------------------------------------------------------------------------------- 1 | resource) || isset($resource->permission_id))) { 31 | throw new InvalidArgumentException('permission must include resource'); 32 | } 33 | 34 | if(!isset($resource->resource)) { 35 | $group_resources = GroupResources::getGroupResources(); 36 | 37 | if(!isset($group_resources[$resource->permission_id])) { 38 | throw new InvalidArgumentException('permission id do not have resource: '.$resource->permission_id); 39 | } 40 | 41 | $data['resource'] = $group_resources[$resource->permission_id]; 42 | } else { 43 | $data['resource'] = $resource->resource; 44 | } 45 | 46 | if(isset($resource->values)) { 47 | if(is_array($resource->values)) { 48 | $data['values'] = $resource->values; 49 | } else if(is_string($resource->values)) { 50 | $data['values'] = json_decode($resource->values); 51 | } 52 | } 53 | 54 | $data['allowed'] = !isset($resource->allowed) || is_null ( $resource->allowed ) ? $default_permission : (bool)$resource->allowed; 55 | } else { 56 | 57 | $data['resource'] = $resource; 58 | $data['values'] = $values; 59 | 60 | 61 | $data['allowed'] = is_null ( $allowed ) || ! is_bool ( $allowed ) ? $default_permission : $allowed; 62 | } 63 | 64 | parent::__construct($data); 65 | } 66 | public function mergePermission(AclPermission $permission) { 67 | 68 | if($permission->resource !== $this->resource) { 69 | throw new \Exception('Resouce not match'); 70 | } 71 | 72 | if (($this->allowed && $permission->allowed) || ($this->allowed && ! $this->values) || ($permission->allowed && ! $permission->values)) { 73 | if (! $this->values || ! $permission->values) { 74 | return new self($this->resource, [], true); 75 | } else { 76 | $ids = array_merge ( $this->values, $permission->values); 77 | return new self($this->resource, $ids, true); 78 | } 79 | } 80 | 81 | $p1 = $permission->allowed ? $permission : $this; 82 | $p2 = $permission->allowed ? $this : $permission; 83 | 84 | if ($p1->allowed) { 85 | if (! $p2->values) { 86 | return clone $p1; 87 | } 88 | 89 | $values = array_diff ( $p2->values, $p1->values ); 90 | 91 | //check if there are same values but one permission allow but other not 92 | if(!$values && $p2->values) { 93 | return new self($p1->resource, $values, true); 94 | } 95 | 96 | return new self($p1->resource, $values, false); 97 | } 98 | 99 | // both not allow 100 | if (! $p1->values && ! $p2->values) { 101 | return clone $p1; 102 | } 103 | 104 | if ($p1->values && $p2->values) { 105 | $values = array_intersect ( $p1->values, $p2->values ); 106 | return new self($p1->resource, $values, false); 107 | } 108 | 109 | if ($p1->values) { 110 | return clone $p1; 111 | } 112 | 113 | if ($p2->values) { 114 | return clone $p2; 115 | } 116 | 117 | return new self($this->resource); 118 | 119 | } 120 | 121 | /* 122 | * create new Permission base on this permission filter by $ids 123 | */ 124 | public function newSubPermission(array $ids = []) { 125 | $result = clone $this; 126 | 127 | if(!$this->allowed && !$this->values) { 128 | return $result; 129 | } 130 | 131 | if(!$ids || $this->isAllowAll()) { 132 | $result->values = $ids; 133 | return $result; 134 | } 135 | 136 | if($this->allowed) { 137 | $result->values = array_intersect($result->values, $ids); 138 | } else { 139 | $values = array_diff($ids, $this->values); 140 | if($values) { 141 | $result->allowed = true; 142 | $result->values = $values; 143 | } else { 144 | $result->values = []; 145 | } 146 | } 147 | 148 | return $result; 149 | 150 | } 151 | 152 | public function isAllowAll() { 153 | return $this->allowed && !$this->values; 154 | } 155 | 156 | public function offsetUnset($offset) { 157 | throw new \Exception(); 158 | } 159 | 160 | } 161 | -------------------------------------------------------------------------------- /src/Volicon/Acl/AclRole.php: -------------------------------------------------------------------------------- 1 | attributes['permissions'] = new Collection(); 27 | $this->attributes['users'] = new Collection(); 28 | 29 | if($role instanceof \Volicon\Acl\Models\Role) { 30 | $this->attributes['role_id'] = $role->role_id; 31 | $this->attributes['name'] = $role->name; 32 | $this->attributes['type'] = $role->type; 33 | $this->attributes['default'] = $role->default; 34 | 35 | if(isset($role->permissions)) { 36 | $this->attributes['permissions'] = $this->_aclPermissions($role->permissions); 37 | } 38 | 39 | if(isset($role->users)) { 40 | $this->attributes['users'] = $this->_aclUsers($role->users); 41 | } 42 | } else if(is_array($role)) { 43 | $default = isset($role['default']) ? (bool)$role['default'] : FALSE; 44 | $this->attributes['default'] = $default; 45 | unset($role['default']); 46 | 47 | if(isset($role['permissions'])) { 48 | $this->attributes['permissions'] = $this->_aclPermissions($role['permissions']); 49 | 50 | unset($role['permissions']); 51 | } 52 | 53 | if(isset($role['users'])) { 54 | $this->attributes['users'] = $this->_aclUsers($role['users']); 55 | unset($role['users']); 56 | } 57 | 58 | foreach ($role as $key=>$value) { 59 | $this->attributes[$key] = $value; 60 | } 61 | } 62 | } 63 | 64 | public function getPermission($resource, $ids=[]) { 65 | 66 | $permissions = $this->permissions->keyBy('resource'); 67 | 68 | $result = isset($permissions[$resource]) ? $permissions[$resource] : new AclPermission($resource); 69 | if($ids) { 70 | $result = $result->newSubPermission($ids); 71 | } 72 | } 73 | 74 | public function add() { 75 | /* @var $role_provider RoleProviders\AclRoleProvider */ 76 | $role_provider = AclFacade::getRoleProvider($this->attributes['type']); 77 | $result = $role_provider->addRole($this); 78 | if($result) { 79 | Event::fire('acl_role_added', array($result)); 80 | } 81 | return $result; 82 | } 83 | 84 | public function update() { 85 | /* @var $role_provider RoleProviders\AclRoleProvider */ 86 | $role_provider = AclFacade::getRoleProvider($this->attributes['type']); 87 | $result = $role_provider->updateRole($this); 88 | if($result) { 89 | Event::fire('acl_role_updated', array($result)); 90 | } 91 | return $result; 92 | } 93 | 94 | public function remove() { 95 | 96 | if($this->attributes['default']) { 97 | throw new NoPermissionsException("You cannot remove default role."); 98 | } 99 | 100 | if(!isset($this->attributes['role_id']) || !$this->attributes['role_id']) { 101 | throw new NoPermissionsException("missing role_id"); 102 | } 103 | 104 | /* @var $role_provider RoleProviders\AclRoleProvider */ 105 | $role_provider = AclFacade::getRoleProvider($this->attributes['type']); 106 | $result = $role_provider->removeRole($this->attributes['role_id']); 107 | if($result) { 108 | Event::fire('acl_role_removed', array($result)); 109 | } 110 | return $result; 111 | } 112 | 113 | public function offsetSet($offset, $value) { 114 | 115 | if($offset === 'default') { 116 | throw new NoPermissionsException("You cannot change default field."); 117 | } 118 | 119 | if($offset === 'type' && isset($this->attributes['type'])) { 120 | throw new NoPermissionsException("You cannot change type after it set."); 121 | } 122 | 123 | if(isset($this->attributes['role_id']) && $offset == $this->attributes['role_id'] && $value !== $this->attributes['role_id']) { 124 | throw new NoPermissionsException("You cannot change id of role."); 125 | } 126 | 127 | if($this->attributes['default'] && $offset === 'name') { 128 | throw new NoPermissionsException("You cannot change default role name."); 129 | } 130 | 131 | if($offset === 'permissions') { 132 | 133 | $this->attributes['permissions'] = $this->_aclPermissions($value); 134 | 135 | } else if($offset === 'users') { 136 | 137 | $this->attributes['users'] = $this->_aclUsers($value); 138 | 139 | } else { 140 | parent::offsetSet($offset, $value); 141 | } 142 | 143 | } 144 | 145 | public function offsetUnset($offset) { 146 | 147 | if(in_array($offset, ['role_id', 'name', 'type', 'default', 'permissions', 'users'])) { 148 | throw new NoPermissionsException("No permission to unset: ".$offset); 149 | } 150 | 151 | parent::offsetUnset($offset); 152 | 153 | } 154 | 155 | protected function _aclPermissions($permissions) { 156 | 157 | $result = new Collection(); 158 | 159 | foreach($permissions as $perm) { 160 | if($perm instanceof AclPermission) { 161 | $result[] = $perm; 162 | } else { 163 | $result[] = new AclPermission($perm); 164 | } 165 | } 166 | 167 | return $result; 168 | } 169 | 170 | protected function _aclUsers($users) { 171 | $result = new Collection(); 172 | 173 | $user_key = (new User)->getKeyName(); 174 | 175 | foreach($users as $user) { 176 | if(is_numeric($user)) { 177 | $result[] = (int)$user; 178 | } else if(is_array($user)) { 179 | if(isset($user[$user_key])) { 180 | $result[] = (int)$user[$user_key]; 181 | } 182 | } else if(is_object($user)) { 183 | $result[] = (int)$user->$user_key; 184 | } 185 | } 186 | 187 | return $result; 188 | } 189 | 190 | } 191 | -------------------------------------------------------------------------------- /src/Volicon/Acl/AclRoute.php: -------------------------------------------------------------------------------- 1 | getName(); 18 | if(!$route_name) { 19 | $route_name = $route->getActionName(); 20 | } 21 | 22 | $params = $route->parametersWithoutNulls(); 23 | 24 | $ids = []; 25 | 26 | if($params) { 27 | $param = current($params); 28 | if(is_numeric($param)) { 29 | $ids[] = $param; 30 | } 31 | } 32 | 33 | $result = AclFacade::check($route_name, $ids); 34 | 35 | if(!$result) { 36 | $error_message = "No Permission for $route_name"; 37 | 38 | if($ids) { 39 | $error_message .= " for id: {$ids[0]}"; 40 | } 41 | 42 | throw new NoPermissionsException($error_message); 43 | } 44 | 45 | return $result; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/Volicon/Acl/AclServiceProvider.php: -------------------------------------------------------------------------------- 1 | package('volicon/acl'); 22 | 23 | $this->app->bind('Acl', function() { 24 | return new Acl(); 25 | }); 26 | } 27 | /** 28 | * Register the service provider. 29 | * 30 | * @return void 31 | */ 32 | public function register() 33 | { 34 | $this->app['acl_install_command'] = $this->app->share(function($app) 35 | { 36 | return new Commands\InstallCommand; 37 | }); 38 | 39 | $this->app['acl_update_command'] = $this->app->share(function($app) 40 | { 41 | return new Commands\UpdateCommand; 42 | }); 43 | $this->commands('acl_install_command'); 44 | $this->commands('acl_update_command'); 45 | } 46 | 47 | /** 48 | * Get the services provided by the provider. 49 | * 50 | * @return array 51 | */ 52 | public function provides() 53 | { 54 | return array(); 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /src/Volicon/Acl/AclUser.php: -------------------------------------------------------------------------------- 1 | toArray()); 37 | } else { 38 | throw new InvalidArgumentException("argument should be array or User"); 39 | } 40 | 41 | if(!isset($this->roles)) { 42 | $this->roles = UserRole::where('user_id', '=', $this->getKey())->get(['role_id'])->lists('role_id'); 43 | $this->user_types = AclFacade::getRoles($this->roles)->lists('type'); 44 | } 45 | 46 | if(!isset($this->user_types)) { 47 | $this->user_types = count($this->roles) ? AclFacade::getRoles($this->roles)->lists('type') : []; 48 | } 49 | } 50 | 51 | public static function find($user_id) { 52 | $user = User::find($user_id); 53 | 54 | if(!$user) { 55 | return NULL; 56 | } 57 | 58 | return new static($user); 59 | } 60 | 61 | public static function findWithPermissions($user_id) { 62 | $user = static::find($user_id); 63 | 64 | if(!$user) { 65 | return $user; 66 | } 67 | 68 | $user_types = []; 69 | $permissions = []; 70 | 71 | $roles = $user->roles ? AclFacade::getRoles($user->roles) : []; 72 | 73 | foreach($roles as $role) { 74 | if(!in_array($role->type, $user_types)) { 75 | $user_types[] = $role->type; 76 | } 77 | 78 | /* @var $perm \Volicon\Acl\AclPermission */ 79 | foreach($role->permissions as $perm) { 80 | if(!isset($permissions[$perm->resource])) { 81 | $permissions[$perm->resource] = $perm; 82 | } else { 83 | $permissions[$perm->resource] = $permissions[$perm->resource]->mergePermission($perm); 84 | } 85 | } 86 | 87 | } 88 | 89 | $user->user_types = $user_types; 90 | $user->permissions = new Collection($permissions); 91 | 92 | return $user; 93 | 94 | } 95 | 96 | /** 97 | * search and paginate users 98 | * 99 | */ 100 | public static function search() { 101 | $result = new Collection(); 102 | $key_name = static::getKeyName(); 103 | $users = User::all()->toArray(); 104 | $usersRoles = UserRole::all(['user_id', 'role_id'])->groupBy('user_id'); 105 | foreach($users as &$user) { 106 | $user['roles'] = isset($usersRoles[$user[$key_name]]) ? array_pluck($usersRoles[$user[$key_name]], 'role_id') : []; 107 | $result[] = new static($user); 108 | } 109 | 110 | return $result; 111 | } 112 | 113 | public function setRoles(array $roleIds) { 114 | DB::beginTransaction(); 115 | 116 | $new_roles = array_diff($roleIds, $this->roles); 117 | $exist_roles = array_intersect($roleIds, $this->roles); 118 | $deleted_roles = array_diff($this->roles, $roleIds); 119 | $new_role_saved = []; 120 | $roleProviders = AclFacade::getRoleProvidersTypes(); 121 | foreach($roleProviders as $rp_type) { 122 | $rp = AclFacade::getRoleProvider($rp_type); 123 | if($rp->allowUpdateRole()) { 124 | $roles_to_delete = $deleted_roles ? $rp->getRoles($deleted_roles)->lists('role_id') : []; 125 | if ($roles_to_delete) { 126 | UserRole::where('user_id', '=', $this->getKey())->whereIn('role_id', $roles_to_delete)->delete(); 127 | } 128 | $roles = $new_roles ? $rp->getRoles($new_roles) : []; 129 | foreach($roles as $role) { 130 | $role_id = $role->role_id; 131 | UserRole::create([ 132 | 'user_id' => $this->user_id, 133 | 'role_id' => $role_id 134 | ]); 135 | $new_role_saved[] = $role_id; 136 | } 137 | } 138 | } 139 | 140 | DB::commit(); 141 | $this->roles = array_merge($exist_roles, $new_role_saved); 142 | Event::fire('acl_role_updated', array($roleIds)); 143 | $cache_prefix = Config::get('acl::cache_key', '_volicon_acl_'); 144 | Cache::forever($cache_prefix.'_last_role_update', new MicrotimeDate()); 145 | } 146 | 147 | public function getPermission($resource, array $ids = []) { 148 | 149 | if(in_array($resource, Config::get('acl::allways_allow_resources'))) { 150 | return new AclPermission($resource, $ids, true); 151 | } 152 | 153 | $groupResource = GroupResources::getResourceGroup($resource); 154 | if($groupResource) { 155 | $resource = $groupResource; 156 | } 157 | 158 | $result = new AclPermission($resource); 159 | 160 | if($ids) { 161 | $result = $result->newSubPermission($ids); 162 | } 163 | 164 | $result = AclFacade::applyHook($result, $ids, $this); 165 | 166 | $aclUser = $this; 167 | if(!isset($this->permissions)) { 168 | $aclUser = self::findWithPermissions($this->getKey()); 169 | } 170 | 171 | if(isset($aclUser->permissions[$resource])) { 172 | $result = $aclUser->permissions[$resource]; 173 | if($ids) { 174 | $result = $result->newSubPermission($ids); 175 | } 176 | } 177 | return $result; 178 | } 179 | 180 | public function getKey() { 181 | return isset($this[$this->getKeyName()]) ? $this[$this->getKeyName()] : FALSE; 182 | } 183 | 184 | public static function getKeyName() { 185 | if(!self::$__user_key) { 186 | self::$__user_key = (new User)->getKeyName(); 187 | } 188 | 189 | return self::$__user_key; 190 | } 191 | 192 | } 193 | -------------------------------------------------------------------------------- /src/Volicon/Acl/Commands/InstallCommand.php: -------------------------------------------------------------------------------- 1 | call('config:publish', array('--path' => $path, 'package' => 'volicon/acl')); 25 | 26 | $this->call('migrate', array('--package' => 'volicon/'.$package_name)); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/Volicon/Acl/Commands/UpdateCommand.php: -------------------------------------------------------------------------------- 1 | option ( 'update-roles' ); 17 | 18 | $role_permissions = Config::get ( "acl::config.roles" ); 19 | $group_resources = Config::get ( "acl::config.group_resources" ); 20 | 21 | $db_group_resources = GroupResources::all (); 22 | $db_role_permissions = RolePermission::all (); 23 | 24 | if (! $db_role_permissions->count ()) { 25 | $updateRolesOpt = true; 26 | } 27 | 28 | $group_resources_map = array (); 29 | foreach ( $db_group_resources as $row ) { 30 | $group_resources_map [$row->resource] = $row->permission_id; 31 | } 32 | 33 | $this->updateResorces ( $group_resources_map, $group_resources ); 34 | 35 | $this->updateRolesResources (); 36 | 37 | if ($updateRolesOpt && count ( $role_permissions )) { 38 | 39 | // if there new roles add them, don't delete not list role 40 | $roles = Acl::getRoles(); 41 | $rolesMap = array (); 42 | foreach ( $roles as $row ) { 43 | $rolesMap [$row->name] = $row->role_id; 44 | } 45 | 46 | Acl::runUnguardCallback(function() use ($role_permissions, $rolesMap) { 47 | foreach ( $role_permissions as $role ) { 48 | 49 | $aclRole = new AclRole($role); 50 | $role_name = $role ['name']; 51 | 52 | if (isset ( $rolesMap [$role_name] )) { 53 | $role['role_id'] = $rolesMap [$role_name]; 54 | $aclRole = new AclRole($role); 55 | $aclRole->update(); 56 | } else { 57 | $aclRole = new AclRole($role); 58 | $aclRole->add(); 59 | } 60 | } 61 | }); 62 | 63 | $roles_ids = array_values ( $rolesMap ); 64 | 65 | if (count ( $roles_ids )) { 66 | UserRole::whereNotIn ( 'role_id', $roles_ids )->delete (); 67 | } 68 | } 69 | } 70 | 71 | /** 72 | * Get the console command options. 73 | * 74 | * @return array 75 | */ 76 | protected function getOptions() { 77 | return array ( 78 | array ( 79 | 'update-roles', 80 | null, 81 | InputOption::VALUE_NONE, 82 | "Update roles permissions." 83 | ) 84 | ); 85 | } 86 | protected function updateResorces(&$db_resources_map, &$config_resources) { 87 | $db_resources = array_keys ( $db_resources_map ); 88 | $config_resources = array_keys ( $config_resources ); 89 | 90 | // delete group resources that are not in config 91 | $not_in_config_resources = array_diff ( $db_resources, $config_resources ); 92 | if (count ( $not_in_config_resources )) { 93 | GroupResources::whereIn ( 'resource', $not_in_config_resources )->delete (); 94 | } 95 | 96 | // delete role permissions then are not in config 97 | $deleted_permission_ids = array (); 98 | foreach ( $not_in_config_resources as $deleted_resource ) { 99 | $deleted_permission_ids [] = $db_resources_map [$deleted_resource]; 100 | } 101 | 102 | if (count ( $deleted_permission_ids )) { 103 | RolePermission::whereIn ( 'permission_id', $deleted_permission_ids )->delete (); 104 | } 105 | 106 | // add the new resources 107 | $new_resources = array_diff ( $config_resources, $db_resources ); 108 | \Eloquent::unguard (); 109 | foreach ( $new_resources as $resource ) { 110 | GroupResources::create ( array ( 111 | 'resource' => $resource 112 | ) ); 113 | } 114 | \Eloquent::reguard (); 115 | GroupResources::refreshGroupResources(); 116 | } 117 | public function updateRolesResources() { 118 | $roles = Acl::getRoles (); 119 | \Eloquent::unguard (); 120 | Acl::runUnguardCallback(function() use ($roles) { 121 | /* @var $role \Volicon\Acl\AclRole */ 122 | foreach ( $roles as $role ) { 123 | $role->update(); 124 | } 125 | }); 126 | \Eloquent::reguard (); 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /src/Volicon/Acl/Exceptions/NoPermissionsException.php: -------------------------------------------------------------------------------- 1 | acl_field_key && $this->getKeyName ()) { 21 | $this->acl_field_key = $this->getKeyName (); 22 | } 23 | } 24 | 25 | public function newQuery() { 26 | $builder = parent::newQuery (); 27 | 28 | if (!Acl::isGuard()) { 29 | return $builder; 30 | } 31 | 32 | $ok = $this->applyPermissionsRules ( $builder ); 33 | 34 | return $ok !== false ? $builder : $builder->whereRaw ( '1 = 0' ); 35 | } 36 | protected static function boot() { 37 | parent::boot (); 38 | 39 | self::_registerCreatingPermissions (); 40 | self::_registerUpdatingPermissions (); 41 | self::_registerDeletingPermissions (); 42 | } 43 | protected function applyPermissionsRules($builder) { 44 | $class = get_class ( $this ); 45 | 46 | if ($class == 'User') { // bug to fix, use to login 47 | return; 48 | } 49 | 50 | $permission = Acl::getPermission ( $class . '.select' ); 51 | 52 | return $this->wherePermission ( $builder, $permission ); 53 | } 54 | 55 | /** 56 | * 57 | * @param \Illuminate\Database\Eloquent\Builder $builder 58 | * @param AclPermission $permission 59 | * @param string $field 60 | * @return \Illuminate\Database\Eloquent\Builder 61 | */ 62 | public function wherePermission($builder, AclPermission $permission, $field = null) { 63 | if (! $field) { 64 | $field = $this->getAclKey (); 65 | } 66 | 67 | if ($permission->allowed && ! $permission->values) { 68 | return $builder; 69 | } 70 | 71 | if ($permission->allowed) { 72 | $builder->whereIn ( $this->getTable() . '.' . $field, $permission->values ); 73 | return $builder; 74 | } 75 | 76 | if ($permission->values) { 77 | $builder->whereNotIn ( $this->getTable() . '.' . $field, $permission->values ); 78 | return $builder; 79 | } 80 | 81 | throw new NoPermissionsException ( "No perrmision to " . $permission->resource ); 82 | 83 | // return $builder->whereRaw('1 = 0'); 84 | } 85 | protected function getAclKey() { 86 | return $this->acl_field_key; 87 | } 88 | protected static function checkCreatingPermissions($model) { 89 | } 90 | protected static function checkUpdatingPermissions($model) { 91 | } 92 | protected static function checkDeletingPermissions($model) { 93 | } 94 | 95 | private static function _registerCreatingPermissions() { 96 | static::creating ( function ($model) { 97 | if (Acl::isGuard()) { 98 | $class = get_class ( $model ); 99 | $result = Acl::check ( $class . '.insert' ); 100 | if (! $result) { 101 | throw new NoPermissionsException ( "No Permission to create $class" ); 102 | } 103 | return $result; 104 | } 105 | } ); 106 | static::creating ( function ($model) { 107 | if (Acl::isGuard()) { 108 | $result = $this->checkCreatingPermissions ( $model ); 109 | if (! $result) { 110 | throw new NoPermissionsException ( "No Permission to create $class" ); 111 | } 112 | return $result; 113 | } 114 | } ); 115 | } 116 | private static function _registerUpdatingPermissions() { 117 | static::updating ( function ($model) { 118 | if (Acl::isGuard()) { 119 | $class = get_class ( $model ); 120 | $id = $model [$model->getAclKey ()]; 121 | $result = Acl::check ( $class . '.update', [ 122 | $id 123 | ] ); 124 | if (! $result) { 125 | throw new NoPermissionsException ( "No Permission to update $class id:" . $id ); 126 | } 127 | return $result; 128 | } 129 | } ); 130 | static::updating ( function ($model) { 131 | if (Acl::isGuard()) { 132 | $result = $this->checkCreatingPermissions ( $model ); 133 | if (! $result) { 134 | throw new NoPermissionsException ( "No Permission to update $class id:" . $id ); 135 | } 136 | return $result; 137 | } 138 | } ); 139 | } 140 | private static function _registerDeletingPermissions() { 141 | static::deleting ( function ($model) { 142 | if (Acl::isGuard()) { 143 | $class = get_class ( $model ); 144 | $id = $model [$model->getAclKey ()]; 145 | $result = Acl::check ( $class . '.delete', [ 146 | $id 147 | ] ); 148 | if (! $result) { 149 | throw new NoPermissionsException ( "No Permission to delete $class id:" . $id ); 150 | } 151 | return $result; 152 | } 153 | } ); 154 | static::deleting ( function ($model) { 155 | if (Acl::isGuard()) { 156 | $result = $this->checkDeletingPermissions ( $model ); 157 | if (! $result) { 158 | $id = $model [$model->getAclKey ()]; 159 | throw new NoPermissionsException ( "No Permission to delete $class id:" . $id ); 160 | } 161 | return $result; 162 | } 163 | } ); 164 | } 165 | } 166 | -------------------------------------------------------------------------------- /src/Volicon/Acl/Models/GroupResources.php: -------------------------------------------------------------------------------- 1 | permission_id] = $row->resource; 26 | } 27 | } 28 | 29 | return new Collection(self::$group_resources); 30 | } 31 | 32 | public static function refreshGroupResources() { 33 | /** 34 | * TODO: use events instead this method 35 | */ 36 | self::$group_resources = []; 37 | static::getGroupResources(); 38 | } 39 | 40 | public static function getDependentGroupsResources() { 41 | $config_group_resources = Config::get('acl::config.group_resources'); 42 | $result = []; 43 | 44 | $func_data = function(&$data) { 45 | if(!isset ( $data ['@options'] )) { 46 | $data ['@options'] = []; 47 | } 48 | 49 | if(!isset ( $data ['@options']['depend'] )) { 50 | $data ['@options']['depend'] = []; 51 | } 52 | 53 | if(!isset ( $data ['@options']['sub_resource'] )) { 54 | $data ['@options']['sub_resource'] = false; 55 | } 56 | }; 57 | 58 | foreach($config_group_resources as $group=>$data) { 59 | $func_data($data); 60 | if(!$data['@options']['sub_resource']) { 61 | $result[$group] = []; 62 | self::_build_dependent_group_resources($result[$group], $group); 63 | } 64 | } 65 | 66 | return $result; 67 | } 68 | 69 | public static function getResourceGroup($resource) { 70 | if(in_array($resource, self::$group_resources)) { 71 | return $resource; 72 | } 73 | 74 | self::_fillResourcesInGroups(); 75 | return isset(self::$resources_in_groups[$resource]) ? self::$resources_in_groups[$resource] : FALSE; 76 | } 77 | 78 | 79 | private static function _fillResourcesInGroups() { 80 | 81 | if(self::$resources_in_groups) { 82 | return; 83 | } 84 | 85 | $config_group_resources = Config::get('acl::config.group_resources'); 86 | 87 | foreach($config_group_resources as $group=>&$resources) { 88 | foreach($resources as $resource) { 89 | if(is_array($resource)) { 90 | continue; 91 | } 92 | self::$resources_in_groups[$resource] = $group; 93 | } 94 | } 95 | } 96 | 97 | private static function _get_config_group ($resource) { 98 | $group_resources = Config::get('acl::config.group_resources'); 99 | $data = $group_resources[$resource]; 100 | 101 | if(!is_array($data)) { 102 | return NULL; 103 | } 104 | 105 | if(!isset ( $data ['@options'] )) { 106 | $data ['@options'] = []; 107 | } 108 | 109 | if(!isset ( $data ['@options']['depend'] )) { 110 | $data ['@options']['depend'] = []; 111 | } 112 | 113 | if(!isset ( $data ['@options']['sub_resource'] )) { 114 | $data ['@options']['sub_resource'] = false; 115 | } 116 | 117 | return $data; 118 | } 119 | 120 | private static function _build_dependent_group_resources(&$result, $resource) { 121 | $config_group = self::_get_config_group($resource); 122 | $sub_resources = $config_group['@options']['depend']; 123 | foreach($sub_resources as $sub_resource) { 124 | $result[] = $sub_resource; 125 | self::_build_dependent_group_resources($result, $sub_resource); 126 | } 127 | } 128 | 129 | } 130 | -------------------------------------------------------------------------------- /src/Volicon/Acl/Models/Role.php: -------------------------------------------------------------------------------- 1 | HasMany ( 'Volicon\Acl\Models\UserRole', 'role_id' ); 41 | } 42 | 43 | public function permissions() { 44 | return $this->hasMany ( 'Volicon\Acl\Models\RolePermission', 'role_id' ); 45 | } 46 | 47 | public static function getRoles(array $roleIds = [], $types = [], $resources = []) { 48 | 49 | if(self::$use_cache) { 50 | $roles = Cache::rememberForever(self::$cache_key, function() { 51 | $roles = static::with('users','permissions')->get(); 52 | $result = new Collection(); 53 | 54 | foreach($roles as $role) { 55 | $result[] = new AclRole($role); 56 | } 57 | $cache_prefix = Config::get('acl::cache_key', '_volicon_acl_'); 58 | Cache::forever($cache_prefix.'_last_role_update', new MicrotimeDate()); 59 | 60 | return $result; 61 | }); 62 | /* @var $roles \Illuminate\Support\Collection */ 63 | $need_filter = count($roles) || count($types) || count($resources); 64 | $roles = !$need_filter ? $roles : $roles->filter( 65 | function($role) use ($roleIds, $types, $resources) { 66 | return !( 67 | ($roleIds && !in_array($role->role_id, $roleIds)) || 68 | ($types && !in_array($role->type, $types)) || 69 | ($resources && !array_intersect($role->permissions->lists('resource'), $resources)) 70 | ) ; 71 | 72 | } 73 | ); 74 | 75 | return $roles; 76 | } 77 | 78 | $roles = static::with('users'); 79 | 80 | $roles->with(['permissions' => function($query) use ($resources) { 81 | 82 | if(!$resources) { 83 | return; 84 | } 85 | 86 | $groupResources = GroupResources::getGroupResources(); 87 | $resourcesIds = []; 88 | foreach($resources as $resource) { 89 | 90 | $resourcesIds[] = $groupResources->search($resource);; 91 | } 92 | 93 | $query->whereIn('permission_id', $resourcesIds); 94 | 95 | }]); 96 | 97 | if($types) { 98 | $roles->whereIn('type', $types); 99 | } 100 | 101 | if($roleIds) { 102 | $roles->whereIn('role_id', $roleIds); 103 | } 104 | 105 | $result = new Collection(); 106 | 107 | foreach($roles->get() as $role) { 108 | $result[] = new AclRole($role); 109 | } 110 | 111 | return $result; 112 | } 113 | 114 | public static function addRole(AclRole $role) { 115 | $new_role = Role::create([ 116 | 'name' => $role->name, 117 | 'type' => $role->type, 118 | 'default' => $role->default 119 | ]); 120 | 121 | $role->role_id = $new_role->role_id; 122 | 123 | RolePermission::updateRolePermissions($role); 124 | 125 | UserRole::updateRoleUsers($role); 126 | 127 | return $role->role_id; 128 | } 129 | 130 | public static function updateRole(AclRole $role) { 131 | DB::beginTransaction(); 132 | $dbRole = static::find($role->role_id); 133 | 134 | if(!$dbRole) { 135 | throw new Exception("Role not found: ".$role->role_id); 136 | } 137 | 138 | if($dbRole->name !== $role->name && !$dbRole->default) { 139 | $dbRole->name = $role->name; 140 | $dbRole->save(); 141 | } 142 | 143 | RolePermission::updateRolePermissions($role); 144 | 145 | UserRole::updateRoleUsers($role); 146 | DB::commit(); 147 | return $role->role_id; 148 | 149 | } 150 | 151 | public static function removeRole($roleId) { 152 | $dbRole = static::find($roleId); 153 | 154 | if(!$dbRole) { 155 | throw new Exception("Role not found: ".$dbRole->role_id); 156 | } 157 | 158 | if($dbRole->default) { 159 | throw new NoPermissionsException("You cannot remove default role."); 160 | } 161 | 162 | $dbRole->permissions()->delete(); 163 | $dbRole->users()->delete(); 164 | $dbRole->delete(); 165 | 166 | return $roleId; 167 | } 168 | 169 | public static function boot() { 170 | parent::boot(); 171 | static::$cache_key = Config::get('acl::cache_key', '').'_model_Role_'; 172 | static::$use_cache = Config::get('acl::using_cache', false); 173 | 174 | $clear_cache_func = function($result) { 175 | Cache::forget(Role::$cache_key); 176 | Event::fire('acl_role_changed', array($result)); 177 | }; 178 | 179 | Event::listen([ 180 | 'acl_role_added', 181 | 'acl_role_updated', 182 | 'acl_role_removed', 183 | ], $clear_cache_func); 184 | 185 | 186 | } 187 | } 188 | -------------------------------------------------------------------------------- /src/Volicon/Acl/Models/RolePermission.php: -------------------------------------------------------------------------------- 1 | HasOne ( 'Volicon\Acl\Models\Role', 'role_id' ); 17 | } 18 | 19 | public static function updateRolePermissions(AclRole $role) { 20 | $group_resources = GroupResources::getGroupResources(); 21 | 22 | $perm_ids = []; 23 | 24 | /* @var $perm \Volicon\Acl\AclPermission */ 25 | foreach($role->permissions as $key=>$perm) { 26 | $permission_id = $group_resources->search($perm->resource); 27 | $perm_ids[] = $permission_id; 28 | $role->permissions[$key]->permission_id = $permission_id; 29 | 30 | if($permission_id === FALSE) { 31 | throw new \Exception('Resource not exists: '.$perm->resource); 32 | } 33 | } 34 | 35 | $db_role_perm = RolePermission::where ( 'role_id', '=', $role->role_id )->get()->keyBy('permission_id'); 36 | $db_perm_ids = $db_role_perm->lists('permission_id'); 37 | $perm_to_delete = array_diff($db_perm_ids, $perm_ids); 38 | $perm_to_add = array_diff($perm_ids, $db_perm_ids); 39 | 40 | if($perm_to_delete) { 41 | RolePermission::where ( 'role_id', '=', $role->role_id )->whereIn('permission_id', $perm_to_delete)->delete (); 42 | } 43 | 44 | foreach($role->permissions as $perm) { 45 | if(in_array($perm->permission_id, $perm_to_add)) { 46 | RolePermission::create([ 47 | 'role_id' => $role->role_id, 48 | 'permission_id' => $perm->permission_id, 49 | 'values' => json_encode($perm->values), 50 | 'allowed' => $perm->allowed 51 | ]); 52 | } else { 53 | RolePermission::where('role_id', '=', $role->role_id) 54 | ->where('permission_id', '=', $perm->permission_id) 55 | ->update([ 56 | 'values' => json_encode($perm->values), 57 | 'allowed' => $perm->allowed 58 | ]); 59 | } 60 | } 61 | 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /src/Volicon/Acl/Models/UserRole.php: -------------------------------------------------------------------------------- 1 | hasOne ( 'Volicon\Acl\Models\Role', 'role_id' ); 17 | } 18 | 19 | public static function updateRoleUsers(AclRole $role) { 20 | 21 | $current_users = UserRole::where('role_id', '=', $role->role_id)->lists('user_id'); 22 | 23 | $users_to_delete = array_diff($current_users, $role->users->toArray()); 24 | if($users_to_delete) { 25 | static::where ( 'role_id', '=', $role->role_id )->whereIn('user_id', $users_to_delete)->delete(); 26 | 27 | $default_role_id = static::getDefaultRoleId(); 28 | if($default_role_id) { 29 | $users_with_roles = static::whereIn('user_id', $users_to_delete)->get()->lists('user_id'); 30 | $user_without_roles = array_diff($users_to_delete, $users_with_roles); 31 | foreach($user_without_roles as $user_id) { 32 | UserRole::create ( [ 33 | 'role_id' => $default_role_id, 34 | 'user_id' => $user_id 35 | ] ); 36 | } 37 | } 38 | } 39 | 40 | $users_to_add = array_diff($role->users->toArray(), $current_users); 41 | 42 | if($users_to_add) { 43 | foreach ( $users_to_add as $user_id ) { 44 | UserRole::create ( [ 45 | 'role_id' => $role->role_id, 46 | 'user_id' => $user_id 47 | ] ); 48 | } 49 | } 50 | 51 | } 52 | 53 | /* 54 | * 55 | */ 56 | public static function getDefaultRoleId() { 57 | $default_role = Config::get('acl::default_role', false); 58 | if($default_role) { 59 | $role = Role::where('name', '=', $default_role)->where('default', '=', 1)->get(); 60 | return $role->count() ? $role[0]->role_id : false; 61 | } 62 | 63 | return false; 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /src/Volicon/Acl/RoleProviders/AclRoleProvider.php: -------------------------------------------------------------------------------- 1 | role_type )) { 22 | $this->role_type = $role_type; 23 | $class_name = get_class(new static()); 24 | if(!isset(self::$all_role_types[$class_name])) { 25 | self::$all_role_types[$class_name] = []; 26 | } 27 | self::$all_role_types[$class_name][] = $role_type; 28 | } else { 29 | throw new Exception ( 'role type already set for ' . get_class ( new static () ) ); 30 | } 31 | } 32 | 33 | public function getRoles(array $roleIds = [], $resources = []) { 34 | return Role::getRoles($roleIds, [$this->role_type], $resources); 35 | } 36 | 37 | public function addRole(AclRole $role) { 38 | $role->role_type = $this->role_type; 39 | $role->permissions = $this->addSubResources($role->permissions); 40 | return Role::addRole($role); 41 | } 42 | 43 | public function updateRole(AclRole $role) { 44 | if(!$this->allowUpdateRole()) { 45 | return new NoPermissionsException ( 'Not allow to update role.' ); 46 | } 47 | $role->role_type = $this->role_type; 48 | $role->permissions = $this->addSubResources($role->permissions); 49 | return Role::updateRole($role); 50 | } 51 | 52 | public function removeRole($roleId) { 53 | return Role::removeRole($roleId); 54 | } 55 | 56 | public function getPermission($resource, array $ids = []) { 57 | 58 | $result = new AclPermission ( $resource ); 59 | 60 | if($ids){ 61 | $result = $result->newSubPermission($ids); 62 | } 63 | 64 | $roles = $this->getRoles([],[$resource]); 65 | 66 | foreach($roles as $role) { 67 | $result = $result->mergePermission($role->getPermission($resource, $ids)); 68 | } 69 | 70 | return $result; 71 | } 72 | 73 | public function allowUpdateRole() { 74 | return true; 75 | } 76 | 77 | protected function addSubResources($permissions) { 78 | $result = $permissions->keyBy ( 'resource' ); 79 | 80 | $sub_resources = [ ]; 81 | $dependent_resources = [ ]; 82 | $group_resources = Config::get('acl::group_resources', []); 83 | 84 | $dependent_group_resources = GroupResources::getDependentGroupsResources(); 85 | 86 | foreach ( $permissions as $permission ) { 87 | $resource = $permission ['resource']; 88 | if (! isset($group_resources[$resource])) { 89 | continue; 90 | } 91 | $config_permission_options = $group_resources[$resource]; 92 | $permission_options = isset ( $config_permission_options ['@options'] ) ? $config_permission_options ['@options'] : [ ]; 93 | 94 | if (! isset ( $permission_options ['depend'] )) { 95 | $permission_options ['depend'] = [ ]; 96 | } 97 | if (! isset ( $permission_options ['sub_resource'] )) { 98 | $permission_options ['sub_resource'] = false; 99 | } 100 | 101 | if ($permission_options ['sub_resource']) { 102 | $sub_resources [] = $resource; 103 | } else if (count ( $permission_options ['depend'] )) { 104 | $dependent_resources = array_merge ( $dependent_resources, $dependent_group_resources[$permission->resource]); 105 | } 106 | } 107 | 108 | foreach ( $sub_resources as $resource ) { 109 | if (! in_array ( $resource, $dependent_resources ) && ! count ( $result [$resource] ['values'] )) { 110 | unset ( $result [$resource] ); 111 | } 112 | } 113 | 114 | foreach ( $dependent_resources as $resource ) { 115 | if (! isset ( $result [$resource] )) { 116 | $result [$resource] = [ 117 | 'resource' => $resource, 118 | 'values' => [ ], 119 | 'allowed' => true 120 | ]; 121 | } 122 | } 123 | 124 | return $result->values ()->toArray (); 125 | } 126 | 127 | /** 128 | * get all types ids register to this role provider. 129 | * @return array 130 | */ 131 | public static function getAllTypes() { 132 | $class_name = get_class(new static()); 133 | return isset(self::$all_role_types[$class_name]) ? self::$all_role_types[$class_name] : []; 134 | } 135 | 136 | } 137 | -------------------------------------------------------------------------------- /src/Volicon/Acl/RoleProviders/AdminRoleProvider.php: -------------------------------------------------------------------------------- 1 | role_type], false); 22 | 23 | $group_resources = GroupResources::getGroupResources(); 24 | $permissions = new Collection(); 25 | foreach($group_resources as $resource) { 26 | $permissions[] = $this->getPermission($resource); 27 | } 28 | 29 | foreach($roles as &$role) { 30 | $role->permissions = $permissions; 31 | } 32 | 33 | return $roles; 34 | } 35 | 36 | public function addRole(AclRole $role) { 37 | 38 | if(Acl::isGuard()) { 39 | $authUser = AclUser::find ( Auth::id() ); 40 | if (! in_array ( $this->role_type, $authUser->user_types )) { 41 | return new NoPermissionsException ( 'Only admin user can add admin roles' ); 42 | } 43 | } 44 | 45 | $role->permissions = []; 46 | 47 | return parent::addRole ( $role ); 48 | } 49 | public function updateRole(AclRole $role) { 50 | if(Acl::isGuard()) { 51 | $authUser = AclUser::find ( Auth::id() ); 52 | if (! in_array ( $this->role_type, $authUser->user_types )) { 53 | return new NoPermissionsException ( 'Only admin user can update admin roles' ); 54 | } 55 | } 56 | 57 | $role->permissions = []; 58 | 59 | return parent::updateRole ( $role ); 60 | } 61 | public function removeRole($roleId) { 62 | if(Acl::isGuard()) { 63 | $authUser = AclUser::find ( Auth::id() ); 64 | if (! in_array ( $this->role_type, $authUser->user_types )) { 65 | return new NoPermissionsException ( 'Only admin user can remove admin roles' ); 66 | } 67 | } 68 | 69 | return parent::removeRole ( $roleId ); 70 | } 71 | public function getPermission($resource, array $ids = []) { 72 | return new AclPermission ( $resource, [ ], true ); 73 | } 74 | 75 | public function allowUpdateRole() { 76 | if(Acl::isGuard()) { 77 | $authUser = AclUser::find ( Auth::id() ); 78 | if (! in_array ( $this->role_type, $authUser->user_types )) { 79 | return false; 80 | } 81 | } 82 | 83 | return true; 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/Volicon/Acl/RoleProviders/UsersRoleProvider.php: -------------------------------------------------------------------------------- 1 | newSubPermission($ids); 19 | } 20 | 21 | $authUser = AclUser::find ( Auth::id() ); 22 | 23 | $roles = $this->getRoles($authUser->roles, [], [$resource]); 24 | 25 | foreach($roles as $role) { 26 | $permissions = $role->permissions->keyBy('resource'); 27 | if(isset($permissions[$resource])) { 28 | $result = $result->mergePermission($permissions[$resource]->newSubPermission($ids)); 29 | } 30 | } 31 | 32 | return $result; 33 | 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/Volicon/Acl/Support/AclInterface.php: -------------------------------------------------------------------------------- 1 | _guard) { 21 | return true; 22 | } 23 | 24 | if (in_array ( $resource, \Config::get ( 'acl::allways_allow_resources', [ ] ) )) { 25 | return true; 26 | } 27 | 28 | $perm = $this->getPermission ( $resource, $ids ); 29 | 30 | if ($perm->allowed) { 31 | return true; 32 | } 33 | 34 | if (!$perm->values || $ids) { 35 | return FALSE; 36 | } 37 | 38 | return true; 39 | } 40 | 41 | public function filter($resource, array $ids = []) { 42 | 43 | $perm = $this->getPermission ( $resource, $ids ); 44 | 45 | if ($perm->allowed && ! $perm->values) { 46 | return $ids; 47 | } 48 | 49 | if ($perm->allowed) { 50 | return array_intersect ( $ids, $perm->values ); 51 | } 52 | 53 | if (!$perm->values) { 54 | return []; 55 | } 56 | 57 | return array_diff ( $ids, $perm->values ); 58 | } 59 | 60 | public abstract function getPermission($resource = null, array $ids = []); 61 | } 62 | -------------------------------------------------------------------------------- /src/Volicon/Acl/Support/DataObject.php: -------------------------------------------------------------------------------- 1 | attributes = $data; 19 | } 20 | 21 | public function jsonSerialize() { 22 | return $this->toArray(); 23 | } 24 | 25 | public function offsetExists($offset) { 26 | return isset($this->attributes[$offset]); 27 | } 28 | 29 | public function offsetGet($offset) { 30 | return $this->attributes[$offset]; 31 | } 32 | 33 | public function offsetSet($offset, $value) { 34 | $this->attributes[$offset] = $value; 35 | } 36 | 37 | public function offsetUnset($offset) { 38 | unset($this->attributes[$offset]); 39 | } 40 | 41 | public function toArray() { 42 | return $this->attributes; 43 | } 44 | 45 | public function toJson($options = 0) { 46 | return json_encode($this, $options); 47 | } 48 | 49 | public function __get($name) { 50 | return $this->offsetGet($name); 51 | } 52 | 53 | public function __set($name, $value) { 54 | $this->offsetSet($name, $value); 55 | } 56 | 57 | public function __isset($name) { 58 | return isset($this->attributes[$name]); 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /src/Volicon/Acl/Support/MicrotimeDate.php: -------------------------------------------------------------------------------- 1 | millisec = (float)$parts[0]; 18 | $this->sec = (double)$parts[1]; 19 | } 20 | 21 | /** 22 | * 23 | * @param \Volicon\Acl\Support\MicrotimeDate $md 24 | * @return boolean return true if parameter is newer then $this 25 | */ 26 | public function compare(MicrotimeDate $md) { 27 | return $md->sec > $this->sec || ($md->sec == $this->sec && $md->millisec > $this->millisec); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/config/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Volicon/laravel-acl-rbac/9eb40d48163b7cc36ddc7941ba3adf56d470d0ff/src/config/.gitkeep -------------------------------------------------------------------------------- /src/config/config.php: -------------------------------------------------------------------------------- 1 | [ 14 | * 'resources' => [ 15 | * 'products.show' 16 | * ], 17 | * 'access_resources' => [ 18 | * 'products.index' 19 | * ] 20 | * ] 21 | * 22 | */ 23 | 'group_resources' => array(), 24 | 25 | /** 26 | * routes that allow for any user 27 | */ 28 | 'allways_allow_resources' => [], 29 | 30 | /** 31 | * Initial roles and permissions, you can add manually with Acl::addRole, AddRolePermission 32 | * 33 | * if the "values" are empy so the role relted to all values. 34 | * if allowed=false, it meant that all values excpet for the "values" defined are allow 35 | * 36 | * array( 37 | * ['name' => 'Role1', 'permissions' => [ 38 | * ["resource" => "product.create", "values" => [3,2] ,"allowed" => 1], 39 | * ["resource" => "product.edit", "values" => [1,4,5] ,"allowed" => 1], 40 | * ["resource" => "product.delete", "values" => [1,"test"] ,"allowed" => 1] 41 | * ] 42 | * ] 43 | * ) 44 | */ 45 | 'roles' => array(), 46 | 47 | /** 48 | * If role name set, any user without role, will have this role, 49 | */ 50 | 'default_role' => false, 51 | 52 | /** 53 | * what is the default permission 54 | */ 55 | 'default_permission' => false, 56 | 57 | 58 | 'roleProviders' => [ 59 | 0 => '\Volicon\Acl\RoleProviders\UsersRoleProvider', 60 | 1 => '\Volicon\Acl\RoleProviders\AdminRoleProvider' 61 | ], 62 | 63 | 'using_cache' => true, 64 | 65 | 'cache_key' => '_volicon_acl_' 66 | 67 | ); 68 | 69 | -------------------------------------------------------------------------------- /src/config/testing/config.php: -------------------------------------------------------------------------------- 1 | [ 14 | * 'resources' => [ 15 | * 'products.show' 16 | * ], 17 | * 'access_resources' => [ 18 | * 'products.index' 19 | * ] 20 | * ] 21 | * 22 | */ 23 | 'group_resources' => array(), 24 | 25 | /** 26 | * routes that allow for any user 27 | */ 28 | 'allways_allow_resources' => [], 29 | 30 | /** 31 | * Initial roles and permissions, you can add manually with Acl::addRole, AddRolePermission 32 | * 33 | * array( 34 | * ['name' => 'Role1', 'permissions' => [ 35 | * ["resource" => "product.create", "values" => [3,2] ,"allowed" => 1], 36 | * ["resource" => "product.edit", "values" => [1,4,5] ,"allowed" => 1], 37 | * ["resource" => "product.delete", "values" => [1,"test"] ,"allowed" => 1] 38 | * ] 39 | * ] 40 | * ) 41 | */ 42 | 'roles' => array( 43 | array( 44 | 'name' => 'allowAll', 45 | 'permissions' => array( 46 | array("resource" => "product.index", "values" => [] ,"allowed" => 1), 47 | ) 48 | ), 49 | array( 50 | 'name' => 'allowValue1', 51 | 'permissions' => array( 52 | array("resource" => "product.index", "values" => [1] ,"allowed" => 1), 53 | ) 54 | ), 55 | array( 56 | 'name' => 'disallowAll', 57 | 'permissions' => array( 58 | array("resource" => "product.index", "values" => [] ,"allowed" => 0), 59 | ) 60 | ), 61 | array( 62 | 'name' => 'disallowValue1', 63 | 'permissions' => array( 64 | array("resource" => "product.index", "values" => [1] ,"allowed" => 0), 65 | ) 66 | ), 67 | array( 68 | 'name' => 'allowValue1_2_3', 69 | 'permissions' => array( 70 | array("resource" => "product.index", "values" => [1, 2, 3] ,"allowed" => 1), 71 | ) 72 | ), 73 | array( 74 | 'name' => 'disallowValue2_3_4', 75 | 'permissions' => array( 76 | array("resource" => "product.index", "values" => [2, 3, 4] ,"allowed" => 0), 77 | ) 78 | ) 79 | ), 80 | 81 | /** 82 | * If role name set, any user without role, will have this role, 83 | */ 84 | 'default_role' => false, 85 | 86 | /** 87 | * what is the default permission 88 | */ 89 | 'default_permission' => false, 90 | 91 | 92 | 'roleProviders' => [ 93 | 0 => '\Volicon\Acl\RoleProviders\UsersRoleProvider', 94 | 1 => '\Volicon\Acl\RoleProviders\AdminRoleProvider' 95 | ], 96 | 97 | 'using_cache' => false, 98 | 99 | 'cache_key' => '_volicon_acl_' 100 | 101 | ); 102 | 103 | -------------------------------------------------------------------------------- /src/migrations/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Volicon/laravel-acl-rbac/9eb40d48163b7cc36ddc7941ba3adf56d470d0ff/src/migrations/.gitkeep -------------------------------------------------------------------------------- /src/migrations/2013_10_03_110631_create_user_role_table.php: -------------------------------------------------------------------------------- 1 | unsignedInteger('role_id'); 18 | $table->unsignedInteger('user_id'); 19 | 20 | $table->unique(['role_id', 'user_id']); 21 | }); 22 | } 23 | 24 | /** 25 | * Reverse the migrations. 26 | * 27 | * @return void 28 | */ 29 | public function down() 30 | { 31 | Schema::drop('user_role'); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/migrations/2013_10_06_112820_create_role_permission_table.php: -------------------------------------------------------------------------------- 1 | unsignedInteger('role_id'); 18 | $table->unsignedInteger('permission_id'); 19 | $table->text('values')->nullable(); 20 | $table->boolean('allowed'); 21 | 22 | $table->primary(['role_id', 'permission_id']); 23 | }); 24 | } 25 | 26 | /** 27 | * Reverse the migrations. 28 | * 29 | * @return void 30 | */ 31 | public function down() 32 | { 33 | Schema::drop('role_permission'); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/migrations/2013_10_09_120304_create_roles_table.php: -------------------------------------------------------------------------------- 1 | increments('role_id'); 18 | $table->string('name',255)->unique(); 19 | $table->integer('type')->default(0); 20 | $table->boolean('default')->default(0); 21 | $table->timestamps(); 22 | }); 23 | } 24 | 25 | /** 26 | * Reverse the migrations. 27 | * 28 | * @return void 29 | */ 30 | public function down() 31 | { 32 | Schema::drop('roles'); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/migrations/2014_07_27_084049_create_group_resources_table.php: -------------------------------------------------------------------------------- 1 | down(); 16 | Schema::create('group_resources', function(Blueprint $table) 17 | { 18 | $table->increments('permission_id'); 19 | $table->string('resource',255); 20 | }); 21 | } 22 | 23 | /** 24 | * Reverse the migrations. 25 | * 26 | * @return void 27 | */ 28 | public function down() 29 | { 30 | Schema::dropIfExists('group_resources'); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /tests/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Volicon/laravel-acl-rbac/9eb40d48163b7cc36ddc7941ba3adf56d470d0ff/tests/.gitkeep -------------------------------------------------------------------------------- /tests/TestCase.php: -------------------------------------------------------------------------------- 1 | 'Volicon\Acl\Facade\Acl' 14 | ); 15 | } 16 | 17 | protected function getPackageProviders() 18 | { 19 | return array('Volicon\Acl\AclServiceProvider'); 20 | } 21 | 22 | public function setUp() 23 | { 24 | parent::setUp(); 25 | } 26 | } 27 | --------------------------------------------------------------------------------