Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 85 additions & 16 deletions docs/book/v3/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

As with many Dotkernel modules, we focus on the configuration based approach of customizing the module for your needs.

After installing, merge the module's `ConfigProvider` with your application's config to make sure required dependencies and default module configuration are registered. Create a configuration file for this module in your 'config/autoload' folder.
After installing, merge the module's `ConfigProvider` with your application's config to make sure required dependencies and default module configuration are registered.
Create a configuration file for this module in your 'config/autoload' folder.

## authorization-guards.global.php

Expand Down Expand Up @@ -41,8 +42,8 @@ return [
'logout' => ['admin', 'user', 'viewer'],
'account' => ['admin', 'user'],
'home' => ['*'],
]
]
],
],
],
[
'type' => 'RoutePermission',
Expand All @@ -51,40 +52,40 @@ return [
'premium' => ['premium'],
'account' => ['my-account'],
'logout' => ['only-logged'],
]
]
],
],
],
[
'type' => 'Controller',
'options' => [
'rules' => [
[
'route' => 'controller route name',
'actions' => [//list of actions to apply, or empty array for all actions],
//by default, authorization pass if all permissions are present(AND)
'roles' => [//list of roles to allow],
'actions' => [], //list of actions to apply, or empty array for all actions,
// by default, authorization passes if all permissions are present(AND)
'roles' => ['admin'], //list of roles to allow,
],
]
]
],
],
],
[
'type' => 'ControllerPermission',
'options' => [
'rules' => [
[
'route' => 'controller route name',
'actions' => [//list of actions to apply, or empty array for all actions],
//by default, authorization pass if all permissions are present(AND)
'permissions' => [//list of permissions to allow],
'actions' => [], //list of actions to apply, or empty array for all actions,
// by default, authorization passes if all permissions are present(AND)
'permissions' => ['authenticated'], //list of permissions to allow,
],
[
'route' => 'controller route name',
'actions' => [//list of actions to apply, or empty array for all actions],
'actions' => [], //list of actions to apply, or empty array for all actions,
'permissions' => [
//permission can be defined in this way too, for all permission type guards
'permissions' => [//list of permissions],
'permissions' => ['authenticated'], //list of permissions,
'condition' => \Dot\Rbac\Guard\GuardInterface::CONDITION_OR,
]
],
]
]
]
Expand All @@ -103,3 +104,71 @@ return [
],
];
```

> It is **strongly recommended** to explicitly define permissions or roles and not leave the values empty, especially if using `GuardInterface::POLICY_DENY`!

## Route Name Placeholders

Route **names** are allowed to contain `*` as placeholders, allowing more compact specifications.
This feature is available for all types of guards.

> Note that route rules are verified in order of their writing, take care of the order when using placeholder routes, as not to overwrite any specific routes!

```php
[
'type' => 'Route',
'options' => [
'rules' => [
'account-create-form' => ['admin'],
'account-update-form' => ['admin'],
'account-delete-form' => ['admin'],
]
],
[
'type' => 'Controller',
'options' => [
'rules' => [
[
'route' => 'admin-create',
'actions' => [],
'roles' => ['admin'],
],
[
'route' => 'admin-edit',
'actions' => [],
'roles' => ['admin'],
],
[
'route' => 'admin-view',
'actions' => [],
'roles' => ['admin'],
],
]
]
],
],


// Can be written as:

[
'type' => 'Route',
'options' => [
'rules' => [
'account-*-form' => ['admin'],
]
],
[
'type' => 'Controller',
'options' => [
'rules' => [
[
'route' => 'admin-*',
'actions' => [],
'roles' => ['admin'],
],
]
]
],
]
```
25 changes: 23 additions & 2 deletions src/Guard/ControllerGuard.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,12 @@
use Mezzio\Router\RouteResult;
use Psr\Http\Message\ServerRequestInterface;

use function array_keys;
use function in_array;
use function preg_match;
use function sprintf;
use function str_contains;
use function str_replace;
use function strtolower;

class ControllerGuard extends AbstractGuard
Expand All @@ -19,6 +24,8 @@ class ControllerGuard extends AbstractGuard

protected ?RoleServiceInterface $roleService = null;

protected array $rules = [];

public function __construct(?array $options = null)
{
$options = $options ?? [];
Expand All @@ -34,8 +41,6 @@ public function __construct(?array $options = null)

public function setRules(array $rules): void
{
$this->rules = [];

foreach ($rules as $rule) {
$route = strtolower($rule['route']);
$actions = isset($rule['actions']) ? (array) $rule['actions'] : [];
Expand Down Expand Up @@ -72,6 +77,22 @@ public function isGranted(ServerRequestInterface $request): bool

$route = strtolower($routeResult->getMatchedRouteName());

foreach (array_keys($this->rules) as $routeName) {
if (str_contains($routeName, '*')) {
$routePattern = sprintf(
"/^%s$/",
str_replace('*', '[\w\-]+', $routeName)
);

$routeMatched = preg_match($routePattern, $route);

if ($routeMatched === 1) {
$route = $routeName;
break;
}
}
}

if (! isset($this->rules[$route])) {
return $this->protectionPolicy === self::POLICY_ALLOW;
}
Expand Down
25 changes: 23 additions & 2 deletions src/Guard/ControllerPermissionGuard.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,14 @@
use Mezzio\Router\RouteResult;
use Psr\Http\Message\ServerRequestInterface;

use function array_keys;
use function gettype;
use function in_array;
use function is_object;
use function preg_match;
use function sprintf;
use function str_contains;
use function str_replace;
use function strtolower;

class ControllerPermissionGuard extends AbstractGuard
Expand All @@ -23,6 +27,8 @@ class ControllerPermissionGuard extends AbstractGuard

protected ?AuthorizationInterface $authorizationService = null;

protected array $rules = [];

public function __construct(?array $options = null)
{
$options = $options ?? [];
Expand All @@ -42,8 +48,6 @@ public function __construct(?array $options = null)

public function setRules(array $rules): void
{
$this->rules = [];

foreach ($rules as $rule) {
$route = strtolower($rule['route']);
$actions = isset($rule['actions']) ? (array) $rule['actions'] : [];
Expand All @@ -69,6 +73,23 @@ public function isGranted(ServerRequestInterface $request): bool
}

$route = $routeResult->getMatchedRouteName();

foreach (array_keys($this->rules) as $routeName) {
if (str_contains($routeName, '*')) {
$routePattern = sprintf(
"/^%s$/",
str_replace('*', '[\w\-]+', $routeName)
);

$routeMatched = preg_match($routePattern, $route);

if ($routeMatched === 1) {
$route = $routeName;
break;
}
}
}

if (! isset($this->rules[$route])) {
return $this->protectionPolicy === self::POLICY_ALLOW;
}
Expand Down
28 changes: 23 additions & 5 deletions src/Guard/RouteGuard.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@
use function array_keys;
use function in_array;
use function is_int;
use function preg_match;
use function sprintf;
use function str_contains;
use function str_replace;
use function strtolower;

class RouteGuard extends AbstractGuard
Expand All @@ -20,6 +24,8 @@ class RouteGuard extends AbstractGuard

protected ?RoleServiceInterface $roleService = null;

protected array $rules = [];

public function __construct(?array $options = null)
{
$options = $options ?? [];
Expand All @@ -36,8 +42,6 @@ public function __construct(?array $options = null)

public function setRules(array $rules): void
{
$this->rules = [];

foreach ($rules as $key => $value) {
if (is_int($key)) {
$routeName = strtolower($value);
Expand Down Expand Up @@ -73,9 +77,23 @@ public function isGranted(ServerRequestInterface $request): bool
$allowedRoles = null;

foreach (array_keys($this->rules) as $routeName) {
if ($routeName === $matchedRouteName) {
$allowedRoles = $this->rules[$routeName];
break;
if (str_contains($routeName, '*')) {
$routePattern = sprintf(
"/^%s$/",
str_replace('*', '[\w\-]+', $routeName)
);

$routeMatched = preg_match($routePattern, $matchedRouteName);

if ($routeMatched === 1) {
$allowedRoles = $this->rules[$routeName];
break;
}
} else {
if ($routeName === $matchedRouteName) {
$allowedRoles = $this->rules[$routeName];
break;
}
}
}

Expand Down
26 changes: 22 additions & 4 deletions src/Guard/RoutePermissionGuard.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@
use function in_array;
use function is_int;
use function is_object;
use function preg_match;
use function sprintf;
use function str_contains;
use function str_replace;
use function strtolower;

class RoutePermissionGuard extends AbstractGuard
Expand All @@ -24,6 +27,8 @@ class RoutePermissionGuard extends AbstractGuard

protected ?AuthorizationInterface $authorizationService = null;

protected array $rules = [];

public function __construct(?array $options = null)
{
$options = $options ?? [];
Expand All @@ -43,7 +48,6 @@ public function __construct(?array $options = null)

public function setRules(array $rules): void
{
$this->rules = [];
foreach ($rules as $key => $value) {
if (is_int($key)) {
$routeName = strtolower($value);
Expand All @@ -68,9 +72,23 @@ public function isGranted(ServerRequestInterface $request): bool
$allowedPermissions = null;

foreach (array_keys($this->rules) as $routeName) {
if ($matchedRouteName === $routeName) {
$allowedPermissions = $this->rules[$routeName];
break;
if (str_contains($routeName, '*')) {
$routePattern = sprintf(
"/^%s$/",
str_replace('*', '[\w\-]+', $routeName)
);

$routeMatched = preg_match($routePattern, $matchedRouteName);

if ($routeMatched === 1) {
$allowedPermissions = $this->rules[$routeName];
break;
}
} else {
if ($matchedRouteName === $routeName) {
$allowedPermissions = $this->rules[$routeName];
break;
}
}
}

Expand Down
Loading