123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173 |
- <?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\Bundle\SecurityBundle\Command;
- use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
- use Symfony\Component\Console\Input\InputArgument;
- use Symfony\Component\Console\Input\InputInterface;
- use Symfony\Component\Console\Input\InputOption;
- use Symfony\Component\Console\Output\OutputInterface;
- use Symfony\Component\Security\Acl\Domain\ObjectIdentity;
- use Symfony\Component\Security\Acl\Domain\RoleSecurityIdentity;
- use Symfony\Component\Security\Acl\Domain\UserSecurityIdentity;
- use Symfony\Component\Security\Acl\Exception\AclAlreadyExistsException;
- use Symfony\Component\Security\Acl\Model\MutableAclProviderInterface;
- use Symfony\Component\Security\Acl\Permission\MaskBuilder;
- /**
- * Sets ACL for objects.
- *
- * @author Kévin Dunglas <kevin@les-tilleuls.coop>
- */
- class SetAclCommand extends ContainerAwareCommand
- {
- /**
- * {@inheritdoc}
- */
- public function isEnabled()
- {
- if (!$this->getContainer()->has('security.acl.provider')) {
- return false;
- }
- $provider = $this->getContainer()->get('security.acl.provider');
- if (!$provider instanceof MutableAclProviderInterface) {
- return false;
- }
- return parent::isEnabled();
- }
- /**
- * {@inheritdoc}
- */
- protected function configure()
- {
- $this
- ->setName('acl:set')
- ->setDescription('Sets ACL for objects')
- ->setHelp(<<<EOF
- The <info>%command.name%</info> command sets ACL.
- The ACL system must have been initialized with the <info>init:acl</info> command.
- To set <comment>VIEW</comment> and <comment>EDIT</comment> permissions for the user <comment>kevin</comment> on the instance of
- <comment>Acme\MyClass</comment> having the identifier <comment>42</comment>:
- <info>php %command.full_name% --user=Symfony/Component/Security/Core/User/User:kevin VIEW EDIT Acme/MyClass:42</info>
- Note that you can use <comment>/</comment> instead of <comment>\\ </comment>for the namespace delimiter to avoid any
- problem.
- To set permissions for a role, use the <info>--role</info> option:
- <info>php %command.full_name% --role=ROLE_USER VIEW Acme/MyClass:1936</info>
- To set permissions at the class scope, use the <info>--class-scope</info> option:
- <info>php %command.full_name% --class-scope --user=Symfony/Component/Security/Core/User/User:anne OWNER Acme/MyClass:42</info>
-
- EOF
- )
- ->addArgument('arguments', InputArgument::IS_ARRAY | InputArgument::REQUIRED, 'A list of permissions and object identities (class name and ID separated by a column)')
- ->addOption('user', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'A list of security identities')
- ->addOption('role', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'A list of roles')
- ->addOption('class-scope', null, InputOption::VALUE_NONE, 'Use class-scope entries')
- ;
- }
- /**
- * {@inheritdoc}
- */
- protected function execute(InputInterface $input, OutputInterface $output)
- {
- // Parse arguments
- $objectIdentities = array();
- $maskBuilder = $this->getMaskBuilder();
- foreach ($input->getArgument('arguments') as $argument) {
- $data = explode(':', $argument, 2);
- if (\count($data) > 1) {
- $objectIdentities[] = new ObjectIdentity($data[1], strtr($data[0], '/', '\\'));
- } else {
- $maskBuilder->add($data[0]);
- }
- }
- // Build permissions mask
- $mask = $maskBuilder->get();
- $userOption = $input->getOption('user');
- $roleOption = $input->getOption('role');
- $classScopeOption = $input->getOption('class-scope');
- if (empty($userOption) && empty($roleOption)) {
- throw new \InvalidArgumentException('A Role or a User must be specified.');
- }
- // Create security identities
- $securityIdentities = array();
- if ($userOption) {
- foreach ($userOption as $user) {
- $data = explode(':', $user, 2);
- if (1 === \count($data)) {
- throw new \InvalidArgumentException('The user must follow the format "Acme/MyUser:username".');
- }
- $securityIdentities[] = new UserSecurityIdentity($data[1], strtr($data[0], '/', '\\'));
- }
- }
- if ($roleOption) {
- foreach ($roleOption as $role) {
- $securityIdentities[] = new RoleSecurityIdentity($role);
- }
- }
- /** @var $container \Symfony\Component\DependencyInjection\ContainerInterface */
- $container = $this->getContainer();
- /** @var $aclProvider MutableAclProviderInterface */
- $aclProvider = $container->get('security.acl.provider');
- // Sets ACL
- foreach ($objectIdentities as $objectIdentity) {
- // Creates a new ACL if it does not already exist
- try {
- $aclProvider->createAcl($objectIdentity);
- } catch (AclAlreadyExistsException $e) {
- }
- $acl = $aclProvider->findAcl($objectIdentity, $securityIdentities);
- foreach ($securityIdentities as $securityIdentity) {
- if ($classScopeOption) {
- $acl->insertClassAce($securityIdentity, $mask);
- } else {
- $acl->insertObjectAce($securityIdentity, $mask);
- }
- }
- $aclProvider->updateAcl($acl);
- }
- }
- /**
- * Gets the mask builder.
- *
- * @return MaskBuilder
- */
- protected function getMaskBuilder()
- {
- return new MaskBuilder();
- }
- }
|