Actualización

This commit is contained in:
Xes
2025-04-10 12:24:57 +02:00
parent 8969cc929d
commit 45420b6f0d
39760 changed files with 4303286 additions and 0 deletions

View File

@@ -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;
}
}

View File

@@ -0,0 +1,116 @@
<?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 basic permission map complements the masks which have been defined
* on the standard implementation of the MaskBuilder.
*
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
*/
class BasicPermissionMap implements PermissionMapInterface, MaskBuilderRetrievalInterface
{
const PERMISSION_VIEW = 'VIEW';
const PERMISSION_EDIT = 'EDIT';
const PERMISSION_CREATE = 'CREATE';
const PERMISSION_DELETE = 'DELETE';
const PERMISSION_UNDELETE = 'UNDELETE';
const PERMISSION_OPERATOR = 'OPERATOR';
const PERMISSION_MASTER = 'MASTER';
const PERMISSION_OWNER = 'OWNER';
protected $map;
public function __construct()
{
$this->map = array(
self::PERMISSION_VIEW => array(
MaskBuilder::MASK_VIEW,
MaskBuilder::MASK_EDIT,
MaskBuilder::MASK_OPERATOR,
MaskBuilder::MASK_MASTER,
MaskBuilder::MASK_OWNER,
),
self::PERMISSION_EDIT => array(
MaskBuilder::MASK_EDIT,
MaskBuilder::MASK_OPERATOR,
MaskBuilder::MASK_MASTER,
MaskBuilder::MASK_OWNER,
),
self::PERMISSION_CREATE => array(
MaskBuilder::MASK_CREATE,
MaskBuilder::MASK_OPERATOR,
MaskBuilder::MASK_MASTER,
MaskBuilder::MASK_OWNER,
),
self::PERMISSION_DELETE => array(
MaskBuilder::MASK_DELETE,
MaskBuilder::MASK_OPERATOR,
MaskBuilder::MASK_MASTER,
MaskBuilder::MASK_OWNER,
),
self::PERMISSION_UNDELETE => array(
MaskBuilder::MASK_UNDELETE,
MaskBuilder::MASK_OPERATOR,
MaskBuilder::MASK_MASTER,
MaskBuilder::MASK_OWNER,
),
self::PERMISSION_OPERATOR => array(
MaskBuilder::MASK_OPERATOR,
MaskBuilder::MASK_MASTER,
MaskBuilder::MASK_OWNER,
),
self::PERMISSION_MASTER => array(
MaskBuilder::MASK_MASTER,
MaskBuilder::MASK_OWNER,
),
self::PERMISSION_OWNER => array(
MaskBuilder::MASK_OWNER,
),
);
}
/**
* {@inheritdoc}
*/
public function getMasks($permission, $object)
{
if (!isset($this->map[$permission])) {
return;
}
return $this->map[$permission];
}
/**
* {@inheritdoc}
*/
public function contains($permission)
{
return isset($this->map[$permission]);
}
/**
* {@inheritdoc}
*/
public function getMaskBuilder()
{
return new MaskBuilder();
}
}

View File

@@ -0,0 +1,151 @@
<?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 class allows you to build cumulative permissions easily, or convert
* masks to a human-readable format.
*
* <code>
* $builder = new MaskBuilder();
* $builder
* ->add('view')
* ->add('create')
* ->add('edit')
* ;
* var_dump($builder->get()); // int(7)
* var_dump($builder->getPattern()); // string(32) ".............................ECV"
* </code>
*
* We have defined some commonly used base permissions which you can use:
* - VIEW: the SID is allowed to view the domain object / field
* - CREATE: the SID is allowed to create new instances of the domain object / fields
* - EDIT: the SID is allowed to edit existing instances of the domain object / field
* - DELETE: the SID is allowed to delete domain objects
* - UNDELETE: the SID is allowed to recover domain objects from trash
* - OPERATOR: the SID is allowed to perform any action on the domain object
* except for granting others permissions
* - MASTER: the SID is allowed to perform any action on the domain object,
* and is allowed to grant other SIDs any permission except for
* MASTER and OWNER permissions
* - OWNER: the SID is owning the domain object in question and can perform any
* action on the domain object as well as grant any permission
*
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
*/
class MaskBuilder extends AbstractMaskBuilder
{
const MASK_VIEW = 1; // 1 << 0
const MASK_CREATE = 2; // 1 << 1
const MASK_EDIT = 4; // 1 << 2
const MASK_DELETE = 8; // 1 << 3
const MASK_UNDELETE = 16; // 1 << 4
const MASK_OPERATOR = 32; // 1 << 5
const MASK_MASTER = 64; // 1 << 6
const MASK_OWNER = 128; // 1 << 7
const MASK_IDDQD = 1073741823; // 1 << 0 | 1 << 1 | ... | 1 << 30
const CODE_VIEW = 'V';
const CODE_CREATE = 'C';
const CODE_EDIT = 'E';
const CODE_DELETE = 'D';
const CODE_UNDELETE = 'U';
const CODE_OPERATOR = 'O';
const CODE_MASTER = 'M';
const CODE_OWNER = 'N';
const ALL_OFF = '................................';
const OFF = '.';
const ON = '*';
/**
* Returns a human-readable representation of the permission.
*
* @return string
*/
public function getPattern()
{
$pattern = self::ALL_OFF;
$length = strlen($pattern);
$bitmask = str_pad(decbin($this->mask), $length, '0', STR_PAD_LEFT);
for ($i = $length - 1; $i >= 0; --$i) {
if ('1' === $bitmask[$i]) {
try {
$pattern[$i] = self::getCode(1 << ($length - $i - 1));
} catch (\Exception $e) {
$pattern[$i] = self::ON;
}
}
}
return $pattern;
}
/**
* Returns the code for the passed mask.
*
* @param int $mask
*
* @throws \InvalidArgumentException
* @throws \RuntimeException
*
* @return string
*/
public static function getCode($mask)
{
if (!is_int($mask)) {
throw new \InvalidArgumentException('$mask must be an integer.');
}
$reflection = new \ReflectionClass(get_called_class());
foreach ($reflection->getConstants() as $name => $cMask) {
if (0 !== strpos($name, 'MASK_') || $mask !== $cMask) {
continue;
}
if (!defined($cName = 'static::CODE_'.substr($name, 5))) {
throw new \RuntimeException('There was no code defined for this mask.');
}
return constant($cName);
}
throw new \InvalidArgumentException(sprintf('The mask "%d" is not supported.', $mask));
}
/**
* Returns the mask for the passed code.
*
* @param mixed $code
*
* @return int
*
* @throws \InvalidArgumentException
*/
public function resolveMask($code)
{
if (is_string($code)) {
if (!defined($name = sprintf('static::MASK_%s', strtoupper($code)))) {
throw new \InvalidArgumentException(sprintf('The code "%s" is not supported', $code));
}
return constant($name);
}
if (!is_int($code)) {
throw new \InvalidArgumentException('$code must be an integer.');
}
return $code;
}
}

View File

@@ -0,0 +1,76 @@
<?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);
}

View File

@@ -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();
}

View File

@@ -0,0 +1,42 @@
<?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 permission maps.
*
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
*/
interface PermissionMapInterface
{
/**
* Returns an array of bitmasks.
*
* The security identity must have been granted access to at least one of
* these bitmasks.
*
* @param string $permission
* @param object $object
*
* @return array may return null if permission/object combination is not supported
*/
public function getMasks($permission, $object);
/**
* Whether this map contains the given permission.
*
* @param string $permission
*
* @return bool
*/
public function contains($permission);
}