Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
100.00% |
40 / 40 |
|
100.00% |
6 / 6 |
CRAP | |
100.00% |
1 / 1 |
DynamicRoleProvider | |
100.00% |
40 / 40 |
|
100.00% |
6 / 6 |
20 | |
100.00% |
1 / 1 |
__construct | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
getRoles | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getRole | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
3 | |||
populateRoles | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
3 | |||
getPermissionsArray | |
100.00% |
10 / 10 |
|
100.00% |
1 / 1 |
6 | |||
getRolesForSettings | |
100.00% |
17 / 17 |
|
100.00% |
1 / 1 |
6 |
1 | <?php |
2 | |
3 | /** |
4 | * VuFind dynamic role provider. |
5 | * |
6 | * PHP version 8 |
7 | * |
8 | * Copyright (C) Villanova University 2007. |
9 | * |
10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of the GNU General Public License version 2, |
12 | * as published by the Free Software Foundation. |
13 | * |
14 | * This program is distributed in the hope that it will be useful, |
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
17 | * GNU General Public License for more details. |
18 | * |
19 | * You should have received a copy of the GNU General Public License |
20 | * along with this program; if not, write to the Free Software |
21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
22 | * |
23 | * @category VuFind |
24 | * @package Authorization |
25 | * @author Demian Katz <demian.katz@villanova.edu> |
26 | * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License |
27 | * @link https://vufind.org Main Page |
28 | */ |
29 | |
30 | namespace VuFind\Role; |
31 | |
32 | use LmcRbacMvc\Role\RoleProviderInterface; |
33 | use Rbac\Role\Role; |
34 | |
35 | /** |
36 | * VuFind dynamic role provider. |
37 | * |
38 | * @category VuFind |
39 | * @package Authorization |
40 | * @author Demian Katz <demian.katz@villanova.edu> |
41 | * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License |
42 | * @link https://vufind.org Main Page |
43 | */ |
44 | class DynamicRoleProvider implements RoleProviderInterface |
45 | { |
46 | /** |
47 | * Cache of role objects. |
48 | * |
49 | * @var array |
50 | */ |
51 | protected $roles = false; |
52 | |
53 | /** |
54 | * Permission provider manager |
55 | * |
56 | * @var PermissionProviderPluginManager |
57 | */ |
58 | protected $manager; |
59 | |
60 | /** |
61 | * Configuration for determining permissions. |
62 | * |
63 | * @var array |
64 | */ |
65 | protected $config; |
66 | |
67 | /** |
68 | * Constructor |
69 | * |
70 | * @param PermissionProvider\PluginManager $manager Permission provider manager |
71 | * @param array $config Configuration for determining |
72 | * permissions |
73 | */ |
74 | public function __construct( |
75 | PermissionProvider\PluginManager $manager, |
76 | array $config |
77 | ) { |
78 | $this->manager = $manager; |
79 | $this->config = $config; |
80 | } |
81 | |
82 | /** |
83 | * Get the roles from the provider |
84 | * |
85 | * @param string[] $roleNames Role(s) to look up. |
86 | * |
87 | * @return \Rbac\Role\RoleInterface[] |
88 | */ |
89 | public function getRoles(array $roleNames) |
90 | { |
91 | return array_map([$this, 'getRole'], $roleNames); |
92 | } |
93 | |
94 | /** |
95 | * Get a role object by name. |
96 | * |
97 | * @param string $name Role name |
98 | * |
99 | * @return Role |
100 | */ |
101 | protected function getRole($name) |
102 | { |
103 | // Retrieve permissions from providers if not already done: |
104 | if (false === $this->roles) { |
105 | $this->populateRoles(); |
106 | } |
107 | |
108 | // Create role object if missing: |
109 | if (!isset($this->roles[$name])) { |
110 | $this->roles[$name] = new Role($name); |
111 | } |
112 | |
113 | return $this->roles[$name]; |
114 | } |
115 | |
116 | /** |
117 | * Populate the internal role array. |
118 | * |
119 | * @return void |
120 | */ |
121 | protected function populateRoles() |
122 | { |
123 | // Reset internal role array: |
124 | $this->roles = []; |
125 | |
126 | // Map permission configuration to the expected output format. |
127 | foreach ($this->getPermissionsArray() as $roleName => $permissionArr) { |
128 | $role = $this->getRole($roleName); |
129 | foreach ($permissionArr as $permission) { |
130 | $role->addPermission($permission); |
131 | } |
132 | } |
133 | } |
134 | |
135 | /** |
136 | * Get an associative array of role name => permissions using the provided |
137 | * configuration. |
138 | * |
139 | * @return array |
140 | */ |
141 | protected function getPermissionsArray() |
142 | { |
143 | // Loop through all of the permissions: |
144 | $retVal = []; |
145 | foreach ($this->config as $settings) { |
146 | $current = $this->getRolesForSettings($settings); |
147 | if (null !== $current['roles']) { |
148 | foreach ($current['roles'] as $role) { |
149 | if (!isset($retVal[$role])) { |
150 | $retVal[$role] = []; |
151 | } |
152 | foreach ($current['permissions'] as $permission) { |
153 | $retVal[$role][] = $permission; |
154 | } |
155 | } |
156 | } |
157 | } |
158 | return $retVal; |
159 | } |
160 | |
161 | /** |
162 | * Given a settings array, return the appropriate roles. |
163 | * |
164 | * @param array $settings Settings for finding roles that allow a permission |
165 | * |
166 | * @return array |
167 | */ |
168 | protected function getRolesForSettings($settings) |
169 | { |
170 | // Extract require setting: |
171 | if (isset($settings['require'])) { |
172 | $mode = strtoupper(trim($settings['require'])); |
173 | unset($settings['require']); |
174 | } else { |
175 | $mode = 'ALL'; |
176 | } |
177 | |
178 | // Extract permission setting: |
179 | $permissions = isset($settings['permission']) |
180 | ? (array)$settings['permission'] : []; |
181 | unset($settings['permission']); |
182 | |
183 | // Process everything: |
184 | $roles = null; |
185 | foreach ($settings as $provider => $options) { |
186 | $providerObj = $this->manager->get($provider); |
187 | $currentRoles = $providerObj->getPermissions($options); |
188 | if ($roles === null) { |
189 | $roles = $currentRoles; |
190 | } elseif ($mode == 'ANY') { |
191 | $roles = array_merge($roles, $currentRoles); |
192 | } else { |
193 | $roles = array_intersect($roles, $currentRoles); |
194 | } |
195 | } |
196 | return compact('permissions', 'roles'); |
197 | } |
198 | } |