-
-
Notifications
You must be signed in to change notification settings - Fork 188
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
FEATURE: Introduce
RoleId
and RoleIds
value objects
Resolves: #3414
- Loading branch information
1 parent
dfc75e7
commit 1e61872
Showing
5 changed files
with
193 additions
and
37 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
<?php | ||
declare(strict_types=1); | ||
|
||
namespace Neos\Flow\Security\Policy; | ||
|
||
/* | ||
* This file is part of the Neos.Flow package. | ||
* | ||
* (c) Contributors of the Neos Project - www.neos.io | ||
* | ||
* This package is Open Source Software. For the full copyright and license | ||
* information, please view the LICENSE file which was distributed with this | ||
* source code. | ||
*/ | ||
|
||
/** | ||
* A role identifier in the format <Vendor>(.<Package>):<Role>, for example "Some.Package:SomeRole" | ||
*/ | ||
final readonly class RoleId | ||
{ | ||
private const ROLE_IDENTIFIER_PATTERN = '/^(\w+(?:\.\w+)*)\:(\w+)$/'; // Vendor(.Package)?:RoleName | ||
|
||
private string $packageKey; | ||
private string $name; | ||
|
||
private function __construct( | ||
public string $value, | ||
) | ||
{ | ||
if (preg_match(self::ROLE_IDENTIFIER_PATTERN, $value, $matches) !== 1) { | ||
throw new \InvalidArgumentException('The role id must follow the pattern "Vendor.Package:RoleName", but "' . $value . '" was given. Please check the code or policy configuration creating or defining this role.', 1365446549); | ||
} | ||
$this->packageKey = $matches[1]; | ||
$this->name = $matches[2]; | ||
} | ||
|
||
public static function fromString(string $value): self | ||
{ | ||
return new self($value); | ||
} | ||
|
||
public static function everybody(): self | ||
{ | ||
return new self('Neos.Flow:Everybody'); | ||
} | ||
|
||
public static function anonymous(): self | ||
{ | ||
return new self('Neos.Flow:Anonymous'); | ||
} | ||
|
||
public static function authenticatedUser(): self | ||
{ | ||
return new self('Neos.Flow:AuthenticatedUser'); | ||
} | ||
|
||
/** | ||
* The package key prefix of the id, e.g. "Some.Package" | ||
*/ | ||
public function getPackageKey(): string | ||
{ | ||
return $this->packageKey; | ||
} | ||
|
||
/** | ||
* The name suffix of the id without its package key prefix, e.g. "SomeRole" | ||
*/ | ||
public function getName(): string | ||
{ | ||
return $this->name; | ||
} | ||
|
||
public function equals(self $other): bool | ||
{ | ||
return $other->value === $this->value; | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
namespace Neos\Flow\Security\Policy; | ||
|
||
/** | ||
* @implements \IteratorAggregate<RoleId> | ||
*/ | ||
final readonly class RoleIds implements \IteratorAggregate, \Countable | ||
{ | ||
|
||
/** | ||
* array<RoleId> | ||
*/ | ||
private array $roleIds; | ||
|
||
/** | ||
* @param array<RoleId> $roleIds | ||
*/ | ||
private function __construct( | ||
Check failure on line 20 in Neos.Flow/Classes/Security/Policy/RoleIds.php GitHub Actions / PHP 8.2 Test static analysis (deps: highest)
|
||
RoleId ...$roleIds | ||
) { | ||
$this->roleIds = $roleIds; | ||
} | ||
|
||
public static function forAnonymousUser(): self | ||
{ | ||
return self::fromArray([RoleId::everybody(), RoleId::anonymous()]); | ||
} | ||
|
||
/** | ||
* @param array<RoleId|string> $roleIds | ||
*/ | ||
public static function fromArray(array $roleIds): self | ||
{ | ||
$processedIds = []; | ||
foreach ($roleIds as $roleId) { | ||
if (is_string($roleId)) { | ||
$roleId = RoleId::fromString($roleId); | ||
} elseif (!$roleId instanceof RoleId) { | ||
throw new \InvalidArgumentException(sprintf('Expected string or instance of %s, got: %s', RoleId::class, get_debug_type($roleId)), 1731338164); | ||
} | ||
$processedIds[] = $roleId; | ||
} | ||
return new self(...$processedIds); | ||
} | ||
|
||
public function getIterator(): \Traversable | ||
{ | ||
yield from $this->roleIds; | ||
} | ||
|
||
public function count(): int | ||
{ | ||
return count($this->roleIds); | ||
} | ||
|
||
/** | ||
* @template T | ||
* @param callable(RoleId): T $callback | ||
* @return array<T> | ||
*/ | ||
public function map(callable $callback): array | ||
{ | ||
return array_map($callback, $this->roleIds); | ||
} | ||
} |