Completed
Push — master ( 8fc13e...c19aa3 )
by Axel
06:21
created

PermissionController::deleteAction()   A

Complexity

Conditions 6
Paths 3

Size

Total Lines 22
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 12
nc 3
nop 2
dl 0
loc 22
rs 9.2222
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the Zikula package.
7
 *
8
 * Copyright Zikula Foundation - https://ziku.la/
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 Zikula\PermissionsModule\Controller;
15
16
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
17
use Symfony\Component\ErrorHandler\Error\FatalError;
18
use Symfony\Component\HttpFoundation\JsonResponse;
19
use Symfony\Component\HttpFoundation\Request;
20
use Symfony\Component\Routing\Annotation\Route;
21
use Zikula\Bundle\CoreBundle\Controller\AbstractController;
22
use Zikula\GroupsModule\Entity\RepositoryInterface\GroupRepositoryInterface;
23
use Zikula\PermissionsModule\Annotation\PermissionCheck;
24
use Zikula\PermissionsModule\Api\ApiInterface\PermissionApiInterface;
25
use Zikula\PermissionsModule\Entity\PermissionEntity;
26
use Zikula\PermissionsModule\Entity\RepositoryInterface\PermissionRepositoryInterface;
27
use Zikula\PermissionsModule\Form\Type\FilterListType;
28
use Zikula\PermissionsModule\Form\Type\PermissionCheckType;
29
use Zikula\PermissionsModule\Form\Type\PermissionType;
30
use Zikula\PermissionsModule\Helper\SchemaHelper;
31
use Zikula\ThemeModule\Engine\Annotation\Theme;
32
use Zikula\UsersModule\Constant;
33
use Zikula\UsersModule\Entity\RepositoryInterface\UserRepositoryInterface;
34
35
/**
36
 * @PermissionCheck("admin")
37
 */
38
class PermissionController extends AbstractController
39
{
40
    /**
41
     * @Route("/list")
42
     * @Theme("admin")
43
     * @Template("@ZikulaPermissionsModule/Permission/list.html.twig")
44
     *
45
     * View permissions.
46
     */
47
    public function listAction(
48
        GroupRepositoryInterface $groupsRepository,
49
        PermissionRepositoryInterface $permissionRepository,
50
        PermissionApiInterface $permissionApi,
51
        SchemaHelper $schemaHelper
52
    ): array {
53
        $groups = $groupsRepository->getGroupNamesById();
54
        $permissions = $permissionRepository->getFilteredPermissions();
55
        $components = [$this->trans('All components') => '-1'] + $permissionRepository->getAllComponents();
56
        $colours = [$this->trans('All colours') => '-1'] + $permissionRepository->getAllColours();
57
        $permissionLevels = $permissionApi->accessLevelNames();
58
59
        $filterForm = $this->createForm(FilterListType::class, [], [
60
            'groupChoices' => $groups,
61
            'componentChoices' => $components,
62
            'colourChoices' => $colours
63
        ]);
64
        $permissionCheckForm = $this->createForm(PermissionCheckType::class, [], [
65
            'permissionLevels' => $permissionLevels
66
        ]);
67
68
        return [
69
            'filterForm' => $filterForm->createView(),
70
            'permissionCheckForm' => $permissionCheckForm->createView(),
71
            'permissionLevels' => $permissionLevels,
72
            'permissions' => $permissions,
73
            'groups' => $groups,
74
            'lockadmin' => $this->getVar('lockadmin', 1) ? 1 : 0,
75
            'adminId' => $this->getVar('adminid', 1),
76
            'schema' => $schemaHelper->getAllSchema(),
77
            'enableFilter' => (bool)$this->getVar('filter', 1)
78
        ];
79
    }
80
81
    /**
82
     * @Route("/edit/{pid}", options={"expose"=true})
83
     */
84
    public function editAction(
85
        Request $request,
86
        GroupRepositoryInterface $groupsRepository,
87
        PermissionRepositoryInterface $permissionRepository,
88
        PermissionApiInterface $permissionApi,
89
        PermissionEntity $permissionEntity = null
90
    ): JsonResponse {
91
        if (!isset($permissionEntity)) {
92
            $permissionEntity = new PermissionEntity();
93
            if ($request->request->has('sequence')) {
94
                $permissionEntity->setSequence($request->request->getInt('sequence'));
95
            }
96
        }
97
98
        $groupNames = $groupsRepository->getGroupNamesById();
99
        $accessLevelNames = $permissionApi->accessLevelNames();
100
101
        $form = $this->createForm(PermissionType::class, $permissionEntity, [
102
            'groups' => $groupNames,
103
            'permissionLevels' => $accessLevelNames
104
        ]);
105
        $form->handleRequest($request);
106
        if ($form->isSubmitted() && $form->isValid()) {
107
            $permissionEntity = $form->getData();
108
            $pid = $permissionEntity->getPid();
109
            if (null === $pid) {
110
                if (-1 === $permissionEntity->getSequence()) {
111
                    $permissionEntity->setSequence($permissionRepository->getMaxSequence() + 1); // last
112
                } else {
113
                    $permissionRepository->updateSequencesFrom($permissionEntity->getSequence()); // insert
114
                }
115
            }
116
            $permissionRepository->persistAndFlush($permissionEntity);
117
            $row = null === $pid ? $this->renderView('@ZikulaPermissionsModule/Permission/permissionTableRow.html.twig', [
118
                'permission' => $permissionEntity,
119
                'groups' => $groupNames,
120
                'permissionLevels' => $accessLevelNames,
121
                'lockadmin' => $this->getVar('lockadmin', 1) ? 1 : 0,
122
                'adminId' => $this->getVar('adminid', 1)
123
            ]) : null;
124
125
            return $this->json([
126
                'permission' => $permissionEntity->toArray(),
127
                'row' => $row
128
            ]);
129
        }
130
        $templateParameters = [
131
            'form' => $form->createView()
132
        ];
133
        $view = $this->renderView('@ZikulaPermissionsModule/Permission/permission.html.twig', $templateParameters);
134
135
        return $this->json(['view' => $view]);
136
    }
137
138
    /**
139
     * @Route("/change-order", methods = {"POST"}, options={"expose"=true})
140
     *
141
     * Change the order of a permission rule.
142
     */
143
    public function changeOrderAction(
144
        Request $request,
145
        PermissionRepositoryInterface $permissionRepository
146
    ): JsonResponse {
147
        $permOrder = $request->request->get('permorder');
148
        $amountOfPermOrderValues = count($permOrder);
149
        for ($cnt = 0; $cnt < $amountOfPermOrderValues; $cnt++) {
150
            $permission = $permissionRepository->find($permOrder[$cnt]);
0 ignored issues
show
Bug introduced by
The method find() does not exist on Zikula\PermissionsModule...sionRepositoryInterface. It seems like you code against a sub-type of Zikula\PermissionsModule...sionRepositoryInterface such as Zikula\PermissionsModule...ry\PermissionRepository. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

150
            /** @scrutinizer ignore-call */ 
151
            $permission = $permissionRepository->find($permOrder[$cnt]);
Loading history...
151
            $permission['sequence'] = $cnt + 1;
152
        }
153
        $this->getDoctrine()->getManager()->flush();
154
155
        return $this->json(['result' => true]);
156
    }
157
158
    /**
159
     * @Route("/delete/{pid}", methods = {"POST"}, options={"expose"=true})
160
     *
161
     * Delete a permission.
162
     *
163
     * @throws FatalError Thrown if the requested permission rule is the default admin rule
164
     *                           or if the permission rule couldn't be deleted
165
     */
166
    public function deleteAction(
167
        PermissionEntity $permissionEntity,
168
        PermissionRepositoryInterface $permissionRepository
169
    ): JsonResponse {
170
        // check if this is the overall admin permission and return if this shall be deleted
171
        if (1 === $permissionEntity->getPid()
172
            && ACCESS_ADMIN === $permissionEntity->getLevel()
173
            && '.*' === $permissionEntity->getComponent()
174
            && '.*' === $permissionEntity->getInstance()
175
        ) {
176
            throw new FatalError($this->trans('Notice: You cannot delete the main administration permission rule.'));
0 ignored issues
show
Bug introduced by
The call to Symfony\Component\ErrorH...talError::__construct() has too few arguments starting with code. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

176
            throw /** @scrutinizer ignore-call */ new FatalError($this->trans('Notice: You cannot delete the main administration permission rule.'));

This check compares calls to functions or methods with their respective definitions. If the call has less arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
177
        }
178
179
        $this->getDoctrine()->getManager()->remove($permissionEntity);
180
        $this->getDoctrine()->getManager()->flush();
181
        $permissionRepository->reSequence();
182
        if ($permissionEntity->getPid() === $this->getVar('adminid')) {
183
            $this->setVar('adminid', 0);
184
            $this->setVar('lockadmin', false);
185
        }
186
187
        return $this->json(['pid' => $permissionEntity->getPid()]);
188
    }
189
190
    /**
191
     * @Route("/test", methods = {"POST"}, options={"expose"=true})
192
     *
193
     * Test a permission rule for a given username.
194
     */
195
    public function testAction(
196
        Request $request,
197
        PermissionApiInterface $permissionApi,
198
        UserRepositoryInterface $userRepository
199
    ): JsonResponse {
200
        $permissionCheckForm = $this->createForm(PermissionCheckType::class, [], [
201
            'permissionLevels' => $permissionApi->accessLevelNames()
202
        ]);
203
        $permissionCheckForm->handleRequest($request);
204
        $data = $permissionCheckForm->getData();
205
206
        $result = $this->trans('Permission check result:') . ' ';
207
        if (!empty($data['user'])) {
208
            $user = $userRepository->findOneBy(['uname' => $data['user']]);
209
            $uid = isset($user) ? $user->getUid() : Constant::USER_ID_ANONYMOUS;
210
        } else {
211
            $uid = Constant::USER_ID_ANONYMOUS;
212
        }
213
214
        if (false === $uid) {
215
            $result .= '<span class="text-danger">' . $this->trans('unknown user.') . '</span>';
216
        } else {
217
            $granted = $this->hasPermission($data['component'], $data['instance'], $data['level'], $uid);
218
219
            $result .= '<span class="' . ($granted ? 'text-success' : 'text-danger') . '">';
220
            $result .= (0 === $uid) ? $this->trans('unregistered user') : $data['user'];
221
            $result .= ': ';
222
            if ($granted) {
223
                $result .= $this->trans('permission granted.');
224
            } else {
225
                $result .= $this->trans('permission not granted.');
226
            }
227
            $result .= '</span>';
228
        }
229
230
        return $this->json(['testresult' => $result]);
231
    }
232
}
233