StructureVoter::instanceToPermissionName()   A
last analyzed

Complexity

Conditions 5
Paths 8

Size

Total Lines 20
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 10
c 0
b 0
f 0
nc 8
nop 1
dl 0
loc 20
rs 9.6111
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
declare(strict_types=1);
22
23
namespace App\Security\Voter;
24
25
use App\Entity\Attachments\AttachmentType;
26
use App\Entity\ProjectSystem\Project;
27
use App\Entity\Parts\Category;
28
use App\Entity\Parts\Footprint;
29
use App\Entity\Parts\Manufacturer;
30
use App\Entity\Parts\MeasurementUnit;
31
use App\Entity\Parts\Storelocation;
32
use App\Entity\Parts\Supplier;
33
use App\Entity\PriceInformations\Currency;
34
use App\Entity\UserSystem\User;
35
use function get_class;
36
use function is_object;
37
38
class StructureVoter extends ExtendedVoter
39
{
40
    protected const OBJ_PERM_MAP = [
41
        AttachmentType::class => 'attachment_types',
42
        Category::class => 'categories',
43
        Project::class => 'projects',
44
        Footprint::class => 'footprints',
45
        Manufacturer::class => 'manufacturers',
46
        Storelocation::class => 'storelocations',
47
        Supplier::class => 'suppliers',
48
        Currency::class => 'currencies',
49
        MeasurementUnit::class => 'measurement_units',
50
    ];
51
52
    /**
53
     * Determines if the attribute and subject are supported by this voter.
54
     *
55
     * @param  string  $attribute An attribute
56
     * @param mixed  $subject   The subject to secure, e.g. an object the user wants to access or any other PHP type
57
     *
58
     * @return bool True if the attribute and subject are supported, false otherwise
59
     */
60
    protected function supports(string $attribute, $subject): bool
61
    {
62
        if (is_object($subject) || is_string($subject)) {
63
            $permission_name = $this->instanceToPermissionName($subject);
64
            //If permission name is null, then the subject is not supported
65
            return (null !== $permission_name) && $this->resolver->isValidOperation($permission_name, $attribute);
66
        }
67
68
        return false;
69
    }
70
71
    /**
72
     * Maps a instance type to the permission name.
73
     *
74
     * @param object|string $subject The subject for which the permission name should be generated
75
     *
76
     * @return string|null the name of the permission for the subject's type or null, if the subject is not supported
77
     */
78
    protected function instanceToPermissionName($subject): ?string
79
    {
80
        if (!is_string($subject)) {
81
            $class_name = get_class($subject);
82
        } else {
83
            $class_name = $subject;
84
        }
85
86
        //If it is existing in index, we can skip the loop
87
        if (isset(static::OBJ_PERM_MAP[$class_name])) {
88
            return static::OBJ_PERM_MAP[$class_name];
89
        }
90
91
        foreach (static::OBJ_PERM_MAP as $class => $ret) {
92
            if (is_a($class_name, $class, true)) {
93
                return $ret;
94
            }
95
        }
96
97
        return null;
98
    }
99
100
    /**
101
     * Similar to voteOnAttribute, but checking for the anonymous user is already done.
102
     * The current user (or the anonymous user) is passed by $user.
103
     *
104
     * @param  string  $attribute
105
     */
106
    protected function voteOnUser(string $attribute, $subject, User $user): bool
107
    {
108
        $permission_name = $this->instanceToPermissionName($subject);
109
        //Just resolve the permission
110
        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\UserSystem\...ssionManager::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

110
        return $this->resolver->inherit($user, /** @scrutinizer ignore-type */ $permission_name, $attribute) ?? false;
Loading history...
111
    }
112
}
113