ILIAS  release_6 Revision v6.24-5-g0c8bfefb3b8
All Data Structures Namespaces Files Functions Variables Modules Pages
class.ilWebAccessChecker.php
Go to the documentation of this file.
1 <?php
18 // declare(strict_types=1);
23 
24 require_once('./Services/WebAccessChecker/classes/class.ilWACSignedPath.php');
25 require_once('./Services/WebAccessChecker/classes/class.ilWACPath.php');
26 require_once('./Services/WebAccessChecker/classes/class.ilWACSecurePath.php');
27 require_once('./Services/Init/classes/class.ilInitialisation.php');
28 require_once('./Services/FileDelivery/classes/class.ilFileDelivery.php');
29 
37 {
38  const DISPOSITION = 'disposition';
39  const STATUS_CODE = 'status_code';
40  const REVALIDATE = 'revalidate';
41  const CM_FILE_TOKEN = 1;
42  const CM_FOLDER_TOKEN = 2;
44  const CM_SECFOLDER = 4;
48  protected $path_object = null;
52  protected $checked = false;
60  protected $override_mimetype = '';
64  protected $send_status_code = false;
68  protected $initialized = false;
72  protected $revalidate_folder_tokens = true;
76  protected static $use_seperate_logfile = false;
80  protected $applied_checking_methods = array();
84  private $http;
88  private $cookieFactory;
89 
90 
98  {
99  $this->setPathObject(new ilWACPath($httpState->request()->getRequestTarget()));
100  $this->http = $httpState;
101  $this->cookieFactory = $cookieFactory;
102  }
103 
104 
109  public function check()
110  {
111  if (!$this->getPathObject()) {
113  }
114 
115  // Check if Path has been signed with a token
116  $ilWACSignedPath = new ilWACSignedPath($this->getPathObject(), $this->http, $this->cookieFactory);
117  if ($ilWACSignedPath->isSignedPath()) {
118  $this->addAppliedCheckingMethod(self::CM_FILE_TOKEN);
119  if ($ilWACSignedPath->isSignedPathValid()) {
120  $this->setChecked(true);
121  $this->sendHeader('checked using token');
122 
123  return true;
124  }
125  }
126 
127  // Check if the whole secured folder has been signed
128  if ($ilWACSignedPath->isFolderSigned()) {
129  $this->addAppliedCheckingMethod(self::CM_FOLDER_TOKEN);
130  if ($ilWACSignedPath->isFolderTokenValid()) {
131  if ($this->isRevalidateFolderTokens()) {
132  $ilWACSignedPath->revalidatingFolderToken();
133  }
134  $this->setChecked(true);
135  $this->sendHeader('checked using secure folder');
136 
137  return true;
138  }
139  }
140 
141  // Fallback, have to initiate ILIAS
142  $this->initILIAS();
143 
144  // Check if Path is within accepted paths
145  if ($this->getPathObject()->getModuleType() !== 'rs') {
146  $path = realpath($this->getPathObject()->getCleanURLdecodedPath());
147  $data_dir = realpath(CLIENT_WEB_DIR);
148  if (strpos($path, $data_dir) !== 0) {
149  return false;
150  }
151  if (dirname($path) === $data_dir && is_file($path)) {
152  return false;
153  }
154  }
155 
157  // Maybe the path has been registered, lets check
158  $checkingInstance = ilWACSecurePath::getCheckingInstance($this->getPathObject());
159  $this->addAppliedCheckingMethod(self::CM_CHECKINGINSTANCE);
160  $canBeDelivered = $checkingInstance->canBeDelivered($this->getPathObject());
161  if ($canBeDelivered) {
162  $this->sendHeader('checked using fallback');
163  if ($ilWACSignedPath->isFolderSigned() && $this->isRevalidateFolderTokens()) {
164  $ilWACSignedPath->revalidatingFolderToken();
165  }
166 
167  $this->setChecked(true);
168 
169  return true;
170  } else {
171  $this->setChecked(true);
172 
173  return false;
174  }
175  }
176 
177  // none of the checking mechanisms could have been applied. no access
178  $this->setChecked(true);
179  if ($this->getPathObject()->isInSecFolder()) {
180  $this->addAppliedCheckingMethod(self::CM_SECFOLDER);
181 
182  return false;
183  } else {
184  $this->addAppliedCheckingMethod(self::CM_SECFOLDER);
185 
186  return true;
187  }
188  }
189 
190 
196  protected function sendHeader($message)
197  {
198  $response = $this->http->response()->withHeader('X-ILIAS-WebAccessChecker', $message);
199  $this->http->saveResponse($response);
200  }
201 
202 
206  public function initILIAS()
207  {
208  if ($this->isInitialized()) {
209  return;
210  }
211 
212  $GLOBALS['COOKIE_PATH'] = '/';
213 
214  $cookie = $this->cookieFactory->create('ilClientId', $this->getPathObject()->getClient())
215  ->withPath('/')
216  ->withExpires(0);
217 
218  $response = $this->http->cookieJar()
219  ->with($cookie)
220  ->renderIntoResponseHeader($this->http->response());
221 
222  $this->http->saveResponse($response);
223 
225  try {
227  $this->checkUser();
228  $this->checkPublicSection();
229  } catch (Exception $e) {
230  if ($e instanceof ilWACException
231  && $e->getCode() !== ilWACException::ACCESS_DENIED_NO_LOGIN) {
232  throw $e;
233  }
234  if (($e instanceof Exception && $e->getMessage() == 'Authentication failed.')
235  || $e->getCode() === ilWACException::ACCESS_DENIED_NO_LOGIN) {
236  $this->initAnonymousSession();
237  $this->checkUser();
238  $this->checkPublicSection();
239  }
240  }
241  $this->setInitialized(true);
242  }
243 
244 
249  protected function checkPublicSection()
250  {
251  global $DIC;
252  $on_login_page = !$this->isRequestNotFromLoginPage();
253  $is_anonymous = ((int) $DIC->user()->getId() === (int) ANONYMOUS_USER_ID);
254  $is_null_user = ($DIC->user()->getId() === 0);
255  $pub_section_activated = (bool) $DIC['ilSetting']->get('pub_section');
256  $isset = isset($DIC['ilSetting']);
257  $instanceof = $DIC['ilSetting'] instanceof ilSetting;
258 
259  if (!$isset || !$instanceof) {
261  }
262 
263  if ($on_login_page && ($is_null_user || $is_anonymous)) {
264  // Request is initiated from login page
265  return;
266  }
267 
268  if ($pub_section_activated && ($is_null_user || $is_anonymous)) {
269  // Request is initiated from an enabled public area
270  return;
271  }
272 
273  if ($is_anonymous || $is_null_user) {
275  }
276  }
277 
278 
279  protected function checkUser()
280  {
281  global $DIC;
282 
283  $is_user = $DIC->user() instanceof ilObjUser;
284  $user_id_is_zero = ((int) $DIC->user()->getId() === 0);
285  $not_on_login_page = $this->isRequestNotFromLoginPage();
286  if (!$is_user || ($user_id_is_zero && $not_on_login_page)) {
288  }
289  }
290 
291 
295  public function isChecked()
296  {
297  return (bool) $this->checked;
298  }
299 
300 
306  public function setChecked($checked)
307  {
308  assert(is_bool($checked));
309  $this->checked = $checked;
310  }
311 
312 
316  public function getPathObject()
317  {
318  return $this->path_object;
319  }
320 
321 
328  {
329  $this->path_object = $path_object;
330  }
331 
332 
336  public function getDisposition()
337  {
338  return (string) $this->disposition;
339  }
340 
341 
347  public function setDisposition($disposition)
348  {
349  assert(is_string($disposition));
350  $this->disposition = $disposition;
351  }
352 
353 
357  public function getOverrideMimetype()
358  {
359  return (string) $this->override_mimetype;
360  }
361 
362 
369  {
370  assert(is_string($override_mimetype));
371  $this->override_mimetype = $override_mimetype;
372  }
373 
374 
378  public function isInitialized()
379  {
380  return (bool) $this->initialized;
381  }
382 
383 
387  public function setInitialized($initialized)
388  {
389  assert(is_bool($initialized));
390  $this->initialized = $initialized;
391  }
392 
393 
397  public function isSendStatusCode()
398  {
399  return (bool) $this->send_status_code;
400  }
401 
402 
409  {
410  assert(is_bool($send_status_code));
411  $this->send_status_code = $send_status_code;
412  }
413 
414 
418  public function isRevalidateFolderTokens()
419  {
420  return (bool) $this->revalidate_folder_tokens;
421  }
422 
423 
430  {
431  assert(is_bool($revalidate_folder_tokens));
432  $this->revalidate_folder_tokens = $revalidate_folder_tokens;
433  }
434 
435 
439  public static function isUseSeperateLogfile()
440  {
441  return (bool) self::$use_seperate_logfile;
442  }
443 
444 
451  {
452  assert(is_bool($use_seperate_logfile));
453  self::$use_seperate_logfile = $use_seperate_logfile;
454  }
455 
456 
460  public function getAppliedCheckingMethods()
461  {
462  return (array) $this->applied_checking_methods;
463  }
464 
465 
472  {
473  $this->applied_checking_methods = $applied_checking_methods;
474  }
475 
476 
482  protected function addAppliedCheckingMethod($method)
483  {
484  assert(is_int($method));
485  $this->applied_checking_methods[] = $method;
486  }
487 
488 
489  protected function initAnonymousSession()
490  {
491  global $DIC;
492  include_once './Services/Context/classes/class.ilContext.php';
493  session_destroy();
495  require_once("Services/Init/classes/class.ilInitialisation.php");
500  $ilAuthSession = $DIC['ilAuthSession'];
501  $ilAuthSession->init();
502  $ilAuthSession->regenerateId();
503  $a_id = (int) ANONYMOUS_USER_ID;
504  $ilAuthSession->setUserId($a_id);
505  $ilAuthSession->setAuthenticated(false, $a_id);
506  $DIC->user()->setId($a_id);
507  }
508 
509 
513  protected function isRequestNotFromLoginPage()
514  {
515  $referrer = (string) ($_SERVER['HTTP_REFERER'] ?? '');
516  $not_on_login_page = (strpos($referrer, 'login.php') === false
517  && strpos($referrer, '&baseClass=ilStartUpGUI') === false);
518 
519  if ($not_on_login_page && $referrer !== '') {
520  // In some scenarios (observed for content styles on login page, the HTTP_REFERER does not contain a PHP script
521  $referrer_url_parts = parse_url($referrer);
522  $ilias_url_parts = parse_url(ilUtil::_getHttpPath());
523  if (
524  $ilias_url_parts['host'] === $referrer_url_parts['host'] &&
525  (
526  !isset($referrer_url_parts['path']) ||
527  strpos($referrer_url_parts['path'], '.php') === false
528  )
529  ) {
530  $not_on_login_page = false;
531  }
532  }
533 
534  return $not_on_login_page;
535  }
536 }
setPathObject(ilWACPath $path_object)
static setUseSeperateLogfile($use_seperate_logfile)
Interface GlobalHttpState.
request()
Returns the current psr-7 server request.
Class ilWACException.
const CONTEXT_WAC
setAppliedCheckingMethods(array $applied_checking_methods)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
setRevalidateFolderTokens($revalidate_folder_tokens)
__construct(GlobalHttpState $httpState, CookieFactory $cookieFactory)
ilWebAccessChecker constructor.
static initILIAS()
ilias initialisation
static http()
Fetches the global http state from ILIAS.
Class ilWebAccessChecker.
setSendStatusCode($send_status_code)
Class ilWACSignedPath.
$_SERVER['HTTP_HOST']
Definition: raiseError.php:10
if(!defined('PATH_SEPARATOR')) $GLOBALS['_PEAR_default_error_mode']
Definition: PEAR.php:64
setOverrideMimetype($override_mimetype)
static init($a_type)
Init context by type.
static _getHttpPath()
static hasCheckingInstanceRegistered(ilWACPath $ilWACPath)
Searches a checking instance for the given wac path.
$DIC
Definition: xapitoken.php:46
$message
Definition: xapiexit.php:14
$response