Passed
Push — master ( 6556ee...887ac8 )
by Jan
12:04
created

StructureVoter   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 75
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 26
c 2
b 0
f 0
dl 0
loc 75
rs 10
wmc 10

3 Methods

Rating   Name   Duplication   Size   Complexity  
A supports() 0 9 4
A instanceToPermissionName() 0 20 5
A voteOnUser() 0 5 1
1
<?php
2
/**
3
 * This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
4
 *
5
 * Copyright (C) 2019 - 2020 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
declare(strict_types=1);
22
23
/**
24
 * This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
25
 *
26
 * Copyright (C) 2019 Jan Böhmer (https://github.com/jbtronics)
27
 *
28
 * This program is free software; you can redistribute it and/or
29
 * modify it under the terms of the GNU General Public License
30
 * as published by the Free Software Foundation; either version 2
31
 * of the License, or (at your option) any later version.
32
 *
33
 * This program is distributed in the hope that it will be useful,
34
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
35
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
36
 * GNU General Public License for more details.
37
 *
38
 * You should have received a copy of the GNU General Public License
39
 * along with this program; if not, write to the Free Software
40
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
41
 */
42
43
namespace App\Security\Voter;
44
45
use App\Entity\Attachments\AttachmentType;
46
use App\Entity\Devices\Device;
47
use App\Entity\Parts\Category;
48
use App\Entity\Parts\Footprint;
49
use App\Entity\Parts\Manufacturer;
50
use App\Entity\Parts\MeasurementUnit;
51
use App\Entity\Parts\Storelocation;
52
use App\Entity\Parts\Supplier;
53
use App\Entity\PriceInformations\Currency;
54
use App\Entity\UserSystem\User;
55
56
use function get_class;
57
use function is_object;
58
59
class StructureVoter extends ExtendedVoter
60
{
61
    protected const OBJ_PERM_MAP = [
62
        AttachmentType::class => 'attachment_type',
63
        Category::class => 'categories',
64
        Device::class => 'devices',
65
        Footprint::class => 'footprints',
66
        Manufacturer::class => 'manufacturers',
67
        Storelocation::class => 'storelocations',
68
        Supplier::class => 'suppliers',
69
        Currency::class => 'currencies',
70
        MeasurementUnit::class => 'measurement_units',
71
    ];
72
73
    /**
74
     * Determines if the attribute and subject are supported by this voter.
75
     *
76
     * @param string $attribute An attribute
77
     * @param mixed  $subject   The subject to secure, e.g. an object the user wants to access or any other PHP type
78
     *
79
     * @return bool True if the attribute and subject are supported, false otherwise
80
     */
81
    protected function supports($attribute, $subject)
82
    {
83
        if (is_object($subject) || is_string($subject)) {
84
            $permission_name = $this->instanceToPermissionName($subject);
85
            //If permission name is null, then the subject is not supported
86
            return (null !== $permission_name) && $this->resolver->isValidOperation($permission_name, $attribute);
87
        }
88
89
        return false;
90
    }
91
92
    /**
93
     * Maps a instance type to the permission name.
94
     *
95
     * @param object|string $subject The subject for which the permission name should be generated
96
     *
97
     * @return string|null the name of the permission for the subject's type or null, if the subject is not supported
98
     */
99
    protected function instanceToPermissionName($subject): ?string
100
    {
101
        if (! is_string($subject)) {
102
            $class_name = get_class($subject);
103
        } else {
104
            $class_name = $subject;
105
        }
106
107
        //If it is existing in index, we can skip the loop
108
        if (isset(static::OBJ_PERM_MAP[$class_name])) {
109
            return static::OBJ_PERM_MAP[$class_name];
110
        }
111
112
        foreach (static::OBJ_PERM_MAP as $class => $ret) {
113
            if (is_a($class_name, $class, true)) {
114
                return $ret;
115
            }
116
        }
117
118
        return null;
119
    }
120
121
    /**
122
     * Similar to voteOnAttribute, but checking for the anonymous user is already done.
123
     * The current user (or the anonymous user) is passed by $user.
124
     *
125
     * @param string $attribute
126
     *
127
     * @return bool
128
     */
129
    protected function voteOnUser($attribute, $subject, User $user): bool
130
    {
131
        $permission_name = $this->instanceToPermissionName($subject);
132
        //Just resolve the permission
133
        return $this->resolver->inherit($user, $permission_name, $attribute) ?? false;
0 ignored issues
show
Bug introduced by
It seems like $permission_name can also be of type null; however, parameter $permission of App\Services\PermissionResolver::inherit() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

133
        return $this->resolver->inherit($user, /** @scrutinizer ignore-type */ $permission_name, $attribute) ?? false;
Loading history...
134
    }
135
}
136