Passed
Push — master ( b9cd2f...6ed2ee )
by Jan
03:56
created

PermissionResolver::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 19
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 9
nc 1
nop 1
dl 0
loc 19
rs 9.9666
c 0
b 0
f 0
1
<?php
2
/**
3
 *
4
 * part-db version 0.1
5
 * Copyright (C) 2005 Christoph Lechner
6
 * http://www.cl-projects.de/
7
 *
8
 * part-db version 0.2+
9
 * Copyright (C) 2009 K. Jacobs and others (see authors.php)
10
 * http://code.google.com/p/part-db/
11
 *
12
 * Part-DB Version 0.4+
13
 * Copyright (C) 2016 - 2019 Jan Böhmer
14
 * https://github.com/jbtronics
15
 *
16
 * This program is free software; you can redistribute it and/or
17
 * modify it under the terms of the GNU General Public License
18
 * as published by the Free Software Foundation; either version 2
19
 * of the License, or (at your option) any later version.
20
 *
21
 * This program is distributed in the hope that it will be useful,
22
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24
 * GNU General Public License for more details.
25
 *
26
 * You should have received a copy of the GNU General Public License
27
 * along with this program; if not, write to the Free Software
28
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
29
 *
30
 */
31
32
namespace App\Services;
33
34
35
use App\Configuration\PermissionsConfiguration;
36
use App\Entity\User;
37
use App\Security\Interfaces\HasPermissionsInterface;
38
use Symfony\Component\Config\Definition\Processor;
39
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
40
use Symfony\Component\Yaml\Yaml;
41
42
class PermissionResolver
43
{
44
    protected $permission_structure;
45
46
47
    /**
48
     *
49
     * PermissionResolver constructor.
50
     * @param ParameterBagInterface $params
51
     */
52
    public function __construct(ParameterBagInterface $params)
0 ignored issues
show
Unused Code introduced by
The parameter $params is not used and could be removed. ( Ignorable by Annotation )

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

52
    public function __construct(/** @scrutinizer ignore-unused */ ParameterBagInterface $params)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
53
    {
54
        //Read the permission config file...
55
        $config = Yaml::parse(
56
            file_get_contents(__DIR__ . '/../../config/permissions.yaml')
57
        );
58
59
60
        $configs = [$config];
61
62
        //... And parse it
63
        $processor = new Processor();
64
        $databaseConfiguration = new PermissionsConfiguration();
65
        $processedConfiguration = $processor->processConfiguration(
66
            $databaseConfiguration,
67
            $configs
68
        );
69
70
        $this->permission_structure = $processedConfiguration;
71
72
        //dump($this->permission_structure);
73
    }
74
75
76
    /**
77
     * Check if a user/group is allowed to do the specified operation for the permission.
78
     *
79
     * See permissions.yaml for valid permission operation combinations.
80
     *
81
     * @param HasPermissionsInterface $user The user/group for which the operation should be checked.
82
     * @param string $permission The name of the permission for which should be checked.
83
     * @param string $operation The name of the operation for which should be checked.
84
     * @return bool|null True, if the user is allowed to do the operation (ALLOW), false if not (DISALLOW), and null,
85
     * if the value is set to inherit.
86
     */
87
    public function dontInherit(HasPermissionsInterface $user, string $permission, string $operation) : ?bool
88
    {
89
        //Get the permissions from the user
90
        $perm_list = $user->getPermissions();
91
92
        //Determine bit number using our configuration
93
        $bit = $this->permission_structure['perms'][$permission]['operations'][$operation]['bit'];
94
95
        return $perm_list->getPermissionValue($permission, $bit);
96
    }
97
98
99
    /**
100
     * Checks if a user is allowed to do the specified operation for the permission.
101
     * In contrast to dontInherit() it tries to resolve the inherit values, of the user, by going upwards in the
102
     * hierachy (user -> group -> parent group -> so on). But even in this case it is possible, that the inherit value
103
     * could be resolved, and this function returns null.
104
     *
105
     * In that case the voter should set it manually to false by using ?? false.
106
     *
107
     * @param User $user The user for which the operation should be checked.
108
     * @param string $permission The name of the permission for which should be checked.
109
     * @param string $operation The name of the operation for which should be checked.
110
     * @return bool|null True, if the user is allowed to do the operation (ALLOW), false if not (DISALLOW), and null,
111
     * if the value is set to inherit.
112
     */
113
    public function inherit(User $user, string $permission, string $operation) : ?bool
114
    {
115
        //Check if we need to inherit
116
        $allowed = $this->dontInherit($user, $permission, $operation);
117
118
        if ($allowed !== null) {
119
            //Just return the value of the user.
120
            return $allowed;
121
        }
122
123
        $parent = $user->getGroup();
124
        while($parent != null){ //The top group, has parent == null
125
            //Check if our current element gives a info about disallow/allow
126
            $allowed = $this->dontInherit($parent, $permission, $operation);
127
            if ($allowed !== null) {
128
                return $allowed;
129
            }
130
            //Else go up in the hierachy.
131
            $parent = $parent->getParent();
132
        }
133
134
        return null; //The inherited value is never resolved. Should be treat as false, in Voters.
135
    }
136
137
138
    /**
139
     * Lists the names of all operations that is supported for the given permission.
140
     *
141
     * If the Permission is not existing at all, a exception is thrown.
142
     *
143
     * This function is useful for the support() function of the voters.
144
     *
145
     * @param string $permission The permission for which the
146
     * @return string[] A list of all operations that are supported by the given
147
     */
148
    public function listOperationsForPermission(string $permission) : array
149
    {
150
        $operations = $this->permission_structure['perms'][$permission]['operations'];
151
152
        return array_keys($operations);
153
    }
154
155
    /**
156
     * Checks if the permission with the given name is existing.
157
     *
158
     * @param string $permission The name of the permission which we want to check.
159
     * @return bool True if a perm with that name is existing. False if not.
160
     */
161
    public function isValidPermission(string $permission) : bool
162
    {
163
        return isset($this->permission_structure['perms'][$permission]);
164
    }
165
166
    /**
167
     * Checks if the permission operation combination with the given names is existing.
168
     *
169
     * @param string $permission The name of the permission which should be checked.
170
     * @param string $operation The name of the operation which should be checked.
171
     * @return bool True if the given permission operation combination is existing.
172
     */
173
    public function isValidOperation(string $permission, string $operation) : bool
174
    {
175
        return $this->isValidPermission($permission) &&
176
            isset($this->permission_structure['perms'][$permission]['operations'][$operation]);
177
    }
178
179
180
}