Completed
Pull Request — 3.x (#6161)
by
unknown
02:56
created

AdminAclManipulator   A

Complexity

Total Complexity 17

Size/Duplication

Total Lines 96
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 6

Importance

Changes 0
Metric Value
dl 0
loc 96
c 0
b 0
f 0
wmc 17
lcom 1
cbo 6
rs 10

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A configureAcls() 0 27 5
C addAdminClassAces() 0 52 11
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the Sonata Project package.
7
 *
8
 * (c) Thomas Rabaix <[email protected]>
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Sonata\AdminBundle\Util;
15
16
use Sonata\AdminBundle\Admin\AdminInterface;
17
use Sonata\AdminBundle\Security\Handler\AclSecurityHandlerInterface;
18
use Symfony\Component\Console\Output\OutputInterface;
19
use Symfony\Component\Security\Acl\Domain\ObjectIdentity;
20
use Symfony\Component\Security\Acl\Domain\RoleSecurityIdentity;
21
use Symfony\Component\Security\Acl\Model\AclInterface;
22
use Symfony\Component\Security\Acl\Model\MutableAclInterface;
23
24
/**
25
 * @final since sonata-project/admin-bundle 3.52
26
 *
27
 * @author Thomas Rabaix <[email protected]>
28
 */
29
class AdminAclManipulator implements AdminAclManipulatorInterface
30
{
31
    /**
32
     * @var string
33
     */
34
    protected $maskBuilderClass;
35
36
    /**
37
     * @param string $maskBuilderClass
38
     */
39
    public function __construct($maskBuilderClass)
40
    {
41
        $this->maskBuilderClass = $maskBuilderClass;
42
    }
43
44
    public function configureAcls(OutputInterface $output, AdminInterface $admin)
45
    {
46
        $securityHandler = $admin->getSecurityHandler();
47
        if (!$securityHandler instanceof AclSecurityHandlerInterface) {
48
            $output->writeln(sprintf('Admin `%s` is not configured to use ACL : <info>ignoring</info>', $admin->getCode()));
49
50
            return;
51
        }
52
53
        $objectIdentity = ObjectIdentity::fromDomainObject($admin);
54
        $newAcl = false;
55
        if (null === ($acl = $securityHandler->getObjectAcl($objectIdentity))) {
56
            $acl = $securityHandler->createAcl($objectIdentity);
57
            $newAcl = true;
58
        }
59
60
        // create admin ACL
61
        $output->writeln(sprintf(' > install ACL for %s', $admin->getCode()));
62
        $configResult = $this->addAdminClassAces($output, $acl, $securityHandler, $securityHandler->buildSecurityInformation($admin));
63
64
        if ($configResult) {
65
            $securityHandler->updateAcl($acl);
66
        } else {
67
            $output->writeln(sprintf('   - %s , no roles and permissions found', ($newAcl ? 'skip' : 'removed')));
68
            $securityHandler->deleteAcl($objectIdentity);
69
        }
70
    }
71
72
    public function addAdminClassAces(
73
        OutputInterface $output,
74
        AclInterface $acl,
75
        AclSecurityHandlerInterface $securityHandler,
76
        array $roleInformation = []
77
    ) {
78
        if (!$acl instanceof MutableAclInterface) {
79
            throw new \InvalidArgumentException('$acl must implement '.MutableAclInterface::class);
80
        }
81
        if (\count($securityHandler->getAdminPermissions()) > 0) {
82
            $builder = new $this->maskBuilderClass();
83
84
            foreach ($roleInformation as $role => $permissions) {
85
                $aceIndex = $securityHandler->findClassAceIndexByRole($acl, $role);
86
                $roleAdminPermissions = [];
87
88
                foreach ($permissions as $permission) {
89
                    // add only the admin permissions
90
                    if (\in_array($permission, $securityHandler->getAdminPermissions(), true)) {
91
                        $builder->add($permission);
92
                        $roleAdminPermissions[] = $permission;
93
                    }
94
                }
95
96
                if (\count($roleAdminPermissions) > 0) {
97
                    if (false === $aceIndex) {
98
                        $acl->insertClassAce(new RoleSecurityIdentity($role), $builder->get());
99
                        $action = 'add';
100
                    } else {
101
                        $acl->updateClassAce($aceIndex, $builder->get());
102
                        $action = 'update';
103
                    }
104
105
                    if (null !== $output) {
106
                        $output->writeln(sprintf('   - %s role: %s, permissions: %s', $action, $role, json_encode($roleAdminPermissions)));
107
                    }
108
109
                    $builder->reset();
110
                } elseif (false !== $aceIndex) {
111
                    $acl->deleteClassAce($aceIndex);
112
113
                    if (null !== $output) {
114
                        $output->writeln(sprintf('   - remove role: %s', $role));
115
                    }
116
                }
117
            }
118
119
            return true;
120
        }
121
122
        return false;
123
    }
124
}
125