Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
87.50% |
63 / 72 |
|
76.92% |
10 / 13 |
CRAP | |
0.00% |
0 / 1 |
PrimoPermissionHandler | |
87.50% |
63 / 72 |
|
76.92% |
10 / 13 |
44.28 | |
0.00% |
0 / 1 |
__construct | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
3 | |||
setInstCode | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
2 | |||
instCodeExists | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getInstCode | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
2 | |||
hasPermission | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
2 | |||
checkConfig | |
100.00% |
9 / 9 |
|
100.00% |
1 / 1 |
4 | |||
checkLegacySettings | |
54.55% |
6 / 11 |
|
0.00% |
0 / 1 |
7.35 | |||
getInstCodes | |
100.00% |
10 / 10 |
|
100.00% |
1 / 1 |
5 | |||
autodetectCode | |
100.00% |
16 / 16 |
|
100.00% |
1 / 1 |
9 | |||
getDefaultCode | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getDefaultOnCampusRule | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
6 | |||
getOnCampusRule | |
85.71% |
6 / 7 |
|
0.00% |
0 / 1 |
3.03 | |||
checkPermission | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
2 |
1 | <?php |
2 | |
3 | /** |
4 | * Primo Permission Handler. |
5 | * |
6 | * PHP version 8 |
7 | * |
8 | * Copyright (C) Villanova University 2013. |
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 Search |
25 | * @author Oliver Goldschmidt <o.goldschmidt@tuhh.de> |
26 | * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License |
27 | * @link https://vufind.org Main Site |
28 | */ |
29 | |
30 | namespace VuFind\Search\Primo; |
31 | |
32 | use LmcRbacMvc\Service\AuthorizationServiceAwareTrait; |
33 | |
34 | use function in_array; |
35 | use function is_array; |
36 | |
37 | /** |
38 | * Primo Permission Handler. |
39 | * |
40 | * @category VuFind |
41 | * @package Search |
42 | * @author Oliver Goldschmidt <o.goldschmidt@tuhh.de> |
43 | * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License |
44 | * @link https://vufind.org Main Site |
45 | */ |
46 | class PrimoPermissionHandler |
47 | { |
48 | use AuthorizationServiceAwareTrait; |
49 | |
50 | /** |
51 | * Primo-Config for Institutions. |
52 | * |
53 | * @var array |
54 | */ |
55 | protected $primoConfig; |
56 | |
57 | /** |
58 | * Institution code applicable for the user |
59 | * |
60 | * @var string |
61 | */ |
62 | protected $instCode = null; |
63 | |
64 | /** |
65 | * Constructor. |
66 | * |
67 | * @param Laminas\Config\Config|array $primoPermConfig Primo-Config for |
68 | * Institutions |
69 | * |
70 | * @return void |
71 | */ |
72 | public function __construct($primoPermConfig) |
73 | { |
74 | if ($primoPermConfig instanceof \Laminas\Config\Config) { |
75 | $primoPermConfig = $primoPermConfig->toArray(); |
76 | } |
77 | $this->primoConfig = is_array($primoPermConfig) ? $primoPermConfig : []; |
78 | $this->checkLegacySettings(); |
79 | $this->checkConfig(); |
80 | } |
81 | |
82 | /** |
83 | * Set the institution code (no autodetection) |
84 | * |
85 | * @param string $code Institutioncode |
86 | * |
87 | * @return void |
88 | */ |
89 | public function setInstCode($code) |
90 | { |
91 | // If the code is valid, we'll set it; otherwise, we'll use "false" to |
92 | // clear instCode's null status and indicate that the setter has been used. |
93 | $this->instCode = ($this->instCodeExists($code) === true) ? $code : false; |
94 | } |
95 | |
96 | /** |
97 | * Determine if a institution code is set in config file |
98 | * |
99 | * @param string $code Code to approve against config file |
100 | * |
101 | * @return bool |
102 | */ |
103 | public function instCodeExists($code) |
104 | { |
105 | return in_array($code, $this->getInstCodes()) === true; |
106 | } |
107 | |
108 | /** |
109 | * Determine the institution code |
110 | * Returns false, if no institution can get set |
111 | * |
112 | * @return string|boolean |
113 | */ |
114 | public function getInstCode() |
115 | { |
116 | if ($this->instCode === null) { |
117 | $this->autodetectCode(); |
118 | } |
119 | return $this->instCode; |
120 | } |
121 | |
122 | /** |
123 | * Check if the user has permission |
124 | * |
125 | * @return bool |
126 | */ |
127 | public function hasPermission() |
128 | { |
129 | $code = $this->getInstCode(); |
130 | return false !== $code && $this->checkPermission($code) === true; |
131 | } |
132 | |
133 | /** |
134 | * Checks the config file section for validity |
135 | * |
136 | * @return void |
137 | */ |
138 | protected function checkConfig() |
139 | { |
140 | if ( |
141 | isset($this->primoConfig['institutionCode']) |
142 | || isset($this->primoConfig['onCampusRule']) |
143 | || ($this->getDefaultCode() !== false) |
144 | ) { |
145 | return; |
146 | } |
147 | |
148 | // If we reach this point, no institution code is set in config. |
149 | // Primo will not work without an institution code! |
150 | throw new \Exception( |
151 | 'No institutionCode found. Please be sure that at least a ' |
152 | . 'defaultCode is configured in section [Institutions] ' |
153 | . 'in Primo.ini.' |
154 | ); |
155 | } |
156 | |
157 | /** |
158 | * Legacy settings support |
159 | * |
160 | * @return void |
161 | */ |
162 | protected function checkLegacySettings() |
163 | { |
164 | // if we already have settings, ignore the legacy ones |
165 | if ( |
166 | isset($this->primoConfig['defaultCode']) |
167 | || isset($this->primoConfig['onCampusRule']) |
168 | ) { |
169 | return; |
170 | } |
171 | |
172 | // Handle legacy options |
173 | $codes = $this->primoConfig['code'] ?? []; |
174 | $regex = $this->primoConfig['regex'] ?? []; |
175 | if (!empty($codes) && !empty($regex)) { |
176 | throw new \Exception( |
177 | 'Legacy [Institutions] settings detected.' |
178 | . ' Please run upgrade process or correct settings manually' |
179 | . ' in Primo.ini and permissions.ini.' |
180 | ); |
181 | } |
182 | } |
183 | |
184 | /** |
185 | * Gets all possible institution codes from config file |
186 | * |
187 | * @return array Array with valid Primo institution codes |
188 | */ |
189 | protected function getInstCodes() |
190 | { |
191 | // Start with default code (if any): |
192 | $defaultCode = $this->getDefaultCode(); |
193 | $codes = ($defaultCode !== false) ? [$defaultCode] : []; |
194 | |
195 | // Add additional keys from relevant config sections: |
196 | foreach (['institutionCode', 'onCampusRule'] as $section) { |
197 | if ( |
198 | isset($this->primoConfig[$section]) |
199 | && is_array($this->primoConfig[$section]) |
200 | ) { |
201 | $codes = array_merge( |
202 | $codes, |
203 | array_keys($this->primoConfig[$section]) |
204 | ); |
205 | } |
206 | } |
207 | |
208 | return $codes; |
209 | } |
210 | |
211 | /** |
212 | * Autodetects the permissions by configuration file |
213 | * |
214 | * @return void |
215 | */ |
216 | protected function autodetectCode() |
217 | { |
218 | $authService = $this->getAuthorizationService(); |
219 | |
220 | // if no authorization service is available, don't do anything |
221 | if (!$authService) { |
222 | $this->instCode = false; |
223 | return; |
224 | } |
225 | |
226 | // walk through the relevant config sections and check if one is granted |
227 | foreach (['institutionCode', 'onCampusRule'] as $section) { |
228 | if ( |
229 | isset($this->primoConfig[$section]) |
230 | && is_array($this->primoConfig[$section]) |
231 | ) { |
232 | foreach ($this->primoConfig[$section] as $code => $permRule) { |
233 | if ($authService->isGranted($permRule)) { |
234 | $this->instCode = $code; |
235 | return; |
236 | } |
237 | } |
238 | } |
239 | } |
240 | |
241 | // if no rule has matched until here, assume the user gets the default code |
242 | if ($this->getDefaultCode() !== false) { |
243 | $this->instCode = $this->getDefaultCode(); |
244 | return; |
245 | } |
246 | |
247 | // Autodetection failed, set instCode to false |
248 | // Primo will not work without an institution code! |
249 | if ($this->instCode === null) { |
250 | $this->instCode = false; |
251 | } |
252 | } |
253 | |
254 | /** |
255 | * Determine the default institution code |
256 | * Returns false, if no default code has been set |
257 | * |
258 | * @return string|boolean |
259 | */ |
260 | protected function getDefaultCode() |
261 | { |
262 | return $this->primoConfig['defaultCode'] ?? false; |
263 | } |
264 | |
265 | /** |
266 | * Determine the default onCampus Rule |
267 | * |
268 | * @return string |
269 | */ |
270 | protected function getDefaultOnCampusRule() |
271 | { |
272 | $defaultCode = $this->getDefaultCode(); |
273 | return ($defaultCode !== false) |
274 | ? $this->getOnCampusRule($defaultCode) : null; |
275 | } |
276 | |
277 | /** |
278 | * Determine a onCampus Rule for a certain code |
279 | * |
280 | * @param string $code Code to determine the rule name for |
281 | * |
282 | * @return string |
283 | */ |
284 | protected function getOnCampusRule($code) |
285 | { |
286 | if ($code === null) { |
287 | return null; |
288 | } |
289 | |
290 | $onCampusRule |
291 | = $this->primoConfig['onCampusRule'][$code] ?? false; |
292 | |
293 | if (false !== $onCampusRule) { |
294 | return $onCampusRule; |
295 | } |
296 | |
297 | // If primoConfig->onCampusRule[] is not set |
298 | // no rule can get applied. |
299 | // So return null to indicate that nothing can get matched. |
300 | return null; |
301 | } |
302 | |
303 | /** |
304 | * Checks, if a rule is granted |
305 | * |
306 | * @param string $code Code to check the rule name for |
307 | * |
308 | * @return bool |
309 | */ |
310 | protected function checkPermission($code) |
311 | { |
312 | $onCampusRule = $this->getOnCampusRule($code); |
313 | $authService = $this->getAuthorizationService(); |
314 | |
315 | // if no authorization service is available, the user can't get permission |
316 | return $authService && $authService->isGranted($onCampusRule); |
317 | } |
318 | } |