ILIAS  release_10 Revision v10.1-43-ga1241a92c2f
class.ilWebAccessChecker.php
Go to the documentation of this file.
1 <?php
2 
23 
31 {
32  public const DISPOSITION = 'disposition';
33  public const STATUS_CODE = 'status_code';
34  public const REVALIDATE = 'revalidate';
35  public const CM_FILE_TOKEN = 1;
36  public const CM_FOLDER_TOKEN = 2;
37  public const CM_CHECKINGINSTANCE = 3;
38  public const CM_SECFOLDER = 4;
39 
40  protected ?ilWACPath $path_object = null;
41  protected bool $checked = false;
43  protected string $override_mimetype = '';
44  protected bool $send_status_code = false;
45  protected bool $initialized = false;
46  protected bool $revalidate_folder_tokens = true;
47  protected static bool $use_seperate_logfile = false;
51  protected array $applied_checking_methods = [];
52 
56  public function __construct(private Services $http, private CookieFactory $cookieFactory)
57  {
58  }
59 
63  public function check(): bool
64  {
65  $path_object = new ilWACPath($this->http->request()->getRequestTarget());
66  $this->setPathObject($path_object);
67 
68  // Check if Path has been signed with a token
69  $ilWACSignedPath = new ilWACSignedPath($path_object, $this->http, $this->cookieFactory);
70  if ($ilWACSignedPath->isSignedPath()) {
71  $this->addAppliedCheckingMethod(self::CM_FILE_TOKEN);
72  if ($ilWACSignedPath->isSignedPathValid()) {
73  $this->setChecked(true);
74  $this->sendHeader('checked using token');
75 
76  return true;
77  }
78  }
79 
80  // Check if the whole secured folder has been signed
81  if ($ilWACSignedPath->isFolderSigned()) {
82  $this->addAppliedCheckingMethod(self::CM_FOLDER_TOKEN);
83  if ($ilWACSignedPath->isFolderTokenValid()) {
84  if ($this->isRevalidateFolderTokens()) {
85  $ilWACSignedPath->revalidatingFolderToken();
86  }
87  $this->setChecked(true);
88  $this->sendHeader('checked using secure folder');
89 
90  return true;
91  }
92  }
93 
94  // Fallback, have to initiate ILIAS
95  $this->initILIAS();
96 
97  // Check if Path is within accepted paths
98  if ($path_object->getModuleType() !== 'rs') {
99  $clean_path = $path_object->getCleanURLdecodedPath();
100  $path = realpath(__DIR__ . '/../../../../public/' . $clean_path);
101  $data_dir = realpath(CLIENT_WEB_DIR);
102  if (!str_starts_with($path, $data_dir)) {
103  return false;
104  }
105  if (dirname($path) === $data_dir && is_file($path)) {
106  return false;
107  }
108  }
109 
111  // Maybe the path has been registered, lets check
112  $checkingInstance = ilWACSecurePath::getCheckingInstance($path_object);
113  $this->addAppliedCheckingMethod(self::CM_CHECKINGINSTANCE);
114  $canBeDelivered = $checkingInstance->canBeDelivered($path_object);
115  if ($canBeDelivered) {
116  $this->sendHeader('checked using fallback');
117  if ($ilWACSignedPath->isFolderSigned() && $this->isRevalidateFolderTokens()) {
118  $ilWACSignedPath->revalidatingFolderToken();
119  }
120  }
121  $this->setChecked(true);
122  return $canBeDelivered;
123  }
124 
125  // none of the checking mechanisms could have been applied. no access
126  $this->setChecked(true);
127  $this->addAppliedCheckingMethod(self::CM_SECFOLDER);
128  return !$path_object->isInSecFolder();
129  }
130 
131  protected function sendHeader(string $message): void
132  {
133  $response = $this->http->response()->withHeader('X-ILIAS-WebAccessChecker', $message);
134  $this->http->saveResponse($response);
135  }
136 
137  public function initILIAS(): void
138  {
139  global $DIC;
140 
141  if ($this->isInitialized()) {
142  return;
143  }
144 
145  $GLOBALS['COOKIE_PATH'] = '/';
146 
147  $cookie = $this->cookieFactory->create('ilClientId', $this->getPathObject()->getClient())
148  ->withPath('/')
149  ->withExpires(0);
150 
151  $response = $this->http->cookieJar()
152  ->with($cookie)
153  ->renderIntoResponseHeader($this->http->response());
154 
155  $this->http->saveResponse($response);
156 
158  try {
160  $this->checkUser();
161  $this->checkPublicSection();
162  } catch (Exception $e) {
163  if ($e instanceof ilWACException
164  && $e->getCode() !== ilWACException::ACCESS_DENIED_NO_LOGIN) {
165  throw $e;
166  }
167  if (($e instanceof Exception && $e->getMessage() === 'Authentication failed.')
168  || $e->getCode() === ilWACException::ACCESS_DENIED_NO_LOGIN) {
169  $this->initAnonymousSession();
170  $this->checkUser();
171  $this->checkPublicSection();
172  }
173  }
174  $this->setInitialized(true);
175 
176  // This workaround is needed because these issues:
177  // https://mantis.ilias.de/view.php?id=32284 and
178  // https://mantis.ilias.de/view.php?id=32063
179  if ($DIC->user()->getId() === 0) {
180  $DIC->user()->setId(ANONYMOUS_USER_ID);
181  }
182  }
183 
187  protected function checkPublicSection(): void
188  {
189  global $DIC;
190  $is_anonymous = ((int) $DIC->user()->getId() === (int) ANONYMOUS_USER_ID);
191  $is_null_user = ($DIC->user()->getId() === 0);
192  $pub_section_activated = (bool) $DIC['ilSetting']->get('pub_section');
193  $isset = isset($DIC['ilSetting']);
194  $instanceof = $DIC['ilSetting'] instanceof ilSetting;
195 
196  if (!$isset || !$instanceof) {
198  }
199 
200  if ($pub_section_activated && ($is_null_user || $is_anonymous)) {
201  // Request is initiated from an enabled public area
202  return;
203  }
204 
205  if ($is_anonymous || $is_null_user) {
207  }
208  }
209 
210  protected function checkUser(): void
211  {
212  global $DIC;
213 
214  $is_user = $DIC->user() instanceof ilObjUser;
215  $user_id_is_zero = ((int) $DIC->user()->getId() === 0);
216  if (!$is_user || $user_id_is_zero) {
218  }
219  }
220 
221  public function isChecked(): bool
222  {
223  return $this->checked;
224  }
225 
226  public function setChecked(bool $checked): void
227  {
228  $this->checked = $checked;
229  }
230 
231  public function getPathObject(): ?\ilWACPath
232  {
233  return $this->path_object;
234  }
235 
236  public function setPathObject(ilWACPath $path_object): void
237  {
238  $this->path_object = $path_object;
239  }
240 
241  public function getDisposition(): string
242  {
243  return $this->disposition;
244  }
245 
246  public function setDisposition(string $disposition): void
247  {
248  $this->disposition = $disposition;
249  }
250 
251  public function getOverrideMimetype(): string
252  {
254  }
255 
256  public function setOverrideMimetype(string $override_mimetype): void
257  {
258  $this->override_mimetype = $override_mimetype;
259  }
260 
261  public function isInitialized(): bool
262  {
263  return $this->initialized;
264  }
265 
266  public function setInitialized(bool $initialized): void
267  {
268  $this->initialized = $initialized;
269  }
270 
271  public function isSendStatusCode(): bool
272  {
274  }
275 
276  public function setSendStatusCode(bool $send_status_code): void
277  {
278  $this->send_status_code = $send_status_code;
279  }
280 
281  public function isRevalidateFolderTokens(): bool
282  {
284  }
285 
286  public function setRevalidateFolderTokens(bool $revalidate_folder_tokens): void
287  {
288  $this->revalidate_folder_tokens = $revalidate_folder_tokens;
289  }
290 
291  public static function isUseSeperateLogfile(): bool
292  {
293  return self::$use_seperate_logfile;
294  }
295 
296  public static function setUseSeperateLogfile(bool $use_seperate_logfile): void
297  {
298  self::$use_seperate_logfile = $use_seperate_logfile;
299  }
300 
304  public function getAppliedCheckingMethods(): array
305  {
307  }
308 
312  public function setAppliedCheckingMethods(array $applied_checking_methods): void
313  {
314  $this->applied_checking_methods = $applied_checking_methods;
315  }
316 
317  protected function addAppliedCheckingMethod(int $method): void
318  {
319  $this->applied_checking_methods[] = $method;
320  }
321 
322  protected function initAnonymousSession(): void
323  {
324  global $DIC;
325  session_destroy();
331  $ilAuthSession = $DIC['ilAuthSession'];
332  $ilAuthSession->regenerateId();
333  $ilAuthSession->setUserId(ANONYMOUS_USER_ID);
334  $ilAuthSession->setAuthenticated(false, ANONYMOUS_USER_ID);
335  $DIC->user()->setId(ANONYMOUS_USER_ID);
336  }
337 }
setPathObject(ilWACPath $path_object)
const CONTEXT_WAC
const ANONYMOUS_USER_ID
Definition: constants.php:27
$response
Definition: xapitoken.php:90
setAppliedCheckingMethods(array $applied_checking_methods)
setInitialized(bool $initialized)
$http
Definition: deliver.php:14
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
setOverrideMimetype(string $override_mimetype)
$path
Definition: ltiservices.php:30
static initILIAS()
ilias initialisation
setSendStatusCode(bool $send_status_code)
static http()
Fetches the global http state from ILIAS.
$GLOBALS["DIC"]
Definition: wac.php:30
Class ilWebAccessChecker.
global $DIC
Definition: shib_login.php:25
const CLIENT_WEB_DIR
Definition: constants.php:47
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
setRevalidateFolderTokens(bool $revalidate_folder_tokens)
static hasCheckingInstanceRegistered(ilWACPath $ilWACPath)
Searches a checking instance for the given wac path.
static init(string $a_type)
Init context by type.
static setUseSeperateLogfile(bool $use_seperate_logfile)
setDisposition(string $disposition)
getCleanURLdecodedPath()
Returns a clean (everything behind ? is removed and rawurldecoded path.
__construct(private Services $http, private CookieFactory $cookieFactory)
ilWebAccessChecker constructor.