Skip to content

Commit

Permalink
Minor fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
samdark committed Feb 11, 2024
1 parent 238f828 commit 53b4bf1
Show file tree
Hide file tree
Showing 14 changed files with 54 additions and 46 deletions.
34 changes: 17 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@
[![static analysis](https://github.com/yiisoft/rbac/workflows/static%20analysis/badge.svg)](https://github.com/yiisoft/rbac/actions?query=workflow%3A%22static+analysis%22)
[![type-coverage](https://shepherd.dev/github/yiisoft/rbac/coverage.svg)](https://shepherd.dev/github/yiisoft/rbac)

This package provides [RBAC](https://en.wikipedia.org/wiki/Role-based_access_control) (Role-Based Access Control)
This package provides [RBAC](https://en.wikipedia.org/wiki/Role-based_access_control) (Role-Based Access Control)
library. It is used in [Yii Framework](https://yiiframework.com) but is usable separately as well.

## Features

- Flexible RBAC hierarchy with roles, permissions and rules.
- Flexible RBAC hierarchy with roles, permissions, and rules.
- Role inheritance.
- Data could be passed to rules when checking access.
- Multiple storage adapters.
Expand All @@ -29,7 +29,7 @@ library. It is used in [Yii Framework](https://yiiframework.com) but is usable s

## Requirements

- PHP 8.0 or higher.
- PHP 8.1 or higher.

## Installation

Expand Down Expand Up @@ -74,7 +74,7 @@ It requires specifying the following dependencies:

- Items storage (hierarchy itself).
- Assignments storage where user IDs are mapped to roles.
- Rule factory. Given a rule name stored in items storage it can create an instance of `Rule`.
- Rule factory. Given a rule name stored in item storage it can create an instance of `Rule`.

If you don't want to use [Rules Container](https://github.com/yiisoft/rbac-rules-container), here is an example of
simple self-contained rule factory:
Expand Down Expand Up @@ -105,23 +105,23 @@ final class SimpleRuleFactory implements RuleFactoryInterface

A few tips for choosing storage backend:

- Roles and permissions could usually be considered "semi-static", as they only change when you update your application
- Roles and permissions could usually be considered "semi-static," as they only change when you update your application
code, so it may make sense to use PHP storage for it.
- Assignments, on the other hand, could be considered "dynamic". They change more often: when creating a new user,
or when updating user role from within your application. So it may make sense to use database storage for assignments.
- Assignments, on the other hand, could be considered "dynamic." They change more often: when creating a new user,
or when updating a user role from within your application. So it may make sense to use database storage for assignments.

### Managing RBAC hierarchy

Before being able to check for permissions, a RBAC hierarchy must be defined. Usually it is done via either console
commands or migrations. Hierarchy consists of permissions, roles and rules:
Before being able to check for permissions, an RBAC hierarchy must be defined. Usually it is done via either console
commands or migrations. Hierarchy consists of permissions, roles, and rules:

- Permissions are granules of access such as "create a post" or "read a post".
- A role is what is assigned to the user. Role is granted one or more permissions. Typical roles are "manager" or
"admin".
- Rule is a PHP class that given some data answers a single question "given the data, has the user the permission asked
for".
- Permissions are granules of access such as "create a post" or "read a post."
- A role is what is assigned to the user. The Role is granted one or more permissions. Typical roles are "manager" or
"admin."
- Rule is a PHP class that has given some data answers a single question "given the data has the user the permission asked
for."

In order to create a permission, use the following code:
To create a permission, use the following code:

```php
use Yiisoft\Rbac\ManagerInterface;
Expand Down Expand Up @@ -225,7 +225,7 @@ $compositeRule = new CompositeRule(CompositeRule::OR, [FreshRule::class, OwnedRu

### Assigning roles to users

In order to assign a certain role to a user with a given ID, use the following code:
To assign a certain role to a user with a given ID, use the following code:

```php
use Yiisoft\Rbac\ManagerInterface;
Expand All @@ -240,7 +240,7 @@ itself.

### Check for permission

In order to check for permission, obtain an instance of `Yiisoft\Access\AccessCheckerInterface` and use it:
To check for permission, obtain an instance of `Yiisoft\Access\AccessCheckerInterface` and use it:

```php
use Psr\Http\Message\ResponseInterface;
Expand Down
6 changes: 5 additions & 1 deletion src/Assignment.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@ final class Assignment
* @param string $itemName The role or permission name.
* @param int $createdAt UNIX timestamp representing the assignment creation time.
*/
public function __construct(private string $userId, private string $itemName, private int $createdAt)
public function __construct(
private readonly string $userId,
private string $itemName,
private readonly int $createdAt
)
{
}

Expand Down
2 changes: 1 addition & 1 deletion src/AssignmentsStorageInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ public function add(Assignment $assignment): void;
public function hasItem(string $name): bool;

/**
* Change name of an item in assignments.
* Change the name of an item in assignments.
*
* @param string $oldName Old name of the role or the permission.
* @param string $newName New name of the role or permission.
Expand Down
5 changes: 4 additions & 1 deletion src/CompositeRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,10 @@ final class CompositeRule implements RuleInterface
* @param string $operator Operator to be used. Could be `CompositeRule::AND` or `CompositeRule::OR`.
* @param string[] $ruleNames Array of rule names.
*/
public function __construct(private string $operator, private array $ruleNames)
public function __construct(
private readonly string $operator,
private readonly array $ruleNames
)
{
if (!in_array($operator, [self::AND, self::OR], true)) {
throw new InvalidArgumentException(
Expand Down
10 changes: 5 additions & 5 deletions src/ItemsStorageInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,20 +49,20 @@ public function getByNames(array $names): array;
public function get(string $name): Permission|Role|null;

/**
* Whether named role or permission exists.
* Whether a named role or permission exists.
*
* @param string $name The role or the permission name.
*
* @return bool Whether named role or permission exists.
* @return bool Whether a named role or permission exists.
*/
public function exists(string $name): bool;

/**
* Whether named role exists.
* Whether a named role exists.
*
* @param string $name The role name.
*
* @return bool Whether named role exists.
* @return bool Whether a named role exists.
*/
public function roleExists(string $name): bool;

Expand Down Expand Up @@ -258,7 +258,7 @@ public function addChild(string $parentName, string $childName): void;
* Removes a child from its parent.
* Note, the child role or permission is not deleted. Only the parent-child relationship is removed.
*
* @param string $parentName Name of the parent to remove child from.
* @param string $parentName Name of the parent to remove the child from.
* @param string $childName Name of the child to remove.
*/
public function removeChild(string $parentName, string $childName): void;
Expand Down
10 changes: 5 additions & 5 deletions src/Manager.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,10 @@ final class Manager implements ManagerInterface
* roles only.
*/
public function __construct(
private ItemsStorageInterface $itemsStorage,
private AssignmentsStorageInterface $assignmentsStorage,
private RuleFactoryInterface $ruleFactory,
private bool $enableDirectPermissions = false,
private readonly ItemsStorageInterface $itemsStorage,
private readonly AssignmentsStorageInterface $assignmentsStorage,
private readonly RuleFactoryInterface $ruleFactory,
private readonly bool $enableDirectPermissions = false,
) {
}

Expand Down Expand Up @@ -347,7 +347,7 @@ public function getGuestRole(): ?Role
* If the item does not specify a rule, this method will return `true`. Otherwise, it will
* return the value of {@see RuleInterface::execute()}.
*
* @param string $userId The user ID. This should be a string representing the unique identifier of a user. For
* @param string|null $userId The user ID. This should be a string representing the unique identifier of a user. For
* guests the value is `null`.
* @param Item $item The role or the permission that needs to execute its rule.
* @param array $params Parameters passed to {@see AccessCheckerInterface::userHasPermission()} and will be passed
Expand Down
10 changes: 5 additions & 5 deletions src/ManagerInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
interface ManagerInterface extends AccessCheckerInterface
{
/**
* Checks the possibility of adding a child to parent.
* Checks the possibility of adding a child to a parent.
*
* @param string $parentName The name of the parent item.
* @param string $childName The name of the child item to be added to the hierarchy.
Expand Down Expand Up @@ -141,7 +141,7 @@ public function getRolesByUserId(int|Stringable|string $userId): array;
*
* @param string $roleName Name of the role to get child roles for.
*
* @throws InvalidArgumentException If role was not found by `$roleName`.
* @throws InvalidArgumentException If the role was not found by `$roleName`.
*
* @return Role[] Child roles. The array is indexed by the role names.
* @psalm-return array<string, Role>
Expand Down Expand Up @@ -239,7 +239,7 @@ public function getDefaultRoleNames(): array;
/**
* Returns default roles.
*
* @throws DefaultRolesNotFoundException When at least 1 of default roles was not found.
* @throws DefaultRolesNotFoundException When at least 1 of the default roles was not found.
* @return Role[] Default roles. The array is indexed by the role names.
* @psalm-return array<string, Role>
*/
Expand All @@ -260,9 +260,9 @@ public function setGuestRoleName(?string $name): self;
public function getGuestRoleName(): ?string;

/**
* Get guest role.
* Get a guest role.
*
* @throws InvalidArgumentException When role was not found.
* @throws InvalidArgumentException When a role was not found.
* @return Role|null Guest role or `null` if the name was not set.
*/
public function getGuestRole(): ?Role;
Expand Down
5 changes: 4 additions & 1 deletion src/RuleContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@

final class RuleContext
{
public function __construct(private RuleFactoryInterface $ruleFactory, private array $parameters)
public function __construct(
private readonly RuleFactoryInterface $ruleFactory,
private readonly array $parameters
)
{
}

Expand Down
4 changes: 2 additions & 2 deletions src/RuleInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
namespace Yiisoft\Rbac;

/**
* Rule represents a business constraint that may be associated with a role or a permission.
* The Rule represents a business constraint that may be associated with a role or a permission.
*/
interface RuleInterface
{
Expand All @@ -17,7 +17,7 @@ interface RuleInterface
* @param Item $item The role or permission that this rule is associated with.
* @param RuleContext $ruleContext Rule context.
*
* @return bool Whether the rule permits the auth item it is associated with.
* @return bool Whether the rule permits the auth item, it is associated with.
*/
public function execute(?string $userId, Item $item, RuleContext $ruleContext): bool;
}
6 changes: 3 additions & 3 deletions src/SimpleItemsStorage.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public function getAll(): array

public function getByNames(array $names): array
{
return array_filter($this->getAll(), static fn (Item $item): bool => in_array($item->getName(), $names));
return array_filter($this->getAll(), static fn (Item $item): bool => in_array($item->getName(), $names, true));
}

public function get(string $name): Permission|Role|null
Expand Down Expand Up @@ -74,7 +74,7 @@ public function getRolesByNames(array $names): array
{
return array_filter(
$this->getAll(),
static fn (Permission|Role $item): bool => $item instanceof Role && in_array($item->getName(), $names),
static fn (Permission|Role $item): bool => $item instanceof Role && in_array($item->getName(), $names, true),
);
}

Expand All @@ -93,7 +93,7 @@ public function getPermissionsByNames(array $names): array
return array_filter(
$this->getAll(),
static function (Permission|Role $item) use ($names): bool {
return $item instanceof Permission && in_array($item->getName(), $names);
return $item instanceof Permission && in_array($item->getName(), $names, true);
},
);
}
Expand Down
2 changes: 0 additions & 2 deletions tests/Common/AssignmentsStorageTestTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@

trait AssignmentsStorageTestTrait
{
protected static bool $reCreateAssignmentsStorageAfterModifications = false;

private ?ItemsStorageInterface $itemsStorage = null;
private ?AssignmentsStorageInterface $assignmentsStorage = null;

Expand Down
2 changes: 1 addition & 1 deletion tests/RuleContextTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public function testGetParameterValue(): void
{
$context = new RuleContext(new SimpleRuleFactory(['easy' => new EasyRule()]), ['a' => 1, 'b' => 2]);
$this->assertSame(1, $context->getParameterValue('a'));
$this->assertSame(null, $context->getParameterValue('c'));
$this->assertNull($context->getParameterValue('c'));
}

public function testHasParameter(): void
Expand Down
2 changes: 1 addition & 1 deletion tests/Support/EasyRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

final class EasyRule implements RuleInterface
{
public function __construct(private bool $expected = true)
public function __construct(private readonly bool $expected = true)
{
}

Expand Down
2 changes: 1 addition & 1 deletion tests/Support/SimpleRuleFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ final class SimpleRuleFactory implements RuleFactoryInterface
/**
* @psalm-param array<string,RuleInterface> $rules
*/
public function __construct(private array $rules = [])
public function __construct(private readonly array $rules = [])
{
}

Expand Down

0 comments on commit 53b4bf1

Please sign in to comment.