├── .gitignore ├── .travis.yml ├── CHANGELOG.md ├── LICENSE ├── Module.php ├── README.md ├── UPGRADE.md ├── composer.json ├── config ├── module.config.php └── zfc_rbac.global.php.dist ├── data ├── FlatRole.php.dist ├── HierarchicalRole.php.dist ├── Permission.php.dist └── README.md ├── docs ├── 01. Introduction.md ├── 02. Quick Start.md ├── 03. Role providers.md ├── 04. Guards.md ├── 05. Strategies.md ├── 06. Using the Authorization Service.md ├── 07. Cookbook.md ├── README.md └── images │ ├── workflow-with-guards.png │ └── workflow-without-guards.png ├── phpunit.xml.dist ├── src └── ZfcRbac │ ├── Assertion │ ├── AssertionInterface.php │ └── AssertionPluginManager.php │ ├── Collector │ └── RbacCollector.php │ ├── Exception │ ├── ExceptionInterface.php │ ├── InvalidArgumentException.php │ ├── RoleNotFoundException.php │ ├── RuntimeException.php │ ├── UnauthorizedException.php │ └── UnauthorizedExceptionInterface.php │ ├── Factory │ ├── AssertionPluginManagerFactory.php │ ├── AuthenticationIdentityProviderFactory.php │ ├── AuthorizationServiceDelegatorFactory.php │ ├── AuthorizationServiceFactory.php │ ├── ControllerGuardFactory.php │ ├── ControllerPermissionsGuardFactory.php │ ├── GuardPluginManagerFactory.php │ ├── GuardsFactory.php │ ├── HasRoleViewHelperFactory.php │ ├── IsGrantedPluginFactory.php │ ├── IsGrantedViewHelperFactory.php │ ├── ModuleOptionsFactory.php │ ├── ObjectRepositoryRoleProviderFactory.php │ ├── RbacFactory.php │ ├── RedirectStrategyFactory.php │ ├── RoleProviderPluginManagerFactory.php │ ├── RoleServiceFactory.php │ ├── RouteGuardFactory.php │ ├── RoutePermissionsGuardFactory.php │ └── UnauthorizedStrategyFactory.php │ ├── Guard │ ├── AbstractGuard.php │ ├── ControllerGuard.php │ ├── ControllerPermissionsGuard.php │ ├── GuardInterface.php │ ├── GuardPluginManager.php │ ├── ProtectionPolicyTrait.php │ ├── RouteGuard.php │ └── RoutePermissionsGuard.php │ ├── Identity │ ├── AuthenticationIdentityProvider.php │ ├── IdentityInterface.php │ └── IdentityProviderInterface.php │ ├── Initializer │ └── AuthorizationServiceInitializer.php │ ├── Module.php │ ├── Mvc │ └── Controller │ │ └── Plugin │ │ └── IsGranted.php │ ├── Options │ ├── ModuleOptions.php │ ├── RedirectStrategyOptions.php │ └── UnauthorizedStrategyOptions.php │ ├── Permission │ └── PermissionInterface.php │ ├── Role │ ├── InMemoryRoleProvider.php │ ├── ObjectRepositoryRoleProvider.php │ ├── RoleProviderInterface.php │ └── RoleProviderPluginManager.php │ ├── Service │ ├── AuthorizationService.php │ ├── AuthorizationServiceAwareInterface.php │ ├── AuthorizationServiceAwareTrait.php │ ├── AuthorizationServiceInterface.php │ └── RoleService.php │ └── View │ ├── Helper │ ├── HasRole.php │ └── IsGranted.php │ └── Strategy │ ├── AbstractStrategy.php │ ├── RedirectStrategy.php │ └── UnauthorizedStrategy.php ├── tests ├── Bootstrap.php ├── TestConfigurationV2.php.dist ├── TestConfigurationV3.php.dist ├── ZfcRbacTest │ ├── Asset │ │ ├── DummyGuard.php │ │ ├── FlatRole.php │ │ ├── HierarchicalRole.php │ │ ├── MockRoleWithPermissionMethod.php │ │ ├── MockRoleWithPermissionProperty.php │ │ ├── Permission.php │ │ └── SimpleAssertion.php │ ├── Collector │ │ └── RbacCollectorTest.php │ ├── Factory │ │ ├── AssertionPluginManagerFactoryTest.php │ │ ├── AuthenticationIdentityProviderFactoryTest.php │ │ ├── AuthorizationServiceDelegatorTest.php │ │ ├── AuthorizationServiceFactoryTest.php │ │ ├── ControllerGuardFactoryTest.php │ │ ├── ControllerPermissionsGuardFactoryTest.php │ │ ├── GuardPluginManagerFactoryTest.php │ │ ├── GuardsFactoryTest.php │ │ ├── HasRoleViewHelperFactoryTest.php │ │ ├── IsGrantedPluginFactoryTest.php │ │ ├── IsGrantedViewHelperFactoryTest.php │ │ ├── ModuleOptionsFactoryTest.php │ │ ├── ObjectRepositoryRoleProviderFactoryTest.php │ │ ├── RbacFactoryTest.php │ │ ├── RedirectStrategyFactoryTest.php │ │ ├── RoleProviderPluginManagerFactoryTest.php │ │ ├── RoleServiceFactoryTest.php │ │ ├── RouteGuardFactoryTest.php │ │ ├── RoutePermissionsGuardFactoryTest.php │ │ └── UnauthorizedStrategyFactoryTest.php │ ├── Guard │ │ ├── AbstractGuardTest.php │ │ ├── ControllerGuardTest.php │ │ ├── ControllerPermissionsGuardTest.php │ │ ├── GuardPluginManagerTest.php │ │ ├── ProtectionPolicyTraitTest.php │ │ ├── RouteGuardTest.php │ │ └── RoutePermissionsGuardTest.php │ ├── Identity │ │ └── AuthenticationIdentityProviderTest.php │ ├── Initializer │ │ ├── AuthorizationAwareFake.php │ │ └── AuthorizationServiceInitializerTest.php │ ├── ModuleTest.php │ ├── Mvc │ │ └── Controller │ │ │ └── Plugin │ │ │ └── IsGrantedTest.php │ ├── Options │ │ ├── ModuleOptionsTest.php │ │ ├── RedirectStrategyOptionsTest.php │ │ └── UnauthorizedStrategyOptionsTest.php │ ├── Role │ │ ├── InMemoryRoleProviderTest.php │ │ ├── ObjectRepositoryRoleProviderTest.php │ │ └── RoleProviderPluginManagerTest.php │ ├── Service │ │ ├── AuthorizationServiceAwareTraitTest.php │ │ ├── AuthorizationServiceTest.php │ │ └── RoleServiceTest.php │ ├── Util │ │ └── ServiceManagerFactory.php │ └── View │ │ ├── Helper │ │ ├── HasRoleTest.php │ │ └── IsGrantedTest.php │ │ └── Strategy │ │ ├── RedirectStrategyTest.php │ │ └── UnauthorizedStrategyTest.php └── testing.config.php └── view ├── error └── 403.phtml └── zend-developer-tools └── toolbar └── zfc-rbac.phtml /.gitignore: -------------------------------------------------------------------------------- 1 | vendor 2 | composer.lock 3 | .idea 4 | composer.phar 5 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: php 2 | 3 | php: 4 | - 5.6 5 | - 7 6 | - hhvm 7 | 8 | env: 9 | matrix: 10 | - DEPENDENCIES="" 11 | - DEPENDENCIES="--prefer-lowest --prefer-stable" 12 | 13 | before_script: 14 | - composer self-update 15 | - composer update --prefer-dist $DEPENDENCIES 16 | 17 | script: 18 | - ./vendor/bin/phpunit --coverage-clover ./build/logs/clover.xml --exclude-group Functional 19 | - ./vendor/bin/phpunit --group=Functional 20 | - ./vendor/bin/phpcs --standard=PSR2 ./src/ 21 | 22 | after_script: 23 | - php vendor/bin/coveralls -v 24 | 25 | notifications: 26 | irc: "irc.freenode.org#zftalk.modules" 27 | email: true 28 | 29 | matrix: 30 | allow_failures: 31 | - php: hhvm 32 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # CHANGELOG 2 | 3 | For changelog, please refer to the [releases](https://github.com/ZF-Commons/ZfcRbac/releases) page. 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013, ZF-Commons Contributors 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without modification, 5 | are permitted provided that the following conditions are met: 6 | 7 | Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | Redistributions in binary form must reproduce the above copyright notice, this 11 | list of conditions and the following disclaimer in the documentation and/or 12 | other materials provided with the distribution. 13 | 14 | Neither the name of the ZF-Commons nor the names of its 15 | contributors may be used to endorse or promote products derived from 16 | this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 19 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 22 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 25 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /Module.php: -------------------------------------------------------------------------------- 1 | If you are looking for older version of ZfcRbac, please refer to the 0.2.x branch. 31 | > If you are using ZfcRbac 1.0, please upgrade to 2.0. 32 | 33 | ## Optional 34 | 35 | - [DoctrineModule](https://github.com/doctrine/DoctrineModule): if you want to use some built-in role and permission providers. 36 | - [ZendDeveloperTools](https://github.com/zendframework/ZendDeveloperTools): if you want to have useful stats added to 37 | the Zend Developer toolbar. 38 | 39 | ## Upgrade 40 | 41 | You can find an [upgrade guide](UPGRADE.md) to quickly upgrade your application from major versions of ZfcRbac. 42 | 43 | ## Installation 44 | 45 | ZfcRbac only officially supports installation through Composer. For Composer documentation, please refer to 46 | [getcomposer.org](http://getcomposer.org/). 47 | 48 | Install the module: 49 | 50 | ```sh 51 | $ php composer.phar require zf-commons/zfc-rbac:~2.4 52 | ``` 53 | 54 | Enable the module by adding `ZfcRbac` key to your `application.config.php` file. Customize the module by copy-pasting 55 | the `zfc_rbac.global.php.dist` file to your `config/autoload` folder. 56 | 57 | ## Documentation 58 | 59 | The official documentation is available in the [/docs](/docs) folder. 60 | 61 | You can also find some Doctrine entities in the [/data](/data) folder that will help you to more quickly take advantage 62 | of ZfcRbac. 63 | 64 | ## Support 65 | 66 | - File issues at https://github.com/ZF-Commons/zfc-rbac/issues. 67 | - Ask questions in the [zf-common gitter](https://gitter.im/ZFCommons/zfc-rbac) chat. 68 | -------------------------------------------------------------------------------- /UPGRADE.md: -------------------------------------------------------------------------------- 1 | # Upgrade guide 2 | 3 | ## From v2.2 to v2.3 4 | 5 | - No BC 6 | 7 | ## From v2.1 to v2.2 8 | 9 | - [Potential BC] To simplify unit tests, we have introduced a new `AuthorizationServiceInterface` that the 10 | `AuthorizationService` now implements. We didn't touch any interface (such as `AssertionInterface`) that rely explicitly 11 | on typehinting the `AuthorizationService` to avoid big BC. However, we have updated the view helper and controller 12 | plugins to use the interface instead. This can lead to a BC if you created subclasses of those plugins (which is 13 | not a typical use case). If this is the case, just change `AuthorizationService` to `AuthorizationServiceInterface`. 14 | 15 | ## From v2.0 to v2.1 16 | 17 | - [Potential BC] A potential BC have been introduced in v2.1 to respect interfaces of RBAC component more strictly. 18 | However there is great chance that you have nothing to do. Now, ZfcRbac no longer cast permissions to string before 19 | passing it to your "hasPermission" method in the Role entity. If you used to call `isGranted` using a string permission, 20 | like this: `isGranted('myPermission')`, then you have nothing to do. However, if you are passing a `PermissionInterface` 21 | object, you will now receive this object instead of a string. It's up to you to getting the name from your permission. 22 | 23 | ## From v1 to v2 24 | 25 | Here are the major breaking changes from ZfcRbac 1 to ZfcRbac 2: 26 | 27 | - [BC] Dependency to the ZF2 RBAC component has been replaced in favour of a ZF3 prototype which fixes a lot 28 | of design issues. 29 | - [BC] ZfcRbac no longer accepts multiple role providers. Therefore, the option `role_providers` has been renamed 30 | to `role_provider` 31 | - [BC] Permission providers are gone (hence, the options `permission_providers` as well as `permission_manager` should 32 | be removed). Instead, roles now embed all the necessary information 33 | - [BC] The `redirect_to_route` option for the `RedirectStrategy` is gone. Instead, we now have two options: 34 | `redirect_to_route_connected` and `redirect_to_route_disconnected`. This solves an issue when people used to have 35 | a guard on `login` for non-authenticated users only, which leaded to circular redirections. 36 | - [BC] The default protection policy is now `POLICY_ALLOW`. `POLICY_DENY` was way too restrictive and annoying to 37 | work with by default. 38 | - [BC] `isGranted` method of the AuthorizationService no longer accepts an assertion as a second parameter. Instead, 39 | the AuthorizationService now has an assertion map, that allows to map an assertion to a permission. This allows to 40 | inject dependencies into assertions, as well as making the use of assertions much more transparent. 41 | - [BC] Each assertions now receive the whole `AuthorizationService` instead of the current identity. This allows to 42 | support use cases where an assertion needs to check another permission. 43 | - [BC] Entity schema for hierarchical role have changed and no longer require to implement `RecursiveIterator`. Please have a look at the new schema in the `data` folder. 44 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "zf-commons/zfc-rbac", 3 | "description": "Zend Framework 2 Module that provides a layer of features of Zend\\Permissions\\Rbac", 4 | "type": "library", 5 | "license": "MIT", 6 | "keywords": [ 7 | "module", 8 | "zf2", 9 | "rbac", 10 | "permissions" 11 | ], 12 | "homepage": "http://www.github.com/ZF-Commons/zfc-rbac", 13 | "authors": [ 14 | { 15 | "name": "Kyle Spraggs", 16 | "email": "theman@spiffyjr.me", 17 | "homepage": "http://www.spiffyjr.me/" 18 | }, 19 | { 20 | "name": "Michaël Gallego", 21 | "email": "mic.gallego@gmail.com", 22 | "homepage": "http://www.michaelgallego.fr" 23 | }, 24 | { 25 | "name": "Jean-Marie Leroux", 26 | "email": "jmleroux.pro@gmail.com" 27 | } 28 | ], 29 | "require": { 30 | "php": "~5.6 || ~7.0", 31 | "zendframework/zend-config": "~2.2 || ^3.1", 32 | "zendframework/zend-eventmanager": "^2.6.3 || ^3.0", 33 | "zendframework/zend-mvc": "~2.7 || ^3.0", 34 | "zendframework/zend-servicemanager": "^2.7.5 || ^3.0.3", 35 | "zfr/rbac": "~1.2" 36 | }, 37 | "require-dev": { 38 | "zendframework/zend-authentication": "~2.2", 39 | "zendframework/zend-developer-tools": "~1.1", 40 | "zendframework/zend-log": "~2.2", 41 | "zendframework/zend-http": "~2.2", 42 | "zendframework/zend-i18n": "~2.7.3", 43 | "zendframework/zend-serializer": "~2.2", 44 | "zendframework/zend-view": "~2.2", 45 | "phpunit/phpunit": "~4.8.26", 46 | "squizlabs/php_codesniffer": "2.6.*", 47 | "satooshi/php-coveralls": "~0.6", 48 | "doctrine/common": "~2.4", 49 | "doctrine/doctrine-module": "~1.1", 50 | "doctrine/doctrine-orm-module": "^1.0" 51 | }, 52 | "suggest": { 53 | "zendframework/zend-developer-tools": "if you want to show information about the roles", 54 | "doctrine/doctrine-module": "if you want to use Doctrine role provider" 55 | }, 56 | "autoload": { 57 | "psr-0": { 58 | "ZfcRbac\\": "src/" 59 | } 60 | }, 61 | "extra": { 62 | "branch-alias": { 63 | "dev-master": "2.4-dev", 64 | "dev-develop": "3.0-dev" 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /data/FlatRole.php.dist: -------------------------------------------------------------------------------- 1 | permissions = new ArrayCollection(); 59 | } 60 | 61 | /** 62 | * Get the role identifier 63 | * 64 | * @return int 65 | */ 66 | public function getId() 67 | { 68 | return $this->id; 69 | } 70 | 71 | /** 72 | * Set the role name 73 | * 74 | * @param string $name 75 | * @return void 76 | */ 77 | public function setName($name) 78 | { 79 | $this->name = (string) $name; 80 | } 81 | 82 | /** 83 | * Get the role name 84 | * 85 | * @return string 86 | */ 87 | public function getName() 88 | { 89 | return $this->name; 90 | } 91 | 92 | /** 93 | * {@inheritDoc} 94 | */ 95 | public function addPermission($permission) 96 | { 97 | if (is_string($permission)) { 98 | $permission = new Permission($permission); 99 | } 100 | 101 | $this->permissions[(string) $permission] = $permission; 102 | } 103 | 104 | /** 105 | * {@inheritDoc} 106 | */ 107 | public function hasPermission($permission) 108 | { 109 | // This can be a performance problem if your role has a lot of permissions. Please refer 110 | // to the cookbook to an elegant way to solve this issue 111 | 112 | return isset($this->permissions[(string) $permission]); 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /data/Permission.php.dist: -------------------------------------------------------------------------------- 1 | name = (string) $name; 50 | } 51 | 52 | /** 53 | * Get the permission identifier 54 | * 55 | * @return int 56 | */ 57 | public function getId() 58 | { 59 | return $this->id; 60 | } 61 | 62 | /** 63 | * {@inheritDoc} 64 | */ 65 | public function __toString() 66 | { 67 | return $this->name; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /data/README.md: -------------------------------------------------------------------------------- 1 | These files are only provided as-in, and are not part of ZfcRbac. They provide you some basic Doctrine ORM 2 | entities that you can use as a starting point. 3 | 4 | ## Flat role or hierarchical role? 5 | 6 | As you can see, there are a FlatRole and HierarchicalRole entity classes. You must only use one of them, not both. 7 | 8 | The flat role is easier to follow, because each role contains all its permissions, and the database schema is easier 9 | as you do not need a join table for the role hierarchy. 10 | 11 | On the other hand, the hierarchical role is much more flexible, and prevent you from duplicating the same permissions 12 | into all roles. 13 | 14 | It really depends on your application. 15 | -------------------------------------------------------------------------------- /docs/01. Introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | Welcome to the official documentation of ZfcRbac! 4 | 5 | In this part, the following questions will be answered: 6 | 7 | * Why should I use an authorization module? 8 | * What is the Rbac model? 9 | * How can I integrate ZfcRbac into my application? 10 | 11 | ## Why should I use an authorization module? 12 | 13 | The authorization part of an application is an essential aspect of securing your application. While the authentication 14 | part tells you who is using your website, the authorization answers if the given identity has the permission to 15 | perform specific actions. 16 | 17 | ## What is the Rbac model? 18 | 19 | Rbac stands for **role-based access control**. We use a very simple (albeit powerful) implementation of this model 20 | through the use of [this PHP library](https://github.com/zf-fr/rbac). 21 | 22 | > We are not using the official ZF2 Rbac component since ZfcRbac 2.0 as it has some design flaws. The library we are 23 | using here is actually a prototype for ZF3 Rbac component I've made specifically for ZfcRbac. 24 | 25 | The basic idea of Rbac is to use roles and permissions: 26 | 27 | * **Users** can have one or many **Roles** 28 | * **Roles** request access to **Permissions** 29 | * **Permissions** are granted to **Roles** 30 | 31 | By default, ZfcRbac can be used for two kinds of Rbac model: 32 | 33 | * Flat RBAC model: in this model, roles cannot have children. This is ideal for smaller applications, as it is easier 34 | to understand, and the database design is simpler (no need for a join table). 35 | * Hierarchical RBAC model: in this model, roles can have child roles. When evaluating if a given role has a 36 | permission, this model also checks recursively if any of its child roles also have the permission. 37 | 38 | 39 | ## How can I integrate ZfcRbac into my application? 40 | 41 | ZfcRbac offers multiple ways to protect your application: 42 | 43 | * Using **Guards**: these classes act as "firewalls" that block access to routes and/or controllers. Guards are usually 44 | configured using PHP arrays, and are executed early in the MVC dispatch process. Typically this happens right after 45 | the route has been matched. 46 | * Using **AuthorizationService**: a complementary method is to use the `AuthorizationService` class and inject it into your 47 | service classes to protect them from unwanted access. 48 | 49 | While it is advised to use both methods to make your application even more secure, this is completely optional and you 50 | can choose either of them independently. 51 | 52 | To find out about how you can easily make your existing application more secure, please refer to the following section: 53 | 54 | * [Cookbook: A real world example](07.%20Cookbook.md#a-real-world-application) 55 | 56 | ### Navigation 57 | 58 | * Continue to [the **Quick Start**](02.%20Quick%20Start.md) 59 | * Back to [the Index](README.md) 60 | -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | _Up-to-date with version 2.3.* of ZfcRbac_ 2 | 3 | Welcome to the official ZfcRbac documentation. This documentation will help you quickly understand how to use 4 | and extend ZfcRbac. 5 | 6 | If you are looking for some information that is not listed in the documentation, please open an issue! 7 | 8 | 1. [Introduction](01.%20Introduction.md) 9 | 1. [Why should I use an authorization module?](01.%20Introduction.md#why-should-i-use-an-authorization-module) 10 | 2. [What is the Rbac model?](01.%20Introduction.md#what-is-the-rbac-model) 11 | 3. [How can I integrate ZfcRbac into my application?](01.%20Introduction.md#how-can-i-integrate-zfcrbac-into-my-application) 12 | 13 | 2. [Quick Start](02.%20Quick%20Start.md) 14 | 1. [Specifying an identity provider](02.%20Quick%20Start.md#specifying-an-identity-provider) 15 | 2. [Adding a guard](02.%20Quick%20Start.md#adding-a-guard) 16 | 3. [Adding a role provider](02.%20Quick%20Start.md#adding-a-role-provider) 17 | 5. [Registering a strategy](02.%20Quick%20Start.md#registering-a-strategy) 18 | 6. [Using the authorization service](02.%20Quick%20Start.md#using-the-authorization-service) 19 | 20 | 3. [Role providers](03.%20Role%20providers.md) 21 | 1. [What are role providers?](03.%20Role%20providers.md#what-are-role-providers) 22 | 2. [Identity providers](03.%20Role%20providers.md#identity-providers) 23 | 3. [Built-in role providers](03.%20Role%20providers.md#built-in-role-providers) 24 | 4. [Creating custom role providers](03.%20Role%20providers.md#creating-custom-role-providers) 25 | 26 | 4. [Guards](04.%20Guards.md) 27 | 1. [What are guards and when to use them?](04.%20Guards.md#what-are-guards-and-when-to-use-them) 28 | 2. [Built-in guards](04.%20Guards.md#built-in-guards) 29 | 3. [Creating custom guards](04.%20Guards.md#creating-custom-guards) 30 | 31 | 5. [Strategies](05.%20Strategies.md) 32 | 1. [What are strategies?](05.%20Strategies.md#what-are-strategies) 33 | 2. [Built-in strategies](05.%20Strategies.md#built-in-strategies) 34 | 3. [Creating custom strategies](05.%20Strategies.md#creating-custom-strategies) 35 | 36 | 6. [Using the Authorization Service](06.%20Using%20the%20Authorization%20Service.md) 37 | 1. [Injecting the AuthorizationService](06.%20Using%20the%20Authorization%20Service.md#injecting-the-authorization-service) 38 | 2. [Checking permissions](06.%20Using%20the%20Authorization%20Service.md#checking-permissions-in-a-service) 39 | 1. [In a service](06.%20Using%20the%20Authorization%20Service.md#checking-permissions-in-a-service) 40 | 2. [In a controller's action using the isGranted controller plugin](06.%20Using%20the%20Authorization%20Service.md#in-a-controller-) 41 | 3. [In a view using the isGranted view helper](06.%20Using%20the%20Authorization%20Service.md#in-a-view-) 42 | 3. [Permissions and Assertions](06.%20Using%20the%20Authorization%20Service.md#permissions-and-assertions) 43 | 44 | 7. [Cookbook](07.%20Cookbook.md) 45 | 1. [A real world example](07.%20Cookbook.md#a-real-world-application) 46 | 2. [Best practices](07.%20Cookbook.md#best-practices) 47 | 3. [Using ZfcRbac with Doctrine ORM](07.%20Cookbook.md#using-zfcrbac-with-doctrine-orm) 48 | 4. [How to deal with roles with lot of permissions?](07.%20Cookbook.md#how-to-deal-with-roles-with-lot-of-permissions) 49 | 5. [Using ZfcRbac and ZF2 Assetic](07.%20Cookbook.md#using-zfcrbac-and-zf2-assetic) 50 | 6. [Using ZfcRbac and ZfcUser](07.%20Cookbook.md#using-zfcrbac-and-zfcuser) 51 | -------------------------------------------------------------------------------- /docs/images/workflow-with-guards.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZF-Commons/zfc-rbac/a0df20486d17ea7d096efe35504b3d3204da8efe/docs/images/workflow-with-guards.png -------------------------------------------------------------------------------- /docs/images/workflow-without-guards.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZF-Commons/zfc-rbac/a0df20486d17ea7d096efe35504b3d3204da8efe/docs/images/workflow-without-guards.png -------------------------------------------------------------------------------- /phpunit.xml.dist: -------------------------------------------------------------------------------- 1 | 2 | 14 | 15 | ./tests 16 | 17 | 18 | 19 | ./src 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/ZfcRbac/Assertion/AssertionInterface.php: -------------------------------------------------------------------------------- 1 | 27 | * @author Aeneas Rekkas 28 | * @author Daniel Gimenes 29 | * @license MIT 30 | */ 31 | interface AssertionInterface 32 | { 33 | /** 34 | * Check if this assertion is true 35 | * 36 | * @TODO: for v3, update the interface to typehint to AuthorizationServiceInterface instead 37 | * 38 | * @param AuthorizationService $authorizationService 39 | * @param mixed $context 40 | * @return bool 41 | */ 42 | public function assert(AuthorizationService $authorizationService); 43 | } 44 | -------------------------------------------------------------------------------- /src/ZfcRbac/Assertion/AssertionPluginManager.php: -------------------------------------------------------------------------------- 1 | validate($plugin); 55 | } 56 | 57 | /** 58 | * {@inheritDoc} 59 | */ 60 | protected function canonicalizeName($name) 61 | { 62 | return $name; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/ZfcRbac/Exception/ExceptionInterface.php: -------------------------------------------------------------------------------- 1 | 25 | * @license MIT 26 | */ 27 | interface ExceptionInterface 28 | { 29 | } 30 | -------------------------------------------------------------------------------- /src/ZfcRbac/Exception/InvalidArgumentException.php: -------------------------------------------------------------------------------- 1 | 27 | * @license MIT 28 | */ 29 | class InvalidArgumentException extends BaseInvalidArgumentException implements ExceptionInterface 30 | { 31 | } 32 | -------------------------------------------------------------------------------- /src/ZfcRbac/Exception/RoleNotFoundException.php: -------------------------------------------------------------------------------- 1 | 27 | * @license MIT 28 | */ 29 | class RoleNotFoundException extends BaseRuntimeException implements ExceptionInterface 30 | { 31 | /** 32 | * @var string 33 | */ 34 | protected $message = 'No role could be found'; 35 | } 36 | -------------------------------------------------------------------------------- /src/ZfcRbac/Exception/RuntimeException.php: -------------------------------------------------------------------------------- 1 | 27 | * @license MIT 28 | */ 29 | class RuntimeException extends BaseRuntimeException implements ExceptionInterface 30 | { 31 | } 32 | -------------------------------------------------------------------------------- /src/ZfcRbac/Exception/UnauthorizedException.php: -------------------------------------------------------------------------------- 1 | 27 | * @license MIT 28 | */ 29 | class UnauthorizedException extends BaseRuntimeException implements UnauthorizedExceptionInterface 30 | { 31 | /** 32 | * @var string 33 | */ 34 | protected $message = 'You are not authorized to access this resource'; 35 | } 36 | -------------------------------------------------------------------------------- /src/ZfcRbac/Exception/UnauthorizedExceptionInterface.php: -------------------------------------------------------------------------------- 1 | 25 | * @license MIT 26 | */ 27 | interface UnauthorizedExceptionInterface extends ExceptionInterface 28 | { 29 | } 30 | -------------------------------------------------------------------------------- /src/ZfcRbac/Factory/AssertionPluginManagerFactory.php: -------------------------------------------------------------------------------- 1 | get('Config')['zfc_rbac']['assertion_manager']; 44 | 45 | return new AssertionPluginManager($container, $config); 46 | } 47 | 48 | /** 49 | * {@inheritDoc} 50 | * @return AssertionPluginManager 51 | */ 52 | public function createService(ServiceLocatorInterface $serviceLocator) 53 | { 54 | return $this($serviceLocator, AssertionPluginManager::class); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/ZfcRbac/Factory/AuthenticationIdentityProviderFactory.php: -------------------------------------------------------------------------------- 1 | 30 | * @license MIT 31 | */ 32 | class AuthenticationIdentityProviderFactory implements FactoryInterface 33 | { 34 | /** 35 | * @param ContainerInterface $container 36 | * @param string $requestedName 37 | * @param array|null $options 38 | * @return AuthenticationIdentityProvider 39 | */ 40 | public function __invoke(ContainerInterface $container, $requestedName, array $options = null) 41 | { 42 | /* @var \Zend\Authentication\AuthenticationService $authenticationProvider */ 43 | $authenticationProvider = $container->get('Zend\Authentication\AuthenticationService'); 44 | 45 | return new AuthenticationIdentityProvider($authenticationProvider); 46 | } 47 | 48 | /** 49 | * {@inheritDoc} 50 | * @return AuthenticationIdentityProvider 51 | */ 52 | public function createService(ServiceLocatorInterface $serviceLocator) 53 | { 54 | return $this($serviceLocator, AuthenticationIdentityProvider::class); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/ZfcRbac/Factory/AuthorizationServiceDelegatorFactory.php: -------------------------------------------------------------------------------- 1 | 32 | * @license MIT License 33 | */ 34 | class AuthorizationServiceDelegatorFactory implements DelegatorFactoryInterface 35 | { 36 | /** 37 | * @param ContainerInterface $container 38 | * @param string $name 39 | * @param callable $callback 40 | * @param array|null $options 41 | * @return mixed 42 | */ 43 | public function __invoke(ContainerInterface $container, $name, callable $callback, array $options = null) 44 | { 45 | $instanceToDecorate = call_user_func($callback); 46 | 47 | if (!$instanceToDecorate instanceof AuthorizationServiceAwareInterface) { 48 | throw new RuntimeException("The service $name must implement AuthorizationServiceAwareInterface."); 49 | } 50 | 51 | if ($container instanceof AbstractPluginManager) { 52 | $container = $container->getServiceLocator(); 53 | } 54 | 55 | $authorizationService = $container->get('ZfcRbac\Service\AuthorizationService'); 56 | $instanceToDecorate->setAuthorizationService($authorizationService); 57 | 58 | return $instanceToDecorate; 59 | } 60 | 61 | /** 62 | * @param ServiceLocatorInterface $serviceLocator 63 | * @param string $name 64 | * @param string $requestedName 65 | * @param callable $callback 66 | * @return mixed 67 | */ 68 | public function createDelegatorWithName(ServiceLocatorInterface $serviceLocator, $name, $requestedName, $callback) 69 | { 70 | return $this($serviceLocator, $requestedName, $callback); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/ZfcRbac/Factory/AuthorizationServiceFactory.php: -------------------------------------------------------------------------------- 1 | 30 | * @license MIT 31 | */ 32 | class AuthorizationServiceFactory implements FactoryInterface 33 | { 34 | /** 35 | * @param ContainerInterface $container 36 | * @param string $requestedName 37 | * @param array|null $options 38 | * @return AuthorizationService 39 | */ 40 | public function __invoke(ContainerInterface $container, $requestedName, array $options = null) 41 | { 42 | /* @var \Rbac\Rbac $rbac */ 43 | $rbac = $container->get('Rbac\Rbac'); 44 | 45 | /* @var \ZfcRbac\Service\RoleService $roleService */ 46 | $roleService = $container->get('ZfcRbac\Service\RoleService'); 47 | 48 | /* @var \ZfcRbac\Assertion\AssertionPluginManager $assertionPluginManager */ 49 | $assertionPluginManager = $container->get('ZfcRbac\Assertion\AssertionPluginManager'); 50 | 51 | /* @var \ZfcRbac\Options\ModuleOptions $moduleOptions */ 52 | $moduleOptions = $container->get('ZfcRbac\Options\ModuleOptions'); 53 | 54 | $authorizationService = new AuthorizationService($rbac, $roleService, $assertionPluginManager); 55 | $authorizationService->setAssertions($moduleOptions->getAssertionMap()); 56 | 57 | return $authorizationService; 58 | } 59 | 60 | /** 61 | * {@inheritDoc} 62 | * @return AuthorizationService 63 | */ 64 | public function createService(ServiceLocatorInterface $serviceLocator) 65 | { 66 | return $this($serviceLocator, AuthorizationService::class); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/ZfcRbac/Factory/ControllerGuardFactory.php: -------------------------------------------------------------------------------- 1 | 30 | * @license MIT 31 | */ 32 | class ControllerGuardFactory implements FactoryInterface 33 | { 34 | /** 35 | * @var array 36 | */ 37 | protected $options = []; 38 | 39 | /** 40 | * {@inheritDoc} 41 | */ 42 | public function __construct(array $options = []) 43 | { 44 | $this->setCreationOptions($options); 45 | } 46 | 47 | /** 48 | * {@inheritDoc} 49 | */ 50 | public function setCreationOptions(array $options) 51 | { 52 | $this->options = $options; 53 | } 54 | 55 | /** 56 | * @param ContainerInterface $container 57 | * @param string $requestedName 58 | * @param array|null $options 59 | * @return ControllerGuard 60 | */ 61 | public function __invoke(ContainerInterface $container, $requestedName, array $options = null) 62 | { 63 | if (null === $options) { 64 | $options = []; 65 | } 66 | 67 | /* @var \ZfcRbac\Options\ModuleOptions $moduleOptions */ 68 | $moduleOptions = $container->get('ZfcRbac\Options\ModuleOptions'); 69 | 70 | /* @var \ZfcRbac\Service\RoleService $roleService */ 71 | $roleService = $container->get('ZfcRbac\Service\RoleService'); 72 | 73 | $controllerGuard = new ControllerGuard($roleService, $options); 74 | $controllerGuard->setProtectionPolicy($moduleOptions->getProtectionPolicy()); 75 | 76 | return $controllerGuard; 77 | } 78 | 79 | 80 | /** 81 | * {@inheritDoc} 82 | * @return ControllerGuard 83 | */ 84 | public function createService(ServiceLocatorInterface $serviceLocator) 85 | { 86 | return $this($serviceLocator->getServiceLocator(), ControllerGuard::class, $this->options); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/ZfcRbac/Factory/ControllerPermissionsGuardFactory.php: -------------------------------------------------------------------------------- 1 | 30 | * @license MIT 31 | */ 32 | class ControllerPermissionsGuardFactory implements FactoryInterface 33 | { 34 | /** 35 | * @var array 36 | */ 37 | protected $options = []; 38 | 39 | /** 40 | * {@inheritDoc} 41 | */ 42 | public function __construct(array $options = []) 43 | { 44 | $this->setCreationOptions($options); 45 | } 46 | 47 | /** 48 | * {@inheritDoc} 49 | */ 50 | public function setCreationOptions(array $options) 51 | { 52 | $this->options = $options; 53 | } 54 | 55 | /** 56 | * @param ContainerInterface $container 57 | * @param string $resolvedName 58 | * @param array|null $options 59 | * @return ControllerPermissionsGuard 60 | */ 61 | public function __invoke(ContainerInterface $container, $resolvedName, array $options = null) 62 | { 63 | if (null === $options) { 64 | $options = []; 65 | } 66 | 67 | /* @var \ZfcRbac\Options\ModuleOptions $moduleOptions */ 68 | $moduleOptions = $container->get('ZfcRbac\Options\ModuleOptions'); 69 | 70 | /* @var \ZfcRbac\Service\AuthorizationService $authorizationService */ 71 | $authorizationService = $container->get('ZfcRbac\Service\AuthorizationService'); 72 | 73 | $guard = new ControllerPermissionsGuard($authorizationService, $options); 74 | $guard->setProtectionPolicy($moduleOptions->getProtectionPolicy()); 75 | 76 | return $guard; 77 | } 78 | 79 | /** 80 | * @param \Zend\ServiceManager\AbstractPluginManager|ServiceLocatorInterface $serviceLocator 81 | * @return ControllerPermissionsGuard 82 | */ 83 | public function createService(ServiceLocatorInterface $serviceLocator) 84 | { 85 | return $this($serviceLocator->getServiceLocator(), ControllerPermissionsGuard::class, $this->options); 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/ZfcRbac/Factory/GuardPluginManagerFactory.php: -------------------------------------------------------------------------------- 1 | 31 | * @license MIT 32 | */ 33 | class GuardPluginManagerFactory implements FactoryInterface 34 | { 35 | /** 36 | * @param ContainerInterface $container 37 | * @param string $requestedName 38 | * @param array|null $options 39 | * @return GuardPluginManager 40 | */ 41 | public function __invoke(ContainerInterface $container, $requestedName, array $options = null) 42 | { 43 | $config = $container->get('Config')['zfc_rbac']['guard_manager']; 44 | 45 | $pluginManager = new GuardPluginManager($container, $config); 46 | 47 | return $pluginManager; 48 | } 49 | 50 | /** 51 | * {@inheritDoc} 52 | * @return GuardPluginManager 53 | */ 54 | public function createService(ServiceLocatorInterface $serviceLocator) 55 | { 56 | return $this($serviceLocator, GuardPluginManager::class); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/ZfcRbac/Factory/GuardsFactory.php: -------------------------------------------------------------------------------- 1 | 30 | * @license MIT 31 | */ 32 | class GuardsFactory implements FactoryInterface 33 | { 34 | /** 35 | * @param ContainerInterface $container 36 | * @param string $requestedName 37 | * @param array|null $options 38 | * @return array 39 | */ 40 | public function __invoke(ContainerInterface $container, $requestedName, array $options = null) 41 | { 42 | /* @var \ZfcRbac\Options\ModuleOptions $options */ 43 | $options = $container->get('ZfcRbac\Options\ModuleOptions'); 44 | $guardsOptions = $options->getGuards(); 45 | 46 | if (empty($guardsOptions)) { 47 | return []; 48 | } 49 | 50 | /* @var \ZfcRbac\Guard\GuardPluginManager $pluginManager */ 51 | $pluginManager = $container->get('ZfcRbac\Guard\GuardPluginManager'); 52 | $guards = []; 53 | 54 | foreach ($guardsOptions as $type => $options) { 55 | $guards[] = $pluginManager->get($type, $options); 56 | } 57 | 58 | return $guards; 59 | } 60 | 61 | /** 62 | * {@inheritDoc} 63 | * @return \ZfcRbac\Guard\GuardInterface[]|array 64 | */ 65 | public function createService(ServiceLocatorInterface $serviceLocator) 66 | { 67 | return $this($serviceLocator, GuardInterface::class); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/ZfcRbac/Factory/HasRoleViewHelperFactory.php: -------------------------------------------------------------------------------- 1 | 31 | * @license MIT 32 | */ 33 | class HasRoleViewHelperFactory implements FactoryInterface 34 | { 35 | /** 36 | * @param ContainerInterface $container 37 | * @param string $requestedName 38 | * @param array|null $options 39 | * @return HasRole 40 | */ 41 | public function __invoke(ContainerInterface $container, $requestedName, array $options = null) 42 | { 43 | /* @var RoleService $roleService */ 44 | $roleService = $container->get('ZfcRbac\Service\RoleService'); 45 | 46 | return new HasRole($roleService); 47 | } 48 | 49 | /** 50 | * {@inheritDoc} 51 | * @return HasRole 52 | */ 53 | public function createService(ServiceLocatorInterface $serviceLocator) 54 | { 55 | return $this($serviceLocator->getServiceLocator(), HasRole::class); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/ZfcRbac/Factory/IsGrantedPluginFactory.php: -------------------------------------------------------------------------------- 1 | 30 | * @license MIT 31 | */ 32 | class IsGrantedPluginFactory implements FactoryInterface 33 | { 34 | /** 35 | * @param ContainerInterface $container 36 | * @param string $requestedName 37 | * @param array|null $options 38 | * @return IsGranted 39 | */ 40 | public function __invoke(ContainerInterface $container, $requestedName, array $options = null) 41 | { 42 | /* @var \ZfcRbac\Service\AuthorizationService $authorizationService */ 43 | $authorizationService = $container->get('ZfcRbac\Service\AuthorizationService'); 44 | 45 | return new IsGranted($authorizationService); 46 | } 47 | 48 | /** 49 | * {@inheritDoc} 50 | * @return IsGranted 51 | */ 52 | public function createService(ServiceLocatorInterface $serviceLocator) 53 | { 54 | return $this($serviceLocator->getServiceLocator(), IsGranted::class); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/ZfcRbac/Factory/IsGrantedViewHelperFactory.php: -------------------------------------------------------------------------------- 1 | 30 | * @license MIT 31 | */ 32 | class IsGrantedViewHelperFactory implements FactoryInterface 33 | { 34 | /** 35 | * @param ContainerInterface $container 36 | * @param string $requestedName 37 | * @param array|null $options 38 | * @return IsGranted 39 | */ 40 | public function __invoke(ContainerInterface $container, $requestedName, array $options = null) 41 | { 42 | /* @var \ZfcRbac\Service\AuthorizationService $authorizationService */ 43 | $authorizationService = $container->get('ZfcRbac\Service\AuthorizationService'); 44 | 45 | return new IsGranted($authorizationService); 46 | } 47 | 48 | /** 49 | * {@inheritDoc} 50 | * @return IsGranted 51 | */ 52 | public function createService(ServiceLocatorInterface $serviceLocator) 53 | { 54 | return $this($serviceLocator->getServiceLocator(), IsGranted::class); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/ZfcRbac/Factory/ModuleOptionsFactory.php: -------------------------------------------------------------------------------- 1 | 30 | * @license MIT 31 | */ 32 | class ModuleOptionsFactory implements FactoryInterface 33 | { 34 | /** 35 | * @param ContainerInterface $container 36 | * @param string $requestedName 37 | * @param array|null $options 38 | * @return ModuleOptions 39 | */ 40 | public function __invoke(ContainerInterface $container, $requestedName, array $options = null) 41 | { 42 | return new ModuleOptions($container->get('Config')['zfc_rbac']); 43 | } 44 | 45 | /** 46 | * {@inheritDoc} 47 | * @return ModuleOptions 48 | */ 49 | public function createService(ServiceLocatorInterface $serviceLocator) 50 | { 51 | return $this($serviceLocator, ModuleOptions::class); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/ZfcRbac/Factory/RbacFactory.php: -------------------------------------------------------------------------------- 1 | 29 | * @license MIT 30 | */ 31 | class RbacFactory implements FactoryInterface 32 | { 33 | /** 34 | * @param ContainerInterface $container 35 | * @param string $requestedName 36 | * @param array|null $options 37 | * @return Rbac 38 | */ 39 | public function __invoke(ContainerInterface $container, $requestedName, array $options = null) 40 | { 41 | return new Rbac(new GeneratorStrategy()); 42 | } 43 | 44 | /** 45 | * {@inheritDoc} 46 | */ 47 | public function createService(ServiceLocatorInterface $serviceLocator) 48 | { 49 | return $this($serviceLocator, Rbac::class); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/ZfcRbac/Factory/RedirectStrategyFactory.php: -------------------------------------------------------------------------------- 1 | 30 | * @license MIT 31 | */ 32 | class RedirectStrategyFactory implements FactoryInterface 33 | { 34 | /** 35 | * @param ContainerInterface $container 36 | * @param string $requestedName 37 | * @param array|null $options 38 | * @return RedirectStrategy 39 | */ 40 | public function __invoke(ContainerInterface $container, $requestedName, array $options = null) 41 | { 42 | /* @var \ZfcRbac\Options\ModuleOptions $moduleOptions */ 43 | $moduleOptions = $container->get('ZfcRbac\Options\ModuleOptions'); 44 | /** @var \Zend\Authentication\AuthenticationService $authenticationService */ 45 | $authenticationService = $container->get('Zend\Authentication\AuthenticationService'); 46 | 47 | return new RedirectStrategy($moduleOptions->getRedirectStrategy(), $authenticationService); 48 | } 49 | 50 | /** 51 | * {@inheritDoc} 52 | */ 53 | public function createService(ServiceLocatorInterface $serviceLocator) 54 | { 55 | return $this($serviceLocator, RedirectStrategy::class); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/ZfcRbac/Factory/RoleProviderPluginManagerFactory.php: -------------------------------------------------------------------------------- 1 | 30 | * @license MIT 31 | */ 32 | class RoleProviderPluginManagerFactory implements FactoryInterface 33 | { 34 | /** 35 | * @param ContainerInterface $container 36 | * @param string $requestedName 37 | * @param array|null $options 38 | * @return RoleProviderPluginManager 39 | */ 40 | public function __invoke(ContainerInterface $container, $requestedName, array $options = null) 41 | { 42 | $config = $container->get('Config')['zfc_rbac']['role_provider_manager']; 43 | 44 | return new RoleProviderPluginManager($container, $config); 45 | } 46 | 47 | /** 48 | * {@inheritDoc} 49 | * @return RoleProviderPluginManager 50 | */ 51 | public function createService(ServiceLocatorInterface $serviceLocator) 52 | { 53 | return $this($serviceLocator, RoleProviderPluginManager::class); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/ZfcRbac/Factory/RoleServiceFactory.php: -------------------------------------------------------------------------------- 1 | 31 | * @license MIT 32 | */ 33 | class RoleServiceFactory implements FactoryInterface 34 | { 35 | /** 36 | * @param ContainerInterface $container 37 | * @param string $requestedName 38 | * @param array|null $options 39 | * @return RoleService 40 | */ 41 | public function __invoke(ContainerInterface $container, $requestedName, array $options = null) 42 | { 43 | /* @var \ZfcRbac\Options\ModuleOptions $moduleOptions */ 44 | $moduleOptions = $container->get('ZfcRbac\Options\ModuleOptions'); 45 | 46 | /* @var \ZfcRbac\Identity\IdentityProviderInterface $identityProvider */ 47 | $identityProvider = $container->get($moduleOptions->getIdentityProvider()); 48 | 49 | $roleProviderConfig = $moduleOptions->getRoleProvider(); 50 | 51 | if (empty($roleProviderConfig)) { 52 | throw new RuntimeException('No role provider has been set for ZfcRbac'); 53 | } 54 | 55 | /* @var \ZfcRbac\Role\RoleProviderPluginManager $pluginManager */ 56 | $pluginManager = $container->get('ZfcRbac\Role\RoleProviderPluginManager'); 57 | 58 | /* @var \ZfcRbac\Role\RoleProviderInterface $roleProvider */ 59 | reset($roleProviderConfig); 60 | $roleProvider = $pluginManager->get(key($roleProviderConfig), current($roleProviderConfig)); 61 | 62 | /* @var \Rbac\Traversal\Strategy\TraversalStrategyInterface $traversalStrategy */ 63 | $traversalStrategy = $container->get('Rbac\Rbac')->getTraversalStrategy(); 64 | 65 | $roleService = new RoleService($identityProvider, $roleProvider, $traversalStrategy); 66 | $roleService->setGuestRole($moduleOptions->getGuestRole()); 67 | 68 | return $roleService; 69 | } 70 | 71 | /** 72 | * {@inheritDoc} 73 | * @return RoleService 74 | */ 75 | public function createService(ServiceLocatorInterface $serviceLocator) 76 | { 77 | return $this($serviceLocator, RoleService::class); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/ZfcRbac/Factory/RouteGuardFactory.php: -------------------------------------------------------------------------------- 1 | 30 | * @license MIT 31 | */ 32 | class RouteGuardFactory implements FactoryInterface 33 | { 34 | /** 35 | * @var array 36 | */ 37 | protected $options = []; 38 | 39 | /** 40 | * {@inheritDoc} 41 | */ 42 | public function __construct(array $options = []) 43 | { 44 | $this->setCreationOptions($options); 45 | } 46 | 47 | /** 48 | * {@inheritDoc} 49 | */ 50 | public function setCreationOptions(array $options) 51 | { 52 | $this->options = $options; 53 | } 54 | 55 | /** 56 | * @param ContainerInterface $container 57 | * @param string $requestedName 58 | * @param array|null $options 59 | * @return RouteGuard 60 | */ 61 | public function __invoke(ContainerInterface $container, $requestedName, array $options = null) 62 | { 63 | if (null === $options) { 64 | $options = []; 65 | } 66 | 67 | /* @var \ZfcRbac\Options\ModuleOptions $moduleOptions */ 68 | $moduleOptions = $container->get('ZfcRbac\Options\ModuleOptions'); 69 | 70 | /* @var \ZfcRbac\Service\RoleService $roleService */ 71 | $roleService = $container->get('ZfcRbac\Service\RoleService'); 72 | 73 | $routeGuard = new RouteGuard($roleService, $options); 74 | $routeGuard->setProtectionPolicy($moduleOptions->getProtectionPolicy()); 75 | 76 | return $routeGuard; 77 | } 78 | 79 | 80 | /** 81 | * {@inheritDoc} 82 | * @return RouteGuard 83 | */ 84 | public function createService(ServiceLocatorInterface $serviceLocator) 85 | { 86 | return $this($serviceLocator->getServiceLocator(), RouteGuard::class, $this->options); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/ZfcRbac/Factory/RoutePermissionsGuardFactory.php: -------------------------------------------------------------------------------- 1 | 31 | * @author JM Lerouxw 32 | * @license MIT 33 | */ 34 | class RoutePermissionsGuardFactory implements FactoryInterface 35 | { 36 | /** 37 | * @var array 38 | */ 39 | protected $options = []; 40 | 41 | /** 42 | * {@inheritDoc} 43 | */ 44 | public function __construct(array $options = []) 45 | { 46 | $this->setCreationOptions($options); 47 | } 48 | 49 | /** 50 | * {@inheritDoc} 51 | */ 52 | public function setCreationOptions(array $options) 53 | { 54 | $this->options = $options; 55 | } 56 | 57 | /** 58 | * @param ContainerInterface $container 59 | * @param string $requestedName 60 | * @param array|null $options 61 | * @return RoutePermissionsGuard 62 | */ 63 | public function __invoke(ContainerInterface $container, $requestedName, array $options = null) 64 | { 65 | if (null === $options) { 66 | $options = []; 67 | } 68 | 69 | /* @var \ZfcRbac\Options\ModuleOptions $moduleOptions */ 70 | $moduleOptions = $container->get('ZfcRbac\Options\ModuleOptions'); 71 | 72 | /* @var \ZfcRbac\Service\AuthorizationService $authorizationService */ 73 | $authorizationService = $container->get('ZfcRbac\Service\AuthorizationService'); 74 | 75 | $routeGuard = new RoutePermissionsGuard($authorizationService, $options); 76 | $routeGuard->setProtectionPolicy($moduleOptions->getProtectionPolicy()); 77 | 78 | return $routeGuard; 79 | } 80 | 81 | /** 82 | * @param \Zend\ServiceManager\AbstractPluginManager|ServiceLocatorInterface $serviceLocator 83 | * @return RouteGuard 84 | */ 85 | public function createService(ServiceLocatorInterface $serviceLocator) 86 | { 87 | return $this($serviceLocator->getServiceLocator(), RoutePermissionsGuard::class, $this->options); 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/ZfcRbac/Factory/UnauthorizedStrategyFactory.php: -------------------------------------------------------------------------------- 1 | 30 | * @license MIT 31 | */ 32 | class UnauthorizedStrategyFactory implements FactoryInterface 33 | { 34 | /** 35 | * @param ContainerInterface $container 36 | * @param string $requestedName 37 | * @param array|null $options 38 | * @return UnauthorizedStrategy 39 | */ 40 | public function __invoke(ContainerInterface $container, $requestedName, array $options = null) 41 | { 42 | /* @var \ZfcRbac\Options\ModuleOptions $moduleOptions */ 43 | $moduleOptions = $container->get('ZfcRbac\Options\ModuleOptions'); 44 | 45 | return new UnauthorizedStrategy($moduleOptions->getUnauthorizedStrategy()); 46 | } 47 | 48 | /** 49 | * {@inheritDoc} 50 | */ 51 | public function createService(ServiceLocatorInterface $serviceLocator) 52 | { 53 | return $this($serviceLocator, UnauthorizedStrategy::class); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/ZfcRbac/Guard/AbstractGuard.php: -------------------------------------------------------------------------------- 1 | 30 | * @license MIT 31 | */ 32 | abstract class AbstractGuard implements GuardInterface 33 | { 34 | use ListenerAggregateTrait; 35 | 36 | /** 37 | * Event priority 38 | */ 39 | const EVENT_PRIORITY = -5; 40 | 41 | /** 42 | * MVC event to listen 43 | */ 44 | const EVENT_NAME = MvcEvent::EVENT_ROUTE; 45 | 46 | /** 47 | * {@inheritDoc} 48 | */ 49 | public function attach(EventManagerInterface $events, $priority = AbstractGuard::EVENT_PRIORITY) 50 | { 51 | $this->listeners[] = $events->attach(static::EVENT_NAME, [$this, 'onResult'], $priority); 52 | } 53 | 54 | /** 55 | * @private 56 | * @param MvcEvent $event 57 | * @return void 58 | */ 59 | public function onResult(MvcEvent $event) 60 | { 61 | if ($this->isGranted($event)) { 62 | return; 63 | } 64 | 65 | $event->setError(self::GUARD_UNAUTHORIZED); 66 | $event->setParam('exception', new Exception\UnauthorizedException( 67 | 'You are not authorized to access this resource', 68 | 403 69 | )); 70 | 71 | $application = $event->getApplication(); 72 | $eventManager = $application->getEventManager(); 73 | 74 | $event->setName(MvcEvent::EVENT_DISPATCH_ERROR); 75 | $eventManager->triggerEvent($event); 76 | 77 | // just in case 78 | $event->stopPropagation(true); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/ZfcRbac/Guard/GuardInterface.php: -------------------------------------------------------------------------------- 1 | 35 | * @license MIT 36 | */ 37 | interface GuardInterface extends ListenerAggregateInterface 38 | { 39 | /** 40 | * Constant for guard that can be added to the MVC event result 41 | */ 42 | const GUARD_UNAUTHORIZED = 'guard-unauthorized'; 43 | 44 | /** 45 | * Protection policy constants 46 | */ 47 | const POLICY_DENY = 'deny'; 48 | const POLICY_ALLOW = 'allow'; 49 | 50 | /** 51 | * Condition constants 52 | */ 53 | const CONDITION_OR = 'OR'; 54 | const CONDITION_AND = 'AND'; 55 | 56 | /** 57 | * @param MvcEvent $event 58 | * @return bool 59 | */ 60 | public function isGranted(MvcEvent $event); 61 | } 62 | -------------------------------------------------------------------------------- /src/ZfcRbac/Guard/GuardPluginManager.php: -------------------------------------------------------------------------------- 1 | 30 | * @author JM Leroux 31 | * @license MIT 32 | */ 33 | class GuardPluginManager extends AbstractPluginManager 34 | { 35 | /** 36 | * @var array 37 | */ 38 | protected $factories = [ 39 | 'ZfcRbac\Guard\ControllerGuard' => 'ZfcRbac\Factory\ControllerGuardFactory', 40 | 'ZfcRbac\Guard\ControllerPermissionsGuard' => 'ZfcRbac\Factory\ControllerPermissionsGuardFactory', 41 | 'ZfcRbac\Guard\RouteGuard' => 'ZfcRbac\Factory\RouteGuardFactory', 42 | 'ZfcRbac\Guard\RoutePermissionsGuard' => 'ZfcRbac\Factory\RoutePermissionsGuardFactory', 43 | ]; 44 | 45 | /** 46 | * {@inheritDoc} 47 | */ 48 | public function validate($plugin) 49 | { 50 | if ($plugin instanceof GuardInterface) { 51 | return; // we're okay 52 | } 53 | 54 | throw new Exception\RuntimeException(sprintf( 55 | 'Guards must implement "ZfcRbac\Guard\GuardInterface", but "%s" was given', 56 | is_object($plugin) ? get_class($plugin) : gettype($plugin) 57 | )); 58 | } 59 | 60 | /** 61 | * {@inheritDoc} 62 | */ 63 | public function validatePlugin($plugin) 64 | { 65 | $this->validate($plugin); 66 | } 67 | 68 | /** 69 | * {@inheritDoc} 70 | */ 71 | protected function canonicalizeName($name) 72 | { 73 | return $name; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/ZfcRbac/Guard/ProtectionPolicyTrait.php: -------------------------------------------------------------------------------- 1 | 25 | * @license MIT 26 | */ 27 | trait ProtectionPolicyTrait 28 | { 29 | /** 30 | * @var string 31 | */ 32 | protected $protectionPolicy = GuardInterface::POLICY_DENY; 33 | 34 | /** 35 | * Set the protection policy 36 | * 37 | * @param string $protectionPolicy 38 | * @return void 39 | */ 40 | public function setProtectionPolicy($protectionPolicy) 41 | { 42 | $this->protectionPolicy = (string) $protectionPolicy; 43 | } 44 | 45 | /** 46 | * Get the protection policy 47 | * 48 | * @return string 49 | */ 50 | public function getProtectionPolicy() 51 | { 52 | return $this->protectionPolicy; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/ZfcRbac/Identity/AuthenticationIdentityProvider.php: -------------------------------------------------------------------------------- 1 | 27 | * @license MIT 28 | */ 29 | class AuthenticationIdentityProvider implements IdentityProviderInterface 30 | { 31 | /** 32 | * @var AuthenticationServiceInterface 33 | */ 34 | protected $authenticationService; 35 | 36 | /** 37 | * Constructor 38 | * 39 | * @param AuthenticationServiceInterface $authenticationService 40 | */ 41 | public function __construct(AuthenticationServiceInterface $authenticationService) 42 | { 43 | $this->authenticationService = $authenticationService; 44 | } 45 | 46 | /** 47 | * {@inheritDoc} 48 | */ 49 | public function getIdentity() 50 | { 51 | return $this->authenticationService->getIdentity(); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/ZfcRbac/Identity/IdentityInterface.php: -------------------------------------------------------------------------------- 1 | 25 | * @license MIT 26 | */ 27 | interface IdentityInterface 28 | { 29 | /** 30 | * Get the list of roles of this identity 31 | * 32 | * @return string[]|\Rbac\Role\RoleInterface[] 33 | */ 34 | public function getRoles(); 35 | } 36 | -------------------------------------------------------------------------------- /src/ZfcRbac/Identity/IdentityProviderInterface.php: -------------------------------------------------------------------------------- 1 | 25 | * @license MIT 26 | */ 27 | interface IdentityProviderInterface 28 | { 29 | /** 30 | * Get the identity 31 | * 32 | * @return IdentityInterface|null 33 | */ 34 | public function getIdentity(); 35 | } 36 | -------------------------------------------------------------------------------- /src/ZfcRbac/Initializer/AuthorizationServiceInitializer.php: -------------------------------------------------------------------------------- 1 | get('ZfcRbac\Service\AuthorizationService'); 43 | $instance->setAuthorizationService($authorizationService); 44 | } 45 | } 46 | 47 | /** 48 | * @see \Zend\ServiceManager\InitializerInterface::initialize() 49 | */ 50 | public function initialize($instance, ServiceLocatorInterface $serviceLocator) 51 | { 52 | if ($serviceLocator instanceof AbstractPluginManager) { 53 | $serviceLocator = $serviceLocator->getServiceLocator(); 54 | } 55 | 56 | $this($serviceLocator, $instance); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/ZfcRbac/Module.php: -------------------------------------------------------------------------------- 1 | 29 | * @license MIT 30 | */ 31 | class Module implements BootstrapListenerInterface, ConfigProviderInterface 32 | { 33 | /** 34 | * {@inheritDoc} 35 | */ 36 | public function onBootstrap(EventInterface $event) 37 | { 38 | /* @var \Zend\Mvc\Application $application */ 39 | $application = $event->getTarget(); 40 | $serviceManager = $application->getServiceManager(); 41 | $eventManager = $application->getEventManager(); 42 | 43 | /* @var \ZfcRbac\Guard\GuardInterface[]|array $guards */ 44 | $guards = $serviceManager->get('ZfcRbac\Guards'); 45 | 46 | // Register listeners, if any 47 | foreach ($guards as $guard) { 48 | $guard->attach($eventManager); 49 | } 50 | } 51 | 52 | /** 53 | * {@inheritDoc} 54 | */ 55 | public function getConfig() 56 | { 57 | return include __DIR__ . '/../../config/module.config.php'; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/ZfcRbac/Mvc/Controller/Plugin/IsGranted.php: -------------------------------------------------------------------------------- 1 | 28 | * @license MIT 29 | */ 30 | class IsGranted extends AbstractPlugin 31 | { 32 | /** 33 | * @var AuthorizationServiceInterface 34 | */ 35 | private $authorizationService; 36 | 37 | /** 38 | * Constructor 39 | * 40 | * @param AuthorizationServiceInterface $authorizationService 41 | */ 42 | public function __construct(AuthorizationServiceInterface $authorizationService) 43 | { 44 | $this->authorizationService = $authorizationService; 45 | } 46 | 47 | /** 48 | * Check against the given permission 49 | * 50 | * @param string $permission 51 | * @param mixed $context 52 | * @return bool 53 | */ 54 | public function __invoke($permission, $context = null) 55 | { 56 | return $this->authorizationService->isGranted($permission, $context); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/ZfcRbac/Options/UnauthorizedStrategyOptions.php: -------------------------------------------------------------------------------- 1 | 27 | * @license MIT 28 | */ 29 | class UnauthorizedStrategyOptions extends AbstractOptions 30 | { 31 | /** 32 | * Template to use 33 | * 34 | * @var string 35 | */ 36 | protected $template = 'error/403'; 37 | 38 | /** 39 | * @param string $template 40 | */ 41 | public function setTemplate($template) 42 | { 43 | $this->template = (string) $template; 44 | } 45 | 46 | /** 47 | * @return string 48 | */ 49 | public function getTemplate() 50 | { 51 | return $this->template; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/ZfcRbac/Permission/PermissionInterface.php: -------------------------------------------------------------------------------- 1 | 30 | * @license MIT 31 | */ 32 | interface PermissionInterface extends BasePermissionInterface 33 | { 34 | } 35 | -------------------------------------------------------------------------------- /src/ZfcRbac/Role/ObjectRepositoryRoleProvider.php: -------------------------------------------------------------------------------- 1 | 28 | * @license MIT 29 | */ 30 | class ObjectRepositoryRoleProvider implements RoleProviderInterface 31 | { 32 | /** 33 | * @var ObjectRepository 34 | */ 35 | private $objectRepository; 36 | 37 | /** 38 | * @var string 39 | */ 40 | private $roleNameProperty; 41 | 42 | /** 43 | * @var array 44 | */ 45 | private $roleCache = []; 46 | 47 | /** 48 | * Constructor 49 | * 50 | * @param ObjectRepository $objectRepository 51 | * @param string $roleNameProperty 52 | */ 53 | public function __construct(ObjectRepository $objectRepository, $roleNameProperty) 54 | { 55 | $this->objectRepository = $objectRepository; 56 | $this->roleNameProperty = $roleNameProperty; 57 | } 58 | 59 | /** 60 | * Clears the role cache 61 | * 62 | * @return void 63 | */ 64 | public function clearRoleCache() 65 | { 66 | $this->roleCache = []; 67 | } 68 | 69 | /** 70 | * {@inheritDoc} 71 | */ 72 | public function getRoles(array $roleNames) 73 | { 74 | $key = implode($roleNames); 75 | 76 | if (isset($this->roleCache[$key])) { 77 | return $this->roleCache[$key]; 78 | } 79 | 80 | $roles = $this->objectRepository->findBy([$this->roleNameProperty => $roleNames]); 81 | 82 | // We allow more roles to be loaded than asked (although this should not happen because 83 | // role name should have a UNIQUE constraint in database... but just in case ;)) 84 | if (count($roles) >= count($roleNames)) { 85 | $this->roleCache[$key] = $roles; 86 | 87 | return $roles; 88 | } 89 | 90 | // We have roles that were asked but couldn't be found in database... problem! 91 | foreach ($roles as &$role) { 92 | $role = $role->getName(); 93 | } 94 | 95 | throw new RoleNotFoundException(sprintf( 96 | 'Some roles were asked but could not be loaded from database: %s', 97 | implode(', ', array_diff($roleNames, $roles)) 98 | )); 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /src/ZfcRbac/Role/RoleProviderInterface.php: -------------------------------------------------------------------------------- 1 | 28 | * @license MIT 29 | */ 30 | interface RoleProviderInterface 31 | { 32 | /** 33 | * Get the roles from the provider 34 | * 35 | * @param string[] $roleNames 36 | * @return \Rbac\Role\RoleInterface[] 37 | */ 38 | public function getRoles(array $roleNames); 39 | } 40 | -------------------------------------------------------------------------------- /src/ZfcRbac/Role/RoleProviderPluginManager.php: -------------------------------------------------------------------------------- 1 | 30 | * @license MIT 31 | */ 32 | class RoleProviderPluginManager extends AbstractPluginManager 33 | { 34 | /** 35 | * @var array 36 | */ 37 | protected $invokableClasses = [ 38 | 'ZfcRbac\Role\InMemoryRoleProvider' => 'ZfcRbac\Role\InMemoryRoleProvider' 39 | ]; 40 | 41 | /** 42 | * @var array 43 | */ 44 | protected $factories = [ 45 | 'ZfcRbac\Role\ObjectRepositoryRoleProvider' => 'ZfcRbac\Factory\ObjectRepositoryRoleProviderFactory' 46 | ]; 47 | 48 | /** 49 | * {@inheritDoc} 50 | */ 51 | public function validate($plugin) 52 | { 53 | if ($plugin instanceof RoleProviderInterface) { 54 | return; // we're okay 55 | } 56 | 57 | throw new Exception\RuntimeException(sprintf( 58 | 'Role provider must implement "ZfcRbac\Role\RoleProviderInterface", but "%s" was given', 59 | is_object($plugin) ? get_class($plugin) : gettype($plugin) 60 | )); 61 | } 62 | 63 | /** 64 | * {@inheritDoc} 65 | */ 66 | public function validatePlugin($plugin) 67 | { 68 | $this->validate($plugin); 69 | } 70 | 71 | /** 72 | * {@inheritDoc} 73 | */ 74 | protected function canonicalizeName($name) 75 | { 76 | return $name; 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/ZfcRbac/Service/AuthorizationServiceAwareInterface.php: -------------------------------------------------------------------------------- 1 | authorizationService = $authorizationService; 47 | } 48 | 49 | /** 50 | * Return the AuthorizationService 51 | * 52 | * @return AuthorizationService 53 | */ 54 | public function getAuthorizationService() 55 | { 56 | return $this->authorizationService; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/ZfcRbac/Service/AuthorizationServiceInterface.php: -------------------------------------------------------------------------------- 1 | 27 | * @license MIT 28 | */ 29 | interface AuthorizationServiceInterface 30 | { 31 | /** 32 | * Check if the permission is granted to the current identity 33 | * 34 | * @param string|PermissionInterface $permission 35 | * @param mixed $context 36 | * @return bool 37 | */ 38 | public function isGranted($permission, $context = null); 39 | } 40 | -------------------------------------------------------------------------------- /src/ZfcRbac/View/Helper/HasRole.php: -------------------------------------------------------------------------------- 1 | 28 | * @license MIT 29 | */ 30 | class HasRole extends AbstractHelper 31 | { 32 | /** 33 | * @var RoleService 34 | */ 35 | private $roleService; 36 | 37 | /** 38 | * Constructor 39 | * 40 | * @param RoleService $roleService 41 | */ 42 | public function __construct(RoleService $roleService) 43 | { 44 | $this->roleService = $roleService; 45 | } 46 | 47 | /** 48 | * @param string|string[] $roleOrRoles 49 | * @return bool 50 | */ 51 | public function __invoke($roleOrRoles) 52 | { 53 | return $this->roleService->matchIdentityRoles((array)$roleOrRoles); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/ZfcRbac/View/Helper/IsGranted.php: -------------------------------------------------------------------------------- 1 | 28 | * @license MIT 29 | */ 30 | class IsGranted extends AbstractHelper 31 | { 32 | /** 33 | * @var AuthorizationServiceInterface 34 | */ 35 | private $authorizationService; 36 | 37 | /** 38 | * Constructor 39 | * 40 | * @param AuthorizationServiceInterface $authorizationService 41 | */ 42 | public function __construct(AuthorizationServiceInterface $authorizationService) 43 | { 44 | $this->authorizationService = $authorizationService; 45 | } 46 | 47 | /** 48 | * Check against the given permission 49 | * 50 | * @param string $permission 51 | * @param mixed $context 52 | * @return bool 53 | */ 54 | public function __invoke($permission, $context = null) 55 | { 56 | return $this->authorizationService->isGranted($permission, $context); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/ZfcRbac/View/Strategy/AbstractStrategy.php: -------------------------------------------------------------------------------- 1 | 29 | * @license MIT 30 | */ 31 | abstract class AbstractStrategy extends AbstractListenerAggregate 32 | { 33 | /** 34 | * {@inheritDoc} 35 | */ 36 | public function attach(EventManagerInterface $events, $priority = 1) 37 | { 38 | $this->listeners[] = $events->attach(MvcEvent::EVENT_DISPATCH_ERROR, [$this, 'onError'], $priority); 39 | } 40 | 41 | /** 42 | * @private 43 | * @param MvcEvent $event 44 | * @return void 45 | */ 46 | abstract public function onError(MvcEvent $event); 47 | } 48 | -------------------------------------------------------------------------------- /src/ZfcRbac/View/Strategy/UnauthorizedStrategy.php: -------------------------------------------------------------------------------- 1 | 32 | * @license MIT 33 | */ 34 | class UnauthorizedStrategy extends AbstractStrategy 35 | { 36 | /** 37 | * @var UnauthorizedStrategyOptions 38 | */ 39 | protected $options; 40 | 41 | /** 42 | * Constructor 43 | * 44 | * @param UnauthorizedStrategyOptions $options 45 | */ 46 | public function __construct(UnauthorizedStrategyOptions $options) 47 | { 48 | $this->options = $options; 49 | } 50 | 51 | /** 52 | * @private 53 | * @param MvcEvent $event 54 | * @return void 55 | */ 56 | public function onError(MvcEvent $event) 57 | { 58 | // Do nothing if no error or if response is not HTTP response 59 | if (!($event->getParam('exception') instanceof UnauthorizedExceptionInterface) 60 | || ($event->getResult() instanceof HttpResponse) 61 | || !($event->getResponse() instanceof HttpResponse) 62 | ) { 63 | return; 64 | } 65 | 66 | $model = new ViewModel(); 67 | $model->setTemplate($this->options->getTemplate()); 68 | 69 | switch ($event->getError()) { 70 | case GuardInterface::GUARD_UNAUTHORIZED: 71 | $model->setVariable('error', GuardInterface::GUARD_UNAUTHORIZED); 72 | break; 73 | 74 | default: 75 | } 76 | 77 | $response = $event->getResponse() ?: new HttpResponse(); 78 | $response->setStatusCode(403); 79 | 80 | $event->setResponse($response); 81 | $event->setResult($model); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /tests/Bootstrap.php: -------------------------------------------------------------------------------- 1 | add('ZfcRbacTest\\', __DIR__); 42 | 43 | $r = new \ReflectionClass(Application::class); 44 | $requiredParams = $r->getConstructor()->getNumberOfRequiredParameters(); 45 | $version = $requiredParams == 1 ? 3 : 2; 46 | 47 | $configFiles = [ 48 | sprintf(__DIR__ . '/TestConfigurationV%s.php', $version), 49 | sprintf(__DIR__ . '/TestConfigurationV%s.php.dist', $version), 50 | ]; 51 | 52 | foreach ($configFiles as $configFile) { 53 | if (file_exists($configFile)) { 54 | $config = require $configFile; 55 | 56 | break; 57 | } 58 | } 59 | 60 | ServiceManagerFactory::setApplicationConfig($config); 61 | unset($files, $file, $loader, $configFiles, $configFile, $config); 62 | -------------------------------------------------------------------------------- /tests/TestConfigurationV2.php.dist: -------------------------------------------------------------------------------- 1 | [ 21 | 'ZfcRbac', 22 | 'DoctrineModule', 23 | 'DoctrineORMModule', 24 | ], 25 | 'module_listener_options' => [ 26 | 'config_glob_paths' => [ 27 | __DIR__ . '/testing.config.php', 28 | ], 29 | 'module_paths' => [ 30 | ], 31 | ], 32 | ]; 33 | -------------------------------------------------------------------------------- /tests/TestConfigurationV3.php.dist: -------------------------------------------------------------------------------- 1 | [ 21 | 'Zend\Router', 22 | 'ZfcRbac', 23 | 'DoctrineModule', 24 | 'DoctrineORMModule', 25 | ], 26 | 'module_listener_options' => [ 27 | 'config_glob_paths' => [ 28 | __DIR__ . '/testing.config.php', 29 | ], 30 | 'module_paths' => [ 31 | ], 32 | ], 33 | ]; 34 | -------------------------------------------------------------------------------- /tests/ZfcRbacTest/Asset/DummyGuard.php: -------------------------------------------------------------------------------- 1 | name = (string) $name; 61 | $this->permissions = new ArrayCollection(); 62 | } 63 | 64 | /** 65 | * Get the role identifier 66 | * 67 | * @return int 68 | */ 69 | public function getId() 70 | { 71 | return $this->id; 72 | } 73 | 74 | /** 75 | * Add a permission 76 | * 77 | * @param PermissionInterface|string $permission 78 | * @return void 79 | */ 80 | public function addPermission($permission) 81 | { 82 | if (is_string($permission)) { 83 | $name = $permission; 84 | $permission = new Permission($name); 85 | } 86 | 87 | $this->permissions[$permission->getName()] = $permission; 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /tests/ZfcRbacTest/Asset/HierarchicalRole.php: -------------------------------------------------------------------------------- 1 | name = (string) $name; 68 | $this->permissions = new ArrayCollection(); 69 | } 70 | 71 | /** 72 | * Get the role identifier 73 | * 74 | * @return int 75 | */ 76 | public function getId() 77 | { 78 | return $this->id; 79 | } 80 | 81 | /** 82 | * Add a permission 83 | * 84 | * @param PermissionInterface|string $permission 85 | * @return void 86 | */ 87 | public function addPermission($permission) 88 | { 89 | if (is_string($permission)) { 90 | $name = $permission; 91 | $permission = new Permission($name); 92 | } 93 | 94 | $this->permissions[$permission->getName()] = $permission; 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /tests/ZfcRbacTest/Asset/MockRoleWithPermissionMethod.php: -------------------------------------------------------------------------------- 1 | name = (string) $name; 53 | $this->roles = new ArrayCollection(); 54 | } 55 | 56 | /** 57 | * Get the permission identifier 58 | * 59 | * @return int 60 | */ 61 | public function getId() 62 | { 63 | return $this->id; 64 | } 65 | 66 | /** 67 | * Get the permission name 68 | * 69 | * @return string 70 | */ 71 | public function getName() 72 | { 73 | return $this->name; 74 | } 75 | 76 | /** 77 | * {@inheritDoc} 78 | */ 79 | public function __toString() 80 | { 81 | return $this->getName(); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /tests/ZfcRbacTest/Asset/SimpleAssertion.php: -------------------------------------------------------------------------------- 1 | called = true; 37 | 38 | return $context; 39 | } 40 | 41 | /** 42 | * @return bool 43 | */ 44 | public function getCalled() 45 | { 46 | return $this->called; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /tests/ZfcRbacTest/Factory/AssertionPluginManagerFactoryTest.php: -------------------------------------------------------------------------------- 1 | setService('Config', [ 33 | 'zfc_rbac' => [ 34 | 'assertion_manager' => [] 35 | ] 36 | ]); 37 | 38 | $factory = new AssertionPluginManagerFactory(); 39 | $pluginManager = $factory->createService($serviceManager); 40 | 41 | $this->assertInstanceOf('ZfcRbac\Assertion\AssertionPluginManager', $pluginManager); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /tests/ZfcRbacTest/Factory/AuthenticationIdentityProviderFactoryTest.php: -------------------------------------------------------------------------------- 1 | setService( 33 | 'Zend\Authentication\AuthenticationService', 34 | $this->getMock('Zend\Authentication\AuthenticationService') 35 | ); 36 | 37 | $factory = new AuthenticationIdentityProviderFactory(); 38 | $authenticationProvider = $factory->createService($serviceManager); 39 | 40 | $this->assertInstanceOf('ZfcRbac\Identity\AuthenticationIdentityProvider', $authenticationProvider); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /tests/ZfcRbacTest/Factory/AuthorizationServiceFactoryTest.php: -------------------------------------------------------------------------------- 1 | setService('Rbac\Rbac', $this->getMock('Rbac\Rbac', [], [], '', false)); 35 | 36 | $serviceManager->setService( 37 | 'ZfcRbac\Service\RoleService', 38 | $this->getMock('ZfcRbac\Service\RoleService', [], [], '', false) 39 | ); 40 | $serviceManager->setService( 41 | 'ZfcRbac\Assertion\AssertionPluginManager', 42 | $this->getMock('ZfcRbac\Assertion\AssertionPluginManager', [], [], '', false) 43 | ); 44 | $serviceManager->setService( 45 | 'ZfcRbac\Options\ModuleOptions', 46 | new ModuleOptions([]) 47 | ); 48 | 49 | $factory = new AuthorizationServiceFactory(); 50 | $authorizationService = $factory->createService($serviceManager); 51 | 52 | $this->assertInstanceOf('ZfcRbac\Service\AuthorizationService', $authorizationService); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /tests/ZfcRbacTest/Factory/GuardPluginManagerFactoryTest.php: -------------------------------------------------------------------------------- 1 | setService('Config', [ 34 | 'zfc_rbac' => [ 35 | 'guard_manager' => [] 36 | ] 37 | ]); 38 | 39 | $factory = new GuardPluginManagerFactory(); 40 | $pluginManager = $factory->createService($serviceManager); 41 | 42 | $this->assertInstanceOf(GuardPluginManager::class, $pluginManager); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /tests/ZfcRbacTest/Factory/HasRoleViewHelperFactoryTest.php: -------------------------------------------------------------------------------- 1 | markTestSkipped('this test is only vor zend-servicemanager v2'); 36 | } 37 | 38 | $pluginManager = new HelperPluginManager($serviceManager); 39 | 40 | $serviceManager->setService( 41 | 'ZfcRbac\Service\RoleService', 42 | $this->getMock('ZfcRbac\Service\RoleService', [], [], '', false) 43 | ); 44 | 45 | $factory = new HasRoleViewHelperFactory(); 46 | $viewHelper = $factory->createService($pluginManager); 47 | 48 | $this->assertInstanceOf('ZfcRbac\View\Helper\HasRole', $viewHelper); 49 | } 50 | 51 | public function testFactoryV3() 52 | { 53 | $serviceManager = new ServiceManager(); 54 | 55 | if (!method_exists($serviceManager, 'build')) { 56 | $this->markTestSkipped('this test is only vor zend-servicemanager v3'); 57 | } 58 | 59 | $serviceManager->setService( 60 | 'ZfcRbac\Service\RoleService', 61 | $this->getMock('ZfcRbac\Service\RoleService', [], [], '', false) 62 | ); 63 | 64 | $factory = new HasRoleViewHelperFactory(); 65 | $viewHelper = $factory($serviceManager, 'ZfcRbac\View\Helper\HasRole'); 66 | 67 | $this->assertInstanceOf('ZfcRbac\View\Helper\HasRole', $viewHelper); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /tests/ZfcRbacTest/Factory/IsGrantedPluginFactoryTest.php: -------------------------------------------------------------------------------- 1 | markTestSkipped('this test is only vor zend-servicemanager v2'); 36 | } 37 | 38 | $pluginManager = new PluginManager($serviceManager); 39 | 40 | $serviceManager->setService( 41 | 'ZfcRbac\Service\AuthorizationService', 42 | $this->getMock('ZfcRbac\Service\AuthorizationServiceInterface') 43 | ); 44 | 45 | $factory = new IsGrantedPluginFactory(); 46 | $isGranted = $factory->createService($pluginManager); 47 | 48 | $this->assertInstanceOf('ZfcRbac\Mvc\Controller\Plugin\IsGranted', $isGranted); 49 | } 50 | 51 | public function testFactoryV3() 52 | { 53 | $serviceManager = new ServiceManager(); 54 | 55 | if (! method_exists($serviceManager, 'build')) { 56 | $this->markTestSkipped('this test is only vor zend-servicemanager v3'); 57 | } 58 | $serviceManager->setService( 59 | 'ZfcRbac\Service\AuthorizationService', 60 | $this->getMock('ZfcRbac\Service\AuthorizationServiceInterface') 61 | ); 62 | 63 | $factory = new IsGrantedPluginFactory(); 64 | $isGranted = $factory($serviceManager, 'ZfcRbac\Mvc\Controller\Plugin\IsGranted'); 65 | 66 | $this->assertInstanceOf('ZfcRbac\Mvc\Controller\Plugin\IsGranted', $isGranted); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /tests/ZfcRbacTest/Factory/IsGrantedViewHelperFactoryTest.php: -------------------------------------------------------------------------------- 1 | markTestSkipped('this test is only vor zend-servicemanager v2'); 36 | } 37 | 38 | $pluginManager = new HelperPluginManager($serviceManager); 39 | 40 | $serviceManager->setService( 41 | 'ZfcRbac\Service\AuthorizationService', 42 | $this->getMock('ZfcRbac\Service\AuthorizationServiceInterface') 43 | ); 44 | 45 | $factory = new IsGrantedViewHelperFactory(); 46 | $isGranted = $factory->createService($pluginManager); 47 | 48 | $this->assertInstanceOf('ZfcRbac\View\Helper\IsGranted', $isGranted); 49 | } 50 | 51 | public function testFactoryV3() 52 | { 53 | $serviceManager = new ServiceManager(); 54 | 55 | if (! method_exists($serviceManager, 'build')) { 56 | $this->markTestSkipped('this test is only vor zend-servicemanager v3'); 57 | } 58 | $serviceManager->setService( 59 | 'ZfcRbac\Service\AuthorizationService', 60 | $this->getMock('ZfcRbac\Service\AuthorizationServiceInterface') 61 | ); 62 | 63 | $factory = new IsGrantedViewHelperFactory(); 64 | $isGranted = $factory($serviceManager, 'ZfcRbac\View\Helper\IsGranted'); 65 | 66 | $this->assertInstanceOf('ZfcRbac\View\Helper\IsGranted', $isGranted); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /tests/ZfcRbacTest/Factory/ModuleOptionsFactoryTest.php: -------------------------------------------------------------------------------- 1 | []]; 32 | 33 | $serviceManager = new ServiceManager(); 34 | $serviceManager->setService('Config', $config); 35 | 36 | $factory = new ModuleOptionsFactory(); 37 | $options = $factory->createService($serviceManager); 38 | 39 | $this->assertInstanceOf('ZfcRbac\Options\ModuleOptions', $options); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /tests/ZfcRbacTest/Factory/RbacFactoryTest.php: -------------------------------------------------------------------------------- 1 | createService($serviceManager); 35 | 36 | $this->assertInstanceOf('Rbac\Rbac', $rbac); 37 | $this->assertInstanceOf('Rbac\Traversal\Strategy\TraversalStrategyInterface', $rbac->getTraversalStrategy()); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /tests/ZfcRbacTest/Factory/RedirectStrategyFactoryTest.php: -------------------------------------------------------------------------------- 1 | getMock('ZfcRbac\Options\RedirectStrategyOptions'); 33 | 34 | $moduleOptionsMock = $this->getMock('ZfcRbac\Options\ModuleOptions'); 35 | $moduleOptionsMock->expects($this->once()) 36 | ->method('getRedirectStrategy') 37 | ->will($this->returnValue($redirectStrategyOptions)); 38 | 39 | $authenticationServiceMock = $this->getMock('Zend\Authentication\AuthenticationService'); 40 | 41 | $serviceLocatorMock = $this->prophesize(ServiceLocatorInterface::class); 42 | $serviceLocatorMock->willImplement(ContainerInterface::class); 43 | $serviceLocatorMock->get('ZfcRbac\Options\ModuleOptions') 44 | ->willReturn($moduleOptionsMock) 45 | ->shouldBeCalled(); 46 | $serviceLocatorMock->get('Zend\Authentication\AuthenticationService') 47 | ->willReturn($authenticationServiceMock) 48 | ->shouldBeCalled(); 49 | 50 | $factory = new RedirectStrategyFactory(); 51 | $redirectStrategy = $factory->createService($serviceLocatorMock->reveal()); 52 | 53 | $this->assertInstanceOf('ZfcRbac\View\Strategy\RedirectStrategy', $redirectStrategy); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /tests/ZfcRbacTest/Factory/RoleProviderPluginManagerFactoryTest.php: -------------------------------------------------------------------------------- 1 | setService('Config', [ 34 | 'zfc_rbac' => [ 35 | 'role_provider_manager' => [] 36 | ] 37 | ]); 38 | 39 | $factory = new RoleProviderPluginManagerFactory(); 40 | $pluginManager = $factory->createService($serviceManager); 41 | 42 | $this->assertInstanceOf(RoleProviderPluginManager::class, $pluginManager); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /tests/ZfcRbacTest/Factory/UnauthorizedStrategyFactoryTest.php: -------------------------------------------------------------------------------- 1 | getMock('ZfcRbac\Options\UnauthorizedStrategyOptions'); 32 | 33 | $moduleOptionsMock = $this->getMock('ZfcRbac\Options\ModuleOptions'); 34 | $moduleOptionsMock->expects($this->once()) 35 | ->method('getUnauthorizedStrategy') 36 | ->will($this->returnValue($unauthorizedStrategyOptions)); 37 | 38 | $serviceLocatorMock = $this->prophesize('Zend\ServiceManager\ServiceLocatorInterface'); 39 | $serviceLocatorMock->willImplement(ContainerInterface::class); 40 | $serviceLocatorMock->get('ZfcRbac\Options\ModuleOptions')->willReturn($moduleOptionsMock)->shouldBeCalled(); 41 | 42 | $factory = new UnauthorizedStrategyFactory(); 43 | $unauthorizedStrategy = $factory->createService($serviceLocatorMock->reveal()); 44 | 45 | $this->assertInstanceOf('ZfcRbac\View\Strategy\UnauthorizedStrategy', $unauthorizedStrategy); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /tests/ZfcRbacTest/Guard/AbstractGuardTest.php: -------------------------------------------------------------------------------- 1 | prophesize(Application::class); 36 | $application->getEventManager()->willReturn($eventManager); 37 | 38 | $event = new MvcEvent(); 39 | $event->setApplication($application->reveal()); 40 | 41 | $guard = new DummyGuard(); 42 | $guard->attach($eventManager); 43 | 44 | $eventManager->attach(MvcEvent::EVENT_DISPATCH_ERROR, function (MvcEvent $event) { 45 | $event->setParam('first-listener', true); 46 | }); 47 | $eventManager->attach(MvcEvent::EVENT_DISPATCH_ERROR, function (MvcEvent $event) { 48 | $event->setParam('second-listener', true); 49 | }); 50 | 51 | // attach listener with lower priority than DummyGuard 52 | $eventManager->attach(MvcEvent::EVENT_ROUTE, function (MvcEvent $event) { 53 | $this->fail('should not be called, because guard should stop propagation'); 54 | }, DummyGuard::EVENT_PRIORITY - 1); 55 | 56 | $event->setName(MvcEvent::EVENT_ROUTE); 57 | $eventManager->triggerEvent($event); 58 | 59 | $this->assertTrue($event->getParam('first-listener')); 60 | $this->assertTrue($event->getParam('second-listener')); 61 | $this->assertTrue($event->propagationIsStopped()); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /tests/ZfcRbacTest/Guard/GuardPluginManagerTest.php: -------------------------------------------------------------------------------- 1 | 'foo' 37 | ] 38 | ], 39 | [ 40 | 'ZfcRbac\Guard\RoutePermissionsGuard', 41 | [ 42 | 'post/delete' => 'post.delete' 43 | ] 44 | ], 45 | [ 46 | 'ZfcRbac\Guard\ControllerGuard', 47 | [ 48 | [ 49 | 'controller' => 'Foo', 50 | 'actions' => 'bar', 51 | 'roles' => 'baz' 52 | ] 53 | ] 54 | ], 55 | [ 56 | 'ZfcRbac\Guard\ControllerPermissionsGuard', 57 | [ 58 | [ 59 | 'controller' => 'Foo', 60 | 'actions' => 'bar', 61 | 'permissions' => 'baz' 62 | ] 63 | ] 64 | ], 65 | ]; 66 | } 67 | 68 | /** 69 | * @dataProvider guardProvider 70 | */ 71 | public function testCanCreateDefaultGuards($type, $options) 72 | { 73 | $serviceManager = new ServiceManager(); 74 | $serviceManager->setService('ZfcRbac\Options\ModuleOptions', new ModuleOptions()); 75 | $serviceManager->setService( 76 | 'ZfcRbac\Service\RoleService', 77 | $this->getMock('ZfcRbac\Service\RoleService', [], [], '', false) 78 | ); 79 | $serviceManager->setService( 80 | 'ZfcRbac\Service\AuthorizationService', 81 | $this->getMock('ZfcRbac\Service\AuthorizationService', [], [], '', false) 82 | ); 83 | 84 | $pluginManager = new GuardPluginManager($serviceManager); 85 | 86 | $guard = $pluginManager->get($type, $options); 87 | 88 | $this->assertInstanceOf($type, $guard); 89 | } 90 | 91 | public function testThrowExceptionForInvalidPlugin() 92 | { 93 | $this->setExpectedException('ZfcRbac\Exception\RuntimeException'); 94 | 95 | $pluginManager = new GuardPluginManager(new ServiceManager()); 96 | $pluginManager->get('stdClass'); 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /tests/ZfcRbacTest/Guard/ProtectionPolicyTraitTest.php: -------------------------------------------------------------------------------- 1 | getObjectForTrait('ZfcRbac\Guard\ProtectionPolicyTrait'); 31 | $trait->setProtectionPolicy(GuardInterface::POLICY_DENY); 32 | 33 | $this->assertEquals(GuardInterface::POLICY_DENY, $trait->getProtectionPolicy()); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /tests/ZfcRbacTest/Identity/AuthenticationIdentityProviderTest.php: -------------------------------------------------------------------------------- 1 | authenticationService = $this->getMock('Zend\Authentication\AuthenticationService'); 41 | $this->identityProvider = new AuthenticationIdentityProvider($this->authenticationService); 42 | } 43 | 44 | public function testCanReturnIdentity() 45 | { 46 | $identity = $this->getMock('ZfcRbac\Identity\IdentityInterface'); 47 | 48 | $this->authenticationService->expects($this->once()) 49 | ->method('getIdentity') 50 | ->will($this->returnValue($identity)); 51 | 52 | $this->assertSame($identity, $this->identityProvider->getIdentity()); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /tests/ZfcRbacTest/Initializer/AuthorizationAwareFake.php: -------------------------------------------------------------------------------- 1 | prophesize(ServiceLocatorInterface::class)->willImplement(ContainerInterface::class); 38 | $authorizationService = $this->getMock('ZfcRbac\Service\AuthorizationService', [], [], '', false); 39 | 40 | $serviceLocator 41 | ->get($authServiceClassName) 42 | ->willReturn($authorizationService) 43 | ->shouldBeCalled(); 44 | 45 | $initializer->initialize($instance, $serviceLocator->reveal()); 46 | 47 | $this->assertEquals($authorizationService, $instance->getAuthorizationService()); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /tests/ZfcRbacTest/ModuleTest.php: -------------------------------------------------------------------------------- 1 | assertInternalType('array', $module->getConfig()); 32 | } 33 | 34 | public function testCanRegisterGuards() 35 | { 36 | $module = new Module(); 37 | $mvcEvent = $this->getMock('Zend\Mvc\MvcEvent'); 38 | $application = $this->getMock('Zend\Mvc\Application', [], [], '', false); 39 | $eventManager = $this->getMock('Zend\EventManager\EventManagerInterface'); 40 | $serviceManager = $this->getMock('Zend\ServiceManager\ServiceManager'); 41 | 42 | $mvcEvent->expects($this->once())->method('getTarget')->will($this->returnValue($application)); 43 | $application->expects($this->once())->method('getEventManager')->will($this->returnValue($eventManager)); 44 | $application->expects($this->once())->method('getServiceManager')->will($this->returnValue($serviceManager)); 45 | 46 | $guards = [ 47 | $this->getMock('ZfcRbac\Guard\GuardInterface') 48 | ]; 49 | 50 | $serviceManager->expects($this->once()) 51 | ->method('get') 52 | ->with('ZfcRbac\Guards') 53 | ->will($this->returnValue($guards)); 54 | 55 | $module->onBootstrap($mvcEvent); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /tests/ZfcRbacTest/Mvc/Controller/Plugin/IsGrantedTest.php: -------------------------------------------------------------------------------- 1 | getMock('ZfcRbac\Service\AuthorizationServiceInterface'); 31 | 32 | $authorizationService->expects($this->once()) 33 | ->method('isGranted') 34 | ->with('edit') 35 | ->will($this->returnValue(true)); 36 | 37 | $helper = new IsGranted($authorizationService); 38 | 39 | $this->assertTrue($helper('edit')); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /tests/ZfcRbacTest/Options/RedirectStrategyOptionsTest.php: -------------------------------------------------------------------------------- 1 | assertTrue($redirectStrategyOptions->getRedirectWhenConnected()); 33 | $this->assertEquals('login', $redirectStrategyOptions->getRedirectToRouteDisconnected()); 34 | $this->assertEquals('home', $redirectStrategyOptions->getRedirectToRouteConnected()); 35 | $this->assertTrue($redirectStrategyOptions->getAppendPreviousUri()); 36 | $this->assertEquals('redirectTo', $redirectStrategyOptions->getPreviousUriQueryKey()); 37 | } 38 | 39 | public function testSettersAndGetters() 40 | { 41 | $redirectStrategyOptions = new RedirectStrategyOptions([ 42 | 'redirect_when_connected' => false, 43 | 'redirect_to_route_connected' => 'foo', 44 | 'redirect_to_route_disconnected' => 'bar', 45 | 'append_previous_uri' => false, 46 | 'previous_uri_query_key' => 'redirect-to' 47 | ]); 48 | 49 | $this->assertFalse($redirectStrategyOptions->getRedirectWhenConnected()); 50 | $this->assertEquals('foo', $redirectStrategyOptions->getRedirectToRouteConnected()); 51 | $this->assertEquals('bar', $redirectStrategyOptions->getRedirectToRouteDisconnected()); 52 | $this->assertFalse($redirectStrategyOptions->getAppendPreviousUri()); 53 | $this->assertEquals('redirect-to', $redirectStrategyOptions->getPreviousUriQueryKey()); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /tests/ZfcRbacTest/Options/UnauthorizedStrategyOptionsTest.php: -------------------------------------------------------------------------------- 1 | assertEquals('error/403', $unauthorizedStrategyOptions->getTemplate()); 33 | } 34 | 35 | public function testSettersAndGetters() 36 | { 37 | $unauthorizedStrategyOptions = new UnauthorizedStrategyOptions([ 38 | 'template' => 'error/unauthorized' 39 | ]); 40 | 41 | $this->assertEquals('error/unauthorized', $unauthorizedStrategyOptions->getTemplate()); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /tests/ZfcRbacTest/Role/InMemoryRoleProviderTest.php: -------------------------------------------------------------------------------- 1 | [ 32 | 'children' => ['member'], 33 | 'permissions' => ['delete'] 34 | ], 35 | 'member' => [ 36 | 'children' => ['guest'], 37 | 'permissions' => ['write'] 38 | ], 39 | 'guest' 40 | ]); 41 | 42 | $roles = $inMemoryProvider->getRoles(['admin', 'member', 'guest']); 43 | 44 | $this->assertCount(3, $roles); 45 | 46 | // Test admin role 47 | $adminRole = $roles[0]; 48 | $this->assertInstanceOf('Rbac\Role\HierarchicalRoleInterface', $adminRole); 49 | $this->assertEquals('admin', $adminRole->getName()); 50 | $this->assertTrue($adminRole->hasPermission('delete')); 51 | 52 | // Test member role 53 | $memberRole = $roles[1]; 54 | $this->assertInstanceOf('Rbac\Role\HierarchicalRoleInterface', $memberRole); 55 | $this->assertEquals('member', $memberRole->getName()); 56 | $this->assertTrue($memberRole->hasPermission('write')); 57 | $this->assertFalse($memberRole->hasPermission('delete')); 58 | 59 | // Test guest role 60 | $guestRole = $roles[2]; 61 | $this->assertInstanceOf('Rbac\Role\RoleInterface', $guestRole); 62 | $this->assertNotInstanceOf('Rbac\Role\HierarchicalRoleInterface', $guestRole); 63 | $this->assertEquals('guest', $guestRole->getName()); 64 | $this->assertFalse($guestRole->hasPermission('write')); 65 | $this->assertFalse($guestRole->hasPermission('delete')); 66 | 67 | $this->assertSame($adminRole->getChildren()['member'], $memberRole); 68 | $this->assertSame($memberRole->getChildren()['guest'], $guestRole); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /tests/ZfcRbacTest/Role/RoleProviderPluginManagerTest.php: -------------------------------------------------------------------------------- 1 | getMock('ZfcRbac\Role\RoleProviderInterface'); 32 | $pluginManager = new RoleProviderPluginManager(new ServiceManager()); 33 | 34 | $this->assertNull($pluginManager->validatePlugin($pluginMock)); 35 | } 36 | 37 | public function testValidationOfPluginFailsIfRoleProviderInterfaceIsNotImplemented() 38 | { 39 | $this->setExpectedException('ZfcRbac\Exception\RuntimeException'); 40 | 41 | $pluginManager = new RoleProviderPluginManager(new ServiceManager()); 42 | $pluginManager->get('stdClass', []); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /tests/ZfcRbacTest/Service/AuthorizationServiceAwareTraitTest.php: -------------------------------------------------------------------------------- 1 | getObjectForTrait('ZfcRbac\Service\AuthorizationServiceAwareTrait'); 30 | $authorizationService = $this->getMock('ZfcRbac\Service\AuthorizationService', [], [], '', false); 31 | 32 | $trait->setAuthorizationService($authorizationService); 33 | 34 | $this->assertEquals($authorizationService, $trait->getAuthorizationService()); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /tests/ZfcRbacTest/Util/ServiceManagerFactory.php: -------------------------------------------------------------------------------- 1 | 29 | */ 30 | abstract class ServiceManagerFactory 31 | { 32 | /** 33 | * @var array 34 | */ 35 | private static $config = []; 36 | 37 | /** 38 | * @static 39 | * @param array $config 40 | */ 41 | public static function setApplicationConfig(array $config) 42 | { 43 | static::$config = $config; 44 | } 45 | 46 | /** 47 | * @static 48 | * @return array 49 | */ 50 | public static function getApplicationConfig() 51 | { 52 | return static::$config; 53 | } 54 | 55 | /** 56 | * @param array|null $config 57 | * @return ServiceManager 58 | */ 59 | public static function getServiceManager(array $config = null) 60 | { 61 | $config = $config ?: static::getApplicationConfig(); 62 | $serviceManagerConfig = new ServiceManagerConfig( 63 | isset($config['service_manager']) ? $config['service_manager'] : [] 64 | ); 65 | $serviceManager = new ServiceManager(); 66 | $serviceManagerConfig->configureServiceManager($serviceManager); 67 | $serviceManager->setService('ApplicationConfig', $config); 68 | $serviceManager->setAllowOverride(true); 69 | 70 | /* @var $moduleManager \Zend\ModuleManager\ModuleManagerInterface */ 71 | $moduleManager = $serviceManager->get('ModuleManager'); 72 | 73 | $moduleManager->loadModules(); 74 | 75 | return $serviceManager; 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /tests/ZfcRbacTest/View/Helper/HasRoleTest.php: -------------------------------------------------------------------------------- 1 | get('Config'); 33 | $this->assertArrayHasKey('view_helpers', $config); 34 | $viewHelpersConfig = $config['view_helpers']; 35 | $this->assertEquals('ZfcRbac\View\Helper\HasRole', $viewHelpersConfig['aliases']['hasRole']); 36 | $this->assertEquals( 37 | 'ZfcRbac\Factory\HasRoleViewHelperFactory', 38 | $viewHelpersConfig['factories']['ZfcRbac\View\Helper\HasRole'] 39 | ); 40 | } 41 | 42 | public function testCallAuthorizationService() 43 | { 44 | $rolesConfig = [ 45 | ['member', true], 46 | [['member'], true], 47 | ]; 48 | 49 | $authorizationService = $this->getMock('ZfcRbac\Service\RoleService', [], [], '', false); 50 | $authorizationService->expects($this->any()) 51 | ->method('matchIdentityRoles') 52 | ->will($this->returnValueMap($rolesConfig)); 53 | 54 | $helper = new HasRole($authorizationService); 55 | 56 | $this->assertTrue($helper('member')); 57 | $this->assertTrue($helper(['member'])); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /tests/ZfcRbacTest/View/Helper/IsGrantedTest.php: -------------------------------------------------------------------------------- 1 | get('Config'); 33 | $this->assertArrayHasKey('view_helpers', $config); 34 | $viewHelpersConfig = $config['view_helpers']; 35 | $this->assertEquals('ZfcRbac\View\Helper\IsGranted', $viewHelpersConfig['aliases']['isGranted']); 36 | $this->assertEquals( 37 | 'ZfcRbac\Factory\IsGrantedViewHelperFactory', 38 | $viewHelpersConfig['factories']['ZfcRbac\View\Helper\IsGranted'] 39 | ); 40 | } 41 | 42 | public function testCallAuthorizationService() 43 | { 44 | $authorizationService = $this->getMock('ZfcRbac\Service\AuthorizationServiceInterface'); 45 | 46 | $authorizationService->expects($this->once()) 47 | ->method('isGranted') 48 | ->with('edit') 49 | ->will($this->returnValue(true)); 50 | 51 | $helper = new IsGranted($authorizationService); 52 | 53 | $this->assertTrue($helper('edit')); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /tests/ZfcRbacTest/View/Strategy/UnauthorizedStrategyTest.php: -------------------------------------------------------------------------------- 1 | getMock('Zend\EventManager\EventManagerInterface'); 38 | $eventManager->expects($this->once()) 39 | ->method('attach') 40 | ->with(MvcEvent::EVENT_DISPATCH_ERROR); 41 | 42 | $strategyListener->attach($eventManager); 43 | } 44 | 45 | public function testFillEvent() 46 | { 47 | $response = new HttpResponse(); 48 | 49 | $mvcEvent = new MvcEvent(); 50 | $mvcEvent->setParam('exception', new UnauthorizedException()); 51 | $mvcEvent->setResponse($response); 52 | 53 | $options = new UnauthorizedStrategyOptions([ 54 | 'template' => 'error/403' 55 | ]); 56 | 57 | $unauthorizedStrategy = new UnauthorizedStrategy($options); 58 | 59 | $unauthorizedStrategy->onError($mvcEvent); 60 | 61 | $this->assertEquals(403, $mvcEvent->getResponse()->getStatusCode()); 62 | $this->assertInstanceOf('Zend\View\Model\ModelInterface', $mvcEvent->getResult()); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /tests/testing.config.php: -------------------------------------------------------------------------------- 1 | [], 21 | 22 | 'doctrine' => [ 23 | 'driver' => [ 24 | 'application_driver' => [ 25 | 'class' => 'Doctrine\ORM\Mapping\Driver\AnnotationDriver', 26 | 'cache' => 'array', 27 | 'paths' => [__DIR__ . '/ZfcRbacTest/Asset'] 28 | ], 29 | 'orm_default' => [ 30 | 'drivers' => [ 31 | 'ZfcRbacTest\Asset' => 'application_driver' 32 | ] 33 | ] 34 | ], 35 | 36 | 'connection' => [ 37 | 'orm_default' => [ 38 | 'driverClass' => 'Doctrine\DBAL\Driver\PDOSqlite\Driver', 39 | 'params' => [ 40 | 'host' => null, 41 | 'port' => null, 42 | 'user' => null, 43 | 'password' => null, 44 | 'dbname' => 'test', 45 | 'driver' => 'pdo_sqlite', 46 | 'path' => null, 47 | 'memory' => true, 48 | ], 49 | ], 50 | ], 51 | ], 52 | ]; 53 | -------------------------------------------------------------------------------- /view/error/403.phtml: -------------------------------------------------------------------------------- 1 |

A 403 error occurred

2 | 3 |

You are not allowed to access this resource

4 | 5 |

Details

6 | 7 | error) { 11 | case GuardInterface::GUARD_UNAUTHORIZED: 12 | echo '

Request was blocked by a ZfcRbac guard

'; 13 | break; 14 | } 15 | ?> 16 | --------------------------------------------------------------------------------