feature #14001 [2.7] [Security] [ACL] Improved MaskBuilder and PermissionMap (AlexDpy)
This PR was merged into the 2.7 branch. Discussion ---------- [2.7] [Security] [ACL] Improved MaskBuilder and PermissionMap | Q | A | ------------- | --- | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | #13566 | License | MIT | Doc PR | I'll do it if needed This PR refers to #13697 . The previous PR introduced a BC break, so i provide this one which is backward compatible. The MaskBuilderRetrievalInterface::getMaskBuilder methods allows us to retrieve a new instance of the MaskBuilder used in our application, even if it's a custom one. I also added a MaskBuilderInterface and an AbstractMaskBuilder which can be a great helper. Commits -------3d79d8b
added MaskBuilderRetrievalInterface89a1f2a
improved MaskBuilder
This commit is contained in:
commit
a3dc823983
@ -0,0 +1,85 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Security\Acl\Permission;
|
||||
|
||||
/**
|
||||
* This abstract class implements nearly all the MaskBuilderInterface methods
|
||||
*/
|
||||
abstract class AbstractMaskBuilder implements MaskBuilderInterface
|
||||
{
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $mask;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param int $mask optional; defaults to 0
|
||||
*/
|
||||
public function __construct($mask = 0)
|
||||
{
|
||||
$this->set($mask);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function set($mask)
|
||||
{
|
||||
if (!is_int($mask)) {
|
||||
throw new \InvalidArgumentException('$mask must be an integer.');
|
||||
}
|
||||
|
||||
$this->mask = $mask;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function get()
|
||||
{
|
||||
return $this->mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function add($mask)
|
||||
{
|
||||
$this->mask |= $this->resolveMask($mask);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function remove($mask)
|
||||
{
|
||||
$this->mask &= ~$this->resolveMask($mask);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
$this->mask = 0;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
@ -17,7 +17,7 @@ namespace Symfony\Component\Security\Acl\Permission;
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
class BasicPermissionMap implements PermissionMapInterface
|
||||
class BasicPermissionMap implements PermissionMapInterface, MaskBuilderRetrievalInterface
|
||||
{
|
||||
const PERMISSION_VIEW = 'VIEW';
|
||||
const PERMISSION_EDIT = 'EDIT';
|
||||
@ -105,4 +105,12 @@ class BasicPermissionMap implements PermissionMapInterface
|
||||
{
|
||||
return isset($this->map[$permission]);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getMaskBuilder()
|
||||
{
|
||||
return new MaskBuilder();
|
||||
}
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ namespace Symfony\Component\Security\Acl\Permission;
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
class MaskBuilder
|
||||
class MaskBuilder extends AbstractMaskBuilder
|
||||
{
|
||||
const MASK_VIEW = 1; // 1 << 0
|
||||
const MASK_CREATE = 2; // 1 << 1
|
||||
@ -67,50 +67,6 @@ class MaskBuilder
|
||||
const OFF = '.';
|
||||
const ON = '*';
|
||||
|
||||
private $mask;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param int $mask optional; defaults to 0
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function __construct($mask = 0)
|
||||
{
|
||||
if (!is_int($mask)) {
|
||||
throw new \InvalidArgumentException('$mask must be an integer.');
|
||||
}
|
||||
|
||||
$this->mask = $mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a mask to the permission.
|
||||
*
|
||||
* @param mixed $mask
|
||||
*
|
||||
* @return MaskBuilder
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function add($mask)
|
||||
{
|
||||
$this->mask |= $this->getMask($mask);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the mask of this permission.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function get()
|
||||
{
|
||||
return $this->mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a human-readable representation of the permission.
|
||||
*
|
||||
@ -135,34 +91,6 @@ class MaskBuilder
|
||||
return $pattern;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a mask from the permission.
|
||||
*
|
||||
* @param mixed $mask
|
||||
*
|
||||
* @return MaskBuilder
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function remove($mask)
|
||||
{
|
||||
$this->mask &= ~$this->getMask($mask);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the PermissionBuilder.
|
||||
*
|
||||
* @return MaskBuilder
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
$this->mask = 0;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the code for the passed mask.
|
||||
*
|
||||
@ -204,7 +132,7 @@ class MaskBuilder
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
private function getMask($code)
|
||||
public function resolveMask($code)
|
||||
{
|
||||
if (is_string($code)) {
|
||||
if (!defined($name = sprintf('static::MASK_%s', strtoupper($code)))) {
|
||||
|
@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Security\Acl\Permission;
|
||||
|
||||
/**
|
||||
* This is the interface that must be implemented by mask builders.
|
||||
*/
|
||||
interface MaskBuilderInterface
|
||||
{
|
||||
/**
|
||||
* Set the mask of this permission
|
||||
*
|
||||
* @param int $mask
|
||||
*
|
||||
* @return MaskBuilderInterface
|
||||
* @throws \InvalidArgumentException if $mask is not an integer
|
||||
*/
|
||||
public function set($mask);
|
||||
|
||||
/**
|
||||
* Returns the mask of this permission.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function get();
|
||||
|
||||
/**
|
||||
* Adds a mask to the permission.
|
||||
*
|
||||
* @param mixed $mask
|
||||
*
|
||||
* @return MaskBuilderInterface
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function add($mask);
|
||||
|
||||
/**
|
||||
* Removes a mask from the permission.
|
||||
*
|
||||
* @param mixed $mask
|
||||
*
|
||||
* @return MaskBuilderInterface
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function remove($mask);
|
||||
|
||||
/**
|
||||
* Resets the PermissionBuilder.
|
||||
*
|
||||
* @return MaskBuilderInterface
|
||||
*/
|
||||
public function reset();
|
||||
|
||||
/**
|
||||
* Returns the mask for the passed code
|
||||
*
|
||||
* @param mixed $code
|
||||
*
|
||||
* @return int
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function resolveMask($code);
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Security\Acl\Permission;
|
||||
|
||||
/**
|
||||
* Retrieves the MaskBuilder
|
||||
*/
|
||||
interface MaskBuilderRetrievalInterface
|
||||
{
|
||||
/**
|
||||
* Returns a new instance of the MaskBuilder used in the permissionMap
|
||||
*
|
||||
* @return MaskBuilderInterface
|
||||
*/
|
||||
public function getMaskBuilder();
|
||||
}
|
@ -6,6 +6,9 @@ CHANGELOG
|
||||
|
||||
* added LogoutUrlGenerator
|
||||
* added the triggering of the `Symfony\Component\Security\Http\SecurityEvents::INTERACTIVE_LOGIN` in `Symfony\Component\Security\Http\Firewall\SimplePreAuthenticationListener`
|
||||
* The MaskBuilder logic has been abstracted in the `Symfony\Component\Security\Acl\Permission\AbstractMaskBuilder`
|
||||
and described in the `Symfony\Component\Security\Acl\Permission\MaskBuilderInterface`
|
||||
* added interface `Symfony\Component\Security\Acl\Permission\MaskBuilderRetrievalInterface`
|
||||
|
||||
2.6.0
|
||||
-----
|
||||
|
Reference in New Issue
Block a user