ILIAS  release_7 Revision v7.30-3-g800a261c036
class.ilWebAccessChecker.php
Go to the documentation of this file.
1<?php
18// declare(strict_types=1);
22use Psr\Http\Message\UriInterface;
23
24require_once('./Services/WebAccessChecker/classes/class.ilWACSignedPath.php');
25require_once('./Services/WebAccessChecker/classes/class.ilWACPath.php');
26require_once('./Services/WebAccessChecker/classes/class.ilWACSecurePath.php');
27require_once('./Services/Init/classes/class.ilInitialisation.php');
28require_once('./Services/FileDelivery/classes/class.ilFileDelivery.php');
29
37{
38 public const DISPOSITION = 'disposition';
39 public const STATUS_CODE = 'status_code';
40 public const REVALIDATE = 'revalidate';
41 public const CM_FILE_TOKEN = 1;
42 public const CM_FOLDER_TOKEN = 2;
43 public const CM_CHECKINGINSTANCE = 3;
44 public const CM_SECFOLDER = 4;
52 private $http;
61
69 {
70 try {
71 $this->setPathObject(new ilWACPath($httpState->request()->getRequestTarget()));
72 } catch (ilWACException $e) {
73 if ($e->getCode() !== ilWACException::NOT_FOUND) {
74 throw $e;
75 }
76 $this->ressource_not_found = $e;
77 }
78
79 $this->http = $httpState;
80 $this->cookieFactory = $cookieFactory;
81 }
82
83
88 public function check()
89 {
90 if ($this->getPathObject() === null) {
91 if ($this->ressource_not_found !== null) {
92 throw new ilWACException(ilWACException::NOT_FOUND, '', $this->ressource_not_found);
93 }
94
96 }
97
98 // Check if Path has been signed with a token
99 $ilWACSignedPath = new ilWACSignedPath($this->getPathObject(), $this->http, $this->cookieFactory);
100 if ($ilWACSignedPath->isSignedPath()) {
101 $this->addAppliedCheckingMethod(self::CM_FILE_TOKEN);
102 if ($ilWACSignedPath->isSignedPathValid()) {
103 $this->setChecked(true);
104 $this->sendHeader('checked using token');
105
106 return true;
107 }
108 }
109
110 // Check if the whole secured folder has been signed
111 if ($ilWACSignedPath->isFolderSigned()) {
112 $this->addAppliedCheckingMethod(self::CM_FOLDER_TOKEN);
113 if ($ilWACSignedPath->isFolderTokenValid()) {
114 if ($this->isRevalidateFolderTokens()) {
115 $ilWACSignedPath->revalidatingFolderToken();
116 }
117 $this->setChecked(true);
118 $this->sendHeader('checked using secure folder');
119
120 return true;
121 }
122 }
123
124 // Fallback, have to initiate ILIAS
125 $this->initILIAS();
126
127 // Check if Path is within accepted paths
128 if ($this->getPathObject()->getModuleType() !== 'rs') {
129 $clean_path = $this->getPathObject()->getCleanURLdecodedPath();
130 $path = realpath($clean_path);
131 $data_dir = realpath(CLIENT_WEB_DIR);
132 if (strpos($path, (string) $data_dir) !== 0) {
133 return false;
134 }
135 if (dirname($path) === $data_dir && is_file($path)) {
136 return false;
137 }
138 }
139
141 // Maybe the path has been registered, lets check
142 $checkingInstance = ilWACSecurePath::getCheckingInstance($this->getPathObject());
143 $this->addAppliedCheckingMethod(self::CM_CHECKINGINSTANCE);
144 $canBeDelivered = $checkingInstance->canBeDelivered($this->getPathObject());
145 if ($canBeDelivered) {
146 $this->sendHeader('checked using fallback');
147 if ($ilWACSignedPath->isFolderSigned() && $this->isRevalidateFolderTokens()) {
148 $ilWACSignedPath->revalidatingFolderToken();
149 }
150
151 $this->setChecked(true);
152
153 return true;
154 } else {
155 $this->setChecked(true);
156
157 return false;
158 }
159 }
160
161 // none of the checking mechanisms could have been applied. no access
162 $this->setChecked(true);
163 if ($this->getPathObject()->isInSecFolder()) {
164 $this->addAppliedCheckingMethod(self::CM_SECFOLDER);
165
166 return false;
167 } else {
168 $this->addAppliedCheckingMethod(self::CM_SECFOLDER);
169
170 return true;
171 }
172 }
173
174
180 protected function sendHeader($message)
181 {
182 $response = $this->http->response()->withHeader('X-ILIAS-WebAccessChecker', $message);
183 $this->http->saveResponse($response);
184 }
185
186
190 public function initILIAS()
191 {
192 global $DIC;
193
194 if ($this->isInitialized()) {
195 return;
196 }
197
198 $GLOBALS['COOKIE_PATH'] = '/';
199
200 $cookie = $this->cookieFactory->create('ilClientId', $this->getPathObject()->getClient())
201 ->withPath('/')
202 ->withExpires(0);
203
204 $response = $this->http->cookieJar()
205 ->with($cookie)
206 ->renderIntoResponseHeader($this->http->response());
207
208 $this->http->saveResponse($response);
209
211 try {
213 $this->checkUser();
214 $this->checkPublicSection();
215 } catch (Exception $e) {
216 if ($e instanceof ilWACException
217 && $e->getCode() !== ilWACException::ACCESS_DENIED_NO_LOGIN) {
218 throw $e;
219 }
220 if (($e instanceof Exception && $e->getMessage() == 'Authentication failed.')
221 || $e->getCode() === ilWACException::ACCESS_DENIED_NO_LOGIN) {
222 $this->initAnonymousSession();
223 $this->checkUser();
224 $this->checkPublicSection();
225 }
226 }
227 $this->setInitialized(true);
228
229 // This workaround is needed because these issues:
230 // https://mantis.ilias.de/view.php?id=32284 and
231 // https://mantis.ilias.de/view.php?id=32063
232 if ($DIC->user()->getId() === 0) {
233 $DIC->user()->setId(ANONYMOUS_USER_ID);
234 }
235 }
236
237
242 protected function checkPublicSection()
243 {
244 global $DIC;
245 $is_anonymous = ((int) $DIC->user()->getId() === (int) ANONYMOUS_USER_ID);
246 $is_null_user = ($DIC->user()->getId() === 0);
247 $pub_section_activated = (bool) $DIC['ilSetting']->get('pub_section');
248 $isset = isset($DIC['ilSetting']);
249 $instanceof = $DIC['ilSetting'] instanceof ilSetting;
250
251 if (!$isset || !$instanceof) {
253 }
254
255 if ($pub_section_activated && ($is_null_user || $is_anonymous)) {
256 // Request is initiated from an enabled public area
257 return;
258 }
259
260 if ($is_anonymous || $is_null_user) {
262 }
263 }
264
265
266 protected function checkUser()
267 {
268 global $DIC;
269
270 $is_user = $DIC->user() instanceof ilObjUser;
271 $user_id_is_zero = ((int) $DIC->user()->getId() === 0);
272 if (!$is_user || $user_id_is_zero) {
274 }
275 }
276
277
281 public function isChecked()
282 {
283 return (bool) $this->checked;
284 }
285
286
292 public function setChecked($checked)
293 {
294 assert(is_bool($checked));
295 $this->checked = $checked;
296 }
297
298
302 public function getPathObject()
303 {
304 return $this->path_object;
305 }
306
307
313 public function setPathObject(ilWACPath $path_object)
314 {
315 $this->path_object = $path_object;
316 }
317
318
322 public function getDisposition()
323 {
324 return (string) $this->disposition;
325 }
326
327
333 public function setDisposition($disposition)
334 {
335 assert(is_string($disposition));
336 $this->disposition = $disposition;
337 }
338
339
343 public function getOverrideMimetype()
344 {
345 return (string) $this->override_mimetype;
346 }
347
348
354 public function setOverrideMimetype($override_mimetype)
355 {
356 assert(is_string($override_mimetype));
357 $this->override_mimetype = $override_mimetype;
358 }
359
360
364 public function isInitialized()
365 {
366 return (bool) $this->initialized;
367 }
368
369
373 public function setInitialized($initialized)
374 {
375 assert(is_bool($initialized));
376 $this->initialized = $initialized;
377 }
378
379
383 public function isSendStatusCode()
384 {
385 return (bool) $this->send_status_code;
386 }
387
388
394 public function setSendStatusCode($send_status_code)
395 {
396 assert(is_bool($send_status_code));
397 $this->send_status_code = $send_status_code;
398 }
399
400
404 public function isRevalidateFolderTokens()
405 {
406 return (bool) $this->revalidate_folder_tokens;
407 }
408
409
415 public function setRevalidateFolderTokens($revalidate_folder_tokens)
416 {
417 assert(is_bool($revalidate_folder_tokens));
418 $this->revalidate_folder_tokens = $revalidate_folder_tokens;
419 }
420
421
425 public static function isUseSeperateLogfile()
426 {
427 return (bool) self::$use_seperate_logfile;
428 }
429
430
436 public static function setUseSeperateLogfile($use_seperate_logfile)
437 {
438 assert(is_bool($use_seperate_logfile));
439 self::$use_seperate_logfile = $use_seperate_logfile;
440 }
441
442
447 {
448 return (array) $this->applied_checking_methods;
449 }
450
451
458 {
459 $this->applied_checking_methods = $applied_checking_methods;
460 }
461
462
468 protected function addAppliedCheckingMethod($method)
469 {
470 assert(is_int($method));
471 $this->applied_checking_methods[] = $method;
472 }
473
474
475 protected function initAnonymousSession()
476 {
477 global $DIC;
478 include_once './Services/Context/classes/class.ilContext.php';
479 session_destroy();
481 require_once("Services/Init/classes/class.ilInitialisation.php");
486 $ilAuthSession = $DIC['ilAuthSession'];
487 $ilAuthSession->init();
488 $ilAuthSession->regenerateId();
489 $a_id = (int) ANONYMOUS_USER_ID;
490 $ilAuthSession->setUserId($a_id);
491 $ilAuthSession->setAuthenticated(false, $a_id);
492 $DIC->user()->setId($a_id);
493 }
494}
if(!defined('PATH_SEPARATOR')) $GLOBALS['_PEAR_default_error_mode']
Definition: PEAR.php:64
An exception for terminatinating execution or to throw for unit testing.
static init($a_type)
Init context by type.
const CONTEXT_WAC
static initILIAS()
ilias initialisation
ILIAS Setting Class.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
Class ilWACPath.
static hasCheckingInstanceRegistered(ilWACPath $ilWACPath)
Searches a checking instance for the given wac path.
Class ilWACSignedPath.
Class ilWebAccessChecker.
__construct(GlobalHttpState $httpState, CookieFactory $cookieFactory)
ilWebAccessChecker constructor.
static setUseSeperateLogfile($use_seperate_logfile)
setSendStatusCode($send_status_code)
setRevalidateFolderTokens($revalidate_folder_tokens)
setAppliedCheckingMethods(array $applied_checking_methods)
setPathObject(ilWACPath $path_object)
setOverrideMimetype($override_mimetype)
const CLIENT_WEB_DIR
Definition: constants.php:45
const ANONYMOUS_USER_ID
Definition: constants.php:25
global $DIC
Definition: goto.php:24
Interface GlobalHttpState.
request()
Returns the current psr-7 server request.
static http()
Fetches the global http state from ILIAS.
$response
$message
Definition: xapiexit.php:14