ILIAS  release_8 Revision v8.24
class.ilWebAccessChecker.php
Go to the documentation of this file.
1<?php
2
22use Psr\Http\Message\UriInterface;
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 private Services $http;
55
59 public function __construct(Services $httpState, CookieFactory $cookieFactory)
60 {
61 try {
62 $this->setPathObject(new ilWACPath($httpState->request()->getRequestTarget()));
63 } catch (ilWACException $e) {
64 if ($e->getCode() !== ilWACException::NOT_FOUND) {
65 throw $e;
66 }
67 $this->ressource_not_found = $e;
68 }
69
70 $this->http = $httpState;
71 $this->cookieFactory = $cookieFactory;
72 }
73
77 public function check(): bool
78 {
79 if ($this->getPathObject() === null) {
80 if ($this->ressource_not_found !== null) {
81 throw new ilWACException(ilWACException::NOT_FOUND, '', $this->ressource_not_found);
82 }
83
85 }
86
87 // Check if Path has been signed with a token
88 $ilWACSignedPath = new ilWACSignedPath($this->getPathObject(), $this->http, $this->cookieFactory);
89 if ($ilWACSignedPath->isSignedPath()) {
90 $this->addAppliedCheckingMethod(self::CM_FILE_TOKEN);
91 if ($ilWACSignedPath->isSignedPathValid()) {
92 $this->setChecked(true);
93 $this->sendHeader('checked using token');
94
95 return true;
96 }
97 }
98
99 // Check if the whole secured folder has been signed
100 if ($ilWACSignedPath->isFolderSigned()) {
101 $this->addAppliedCheckingMethod(self::CM_FOLDER_TOKEN);
102 if ($ilWACSignedPath->isFolderTokenValid()) {
103 if ($this->isRevalidateFolderTokens()) {
104 $ilWACSignedPath->revalidatingFolderToken();
105 }
106 $this->setChecked(true);
107 $this->sendHeader('checked using secure folder');
108
109 return true;
110 }
111 }
112
113 // Fallback, have to initiate ILIAS
114 $this->initILIAS();
115
116 // Check if Path is within accepted paths
117 if ($this->getPathObject()->getModuleType() !== 'rs') {
118 $clean_path = $this->getPathObject()->getCleanURLdecodedPath();
119 $path = realpath($clean_path);
120 $data_dir = realpath(CLIENT_WEB_DIR);
121 if (strpos($path, $data_dir) !== 0) {
122 return false;
123 }
124 if (dirname($path) === $data_dir && is_file($path)) {
125 return false;
126 }
127 }
128
130 // Maybe the path has been registered, lets check
131 $checkingInstance = ilWACSecurePath::getCheckingInstance($this->getPathObject());
132 $this->addAppliedCheckingMethod(self::CM_CHECKINGINSTANCE);
133 $canBeDelivered = $checkingInstance->canBeDelivered($this->getPathObject());
134 if ($canBeDelivered) {
135 $this->sendHeader('checked using fallback');
136 if ($ilWACSignedPath->isFolderSigned() && $this->isRevalidateFolderTokens()) {
137 $ilWACSignedPath->revalidatingFolderToken();
138 }
139 }
140 $this->setChecked(true);
141 return $canBeDelivered;
142 }
143
144 // none of the checking mechanisms could have been applied. no access
145 $this->setChecked(true);
146 $this->addAppliedCheckingMethod(self::CM_SECFOLDER);
147 return !$this->getPathObject()->isInSecFolder();
148 }
149
150 protected function sendHeader(string $message): void
151 {
152 $response = $this->http->response()->withHeader('X-ILIAS-WebAccessChecker', $message);
153 $this->http->saveResponse($response);
154 }
155
156 public function initILIAS(): void
157 {
158 global $DIC;
159
160 if ($this->isInitialized()) {
161 return;
162 }
163
164 $GLOBALS['COOKIE_PATH'] = '/';
165
166 $cookie = $this->cookieFactory->create('ilClientId', $this->getPathObject()->getClient())
167 ->withPath('/')
168 ->withExpires(0);
169
170 $response = $this->http->cookieJar()
171 ->with($cookie)
172 ->renderIntoResponseHeader($this->http->response());
173
174 $this->http->saveResponse($response);
175
177 try {
179 $this->checkUser();
180 $this->checkPublicSection();
181 } catch (Exception $e) {
182 if ($e instanceof ilWACException
183 && $e->getCode() !== ilWACException::ACCESS_DENIED_NO_LOGIN) {
184 throw $e;
185 }
186 if (($e instanceof Exception && $e->getMessage() === 'Authentication failed.')
187 || $e->getCode() === ilWACException::ACCESS_DENIED_NO_LOGIN) {
188 $this->initAnonymousSession();
189 $this->checkUser();
190 $this->checkPublicSection();
191 }
192 }
193 $this->setInitialized(true);
194
195 // This workaround is needed because these issues:
196 // https://mantis.ilias.de/view.php?id=32284 and
197 // https://mantis.ilias.de/view.php?id=32063
198 if ($DIC->user()->getId() === 0) {
199 $DIC->user()->setId(ANONYMOUS_USER_ID);
200 }
201 }
202
206 protected function checkPublicSection(): void
207 {
208 global $DIC;
209 $is_anonymous = ((int) $DIC->user()->getId() === (int) ANONYMOUS_USER_ID);
210 $is_null_user = ($DIC->user()->getId() === 0);
211 $pub_section_activated = (bool) $DIC['ilSetting']->get('pub_section');
212 $isset = isset($DIC['ilSetting']);
213 $instanceof = $DIC['ilSetting'] instanceof ilSetting;
214
215 if (!$isset || !$instanceof) {
217 }
218
219 if ($pub_section_activated && ($is_null_user || $is_anonymous)) {
220 // Request is initiated from an enabled public area
221 return;
222 }
223
224 if ($is_anonymous || $is_null_user) {
226 }
227 }
228
229 protected function checkUser(): void
230 {
231 global $DIC;
232
233 $is_user = $DIC->user() instanceof ilObjUser;
234 $user_id_is_zero = ((int) $DIC->user()->getId() === 0);
235 if (!$is_user || $user_id_is_zero) {
237 }
238 }
239
240 public function isChecked(): bool
241 {
242 return $this->checked;
243 }
244
245 public function setChecked(bool $checked): void
246 {
247 $this->checked = $checked;
248 }
249
250 public function getPathObject(): ?\ilWACPath
251 {
252 return $this->path_object;
253 }
254
255 public function setPathObject(ilWACPath $path_object): void
256 {
257 $this->path_object = $path_object;
258 }
259
260 public function getDisposition(): string
261 {
262 return $this->disposition;
263 }
264
265 public function setDisposition(string $disposition): void
266 {
267 $this->disposition = $disposition;
268 }
269
270 public function getOverrideMimetype(): string
271 {
273 }
274
275 public function setOverrideMimetype(string $override_mimetype): void
276 {
277 $this->override_mimetype = $override_mimetype;
278 }
279
280 public function isInitialized(): bool
281 {
282 return $this->initialized;
283 }
284
285 public function setInitialized(bool $initialized): void
286 {
287 $this->initialized = $initialized;
288 }
289
290 public function isSendStatusCode(): bool
291 {
293 }
294
295 public function setSendStatusCode(bool $send_status_code): void
296 {
297 $this->send_status_code = $send_status_code;
298 }
299
300 public function isRevalidateFolderTokens(): bool
301 {
303 }
304
306 {
307 $this->revalidate_folder_tokens = $revalidate_folder_tokens;
308 }
309
310 public static function isUseSeperateLogfile(): bool
311 {
313 }
314
315 public static function setUseSeperateLogfile(bool $use_seperate_logfile): void
316 {
317 self::$use_seperate_logfile = $use_seperate_logfile;
318 }
319
323 public function getAppliedCheckingMethods(): array
324 {
326 }
327
332 {
333 $this->applied_checking_methods = $applied_checking_methods;
334 }
335
336 protected function addAppliedCheckingMethod(int $method): void
337 {
338 $this->applied_checking_methods[] = $method;
339 }
340
341 protected function initAnonymousSession(): void
342 {
343 global $DIC;
344 session_destroy();
350 $ilAuthSession = $DIC['ilAuthSession'];
351 $ilAuthSession->regenerateId();
352 $ilAuthSession->setUserId(ANONYMOUS_USER_ID);
353 $ilAuthSession->setAuthenticated(false, ANONYMOUS_USER_ID);
354 $DIC->user()->setId(ANONYMOUS_USER_ID);
355 }
356}
if(!defined('PATH_SEPARATOR')) $GLOBALS['_PEAR_default_error_mode']
Definition: PEAR.php:64
Class Services.
Definition: Services.php:38
static init(string $a_type)
Init context by type.
const CONTEXT_WAC
static initILIAS()
ilias initialisation
User class.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static hasCheckingInstanceRegistered(ilWACPath $ilWACPath)
Searches a checking instance for the given wac path.
Class ilWACSignedPath.
Class ilWebAccessChecker.
ilWACException $ressource_not_found
setInitialized(bool $initialized)
__construct(Services $httpState, CookieFactory $cookieFactory)
ilWebAccessChecker constructor.
setOverrideMimetype(string $override_mimetype)
setSendStatusCode(bool $send_status_code)
setAppliedCheckingMethods(array $applied_checking_methods)
setRevalidateFolderTokens(bool $revalidate_folder_tokens)
setPathObject(ilWACPath $path_object)
setDisposition(string $disposition)
static setUseSeperateLogfile(bool $use_seperate_logfile)
const CLIENT_WEB_DIR
Definition: constants.php:47
const ANONYMOUS_USER_ID
Definition: constants.php:27
global $DIC
Definition: feed.php:28
$path
Definition: ltiservices.php:32
static http()
Fetches the global http state from ILIAS.
$response
$message
Definition: xapiexit.php:32