Passed
Push — master ( ab3f5d...01e1f2 )
by Jan
02:56
created

PermissionResolver::isValidPermission()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
rs 10
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 Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
39
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
40
use Symfony\Component\Config\Definition\Processor;
41
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
42
use Symfony\Component\Yaml\Yaml;
43
44
class PermissionResolver
45
{
46
    protected $permission_structure;
47
48
49
    /**
50
     *
51
     * PermissionResolver constructor.
52
     * @param ParameterBagInterface $params
53
     */
54
    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

54
    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...
55
    {
56
        //Read the permission config file...
57
        $config = Yaml::parse(
58
            file_get_contents(__DIR__ . '/../../config/permissions.yaml')
59
        );
60
61
62
        $configs = [$config];
63
64
        //... And parse it
65
        $processor = new Processor();
66
        $databaseConfiguration = new PermissionsConfiguration();
67
        $processedConfiguration = $processor->processConfiguration(
68
            $databaseConfiguration,
69
            $configs
70
        );
71
72
        $this->permission_structure = $processedConfiguration;
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
}