ParameterVoter::voteOnUser()   D
last analyzed

Complexity

Conditions 21
Paths 21

Size

Total Lines 67
Code Lines 48

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 21
eloc 48
c 1
b 0
f 0
nc 21
nop 3
dl 0
loc 67
rs 4.1666

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/*
3
 * This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
4
 *
5
 *  Copyright (C) 2019 - 2022 Jan Böhmer (https://github.com/jbtronics)
6
 *
7
 *  This program is free software: you can redistribute it and/or modify
8
 *  it under the terms of the GNU Affero General Public License as published
9
 *  by the Free Software Foundation, either version 3 of the License, or
10
 *  (at your option) any later version.
11
 *
12
 *  This program is distributed in the hope that it will be useful,
13
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 *  GNU Affero General Public License for more details.
16
 *
17
 *  You should have received a copy of the GNU Affero General Public License
18
 *  along with this program.  If not, see <https://www.gnu.org/licenses/>.
19
 */
20
21
namespace App\Security\Voter;
22
23
use App\Entity\Parameters\AbstractParameter;
24
use App\Entity\Parameters\AttachmentTypeParameter;
25
use App\Entity\Parameters\CategoryParameter;
26
use App\Entity\Parameters\CurrencyParameter;
27
use App\Entity\Parameters\ProjectParameter;
28
use App\Entity\Parameters\FootprintParameter;
29
use App\Entity\Parameters\GroupParameter;
30
use App\Entity\Parameters\ManufacturerParameter;
31
use App\Entity\Parameters\MeasurementUnitParameter;
32
use App\Entity\Parameters\PartParameter;
33
use App\Entity\Parameters\StorelocationParameter;
34
use App\Entity\Parameters\SupplierParameter;
35
use App\Entity\UserSystem\User;
36
use App\Services\UserSystem\PermissionManager;
37
use Doctrine\ORM\EntityManagerInterface;
38
use RuntimeException;
39
use Symfony\Component\Security\Core\Security;
40
41
class ParameterVoter extends ExtendedVoter
42
{
43
44
    protected Security $security;
45
46
    public function __construct(PermissionManager $resolver, EntityManagerInterface $entityManager, Security $security)
47
    {
48
        $this->security = $security;
49
        parent::__construct($resolver, $entityManager);
50
    }
51
52
    protected function voteOnUser(string $attribute, $subject, User $user): bool
53
    {
54
        //return $this->resolver->inherit($user, 'attachments', $attribute) ?? false;
55
56
        if (!$subject instanceof AbstractParameter) {
57
            return false;
58
        }
59
60
        //If the attachment has no element (which should not happen), we deny access, as we can not determine if the user is allowed to access the associated element
61
        $target_element = $subject->getElement();
62
        if ($target_element !== null) {
63
            //Depending on the operation delegate either to the attachments element or to the attachment permission
64
65
66
            switch ($attribute) {
67
                //We can view the attachment if we can view the element
68
                case 'read':
69
                case 'view':
70
                    $operation = 'read';
71
                    break;
72
                //We can edit/create/delete the attachment if we can edit the element
73
                case 'edit':
74
                case 'create':
75
                case 'delete':
76
                    $operation = 'edit';
77
                    break;
78
                case 'show_history':
79
                    $operation = 'show_history';
80
                    break;
81
                case 'revert_element':
82
                    $operation = 'revert_element';
83
                    break;
84
                default:
85
                    throw new RuntimeException('Unknown operation: '.$attribute);
86
            }
87
88
            return $this->security->isGranted($operation, $target_element);
89
        }
90
91
        //If we do not have a concrete element, we delegate to the different categories
92
        if ($subject instanceof AttachmentTypeParameter) {
93
            $param = 'attachment_types';
94
        } elseif ($subject instanceof CategoryParameter) {
95
            $param = 'categories';
96
        } elseif ($subject instanceof CurrencyParameter) {
97
            $param = 'currencies';
98
        } elseif ($subject instanceof ProjectParameter) {
99
            $param = 'projects';
100
        } elseif ($subject instanceof FootprintParameter) {
101
            $param = 'footprints';
102
        } elseif ($subject instanceof GroupParameter) {
103
            $param = 'groups';
104
        } elseif ($subject instanceof ManufacturerParameter) {
105
            $param = 'manufacturers';
106
        } elseif ($subject instanceof MeasurementUnitParameter) {
107
            $param = 'measurement_units';
108
        } elseif ($subject instanceof PartParameter) {
109
            $param = 'parts';
110
        } elseif ($subject instanceof StorelocationParameter) {
111
            $param = 'storelocations';
112
        } elseif ($subject instanceof SupplierParameter) {
113
            $param = 'suppliers';
114
        } else {
115
            throw new RuntimeException('Encountered unknown Parameter type: ' . get_class($subject));
116
        }
117
118
        return $this->resolver->inherit($user, $param, $attribute) ?? false;
119
    }
120
121
    protected function supports(string $attribute, $subject)
122
    {
123
        if (is_a($subject, AbstractParameter::class, true)) {
124
            //These are the allowed attributes
125
            return in_array($attribute, ['read', 'edit', 'delete', 'create', 'show_history', 'revert_element'], true);
126
        }
127
128
        //Allow class name as subject
129
        return false;
130
    }
131
}