ILIAS  release_8 Revision v8.24
class.ilWACSignedPath.php
Go to the documentation of this file.
1<?php
2
19// declare(strict_types=1);
25
33{
34 public const WAC_TOKEN_ID = 'il_wac_token';
35 public const WAC_TIMESTAMP_ID = 'il_wac_ts';
36 public const WAC_TTL_ID = 'il_wac_ttl';
37 public const TS_SUFFIX = 'ts';
38 public const TTL_SUFFIX = 'ttl';
39 public const MAX_LIFETIME = 600;
40
41 protected ?ilWACPath $path_object = null;
42 protected ?ilWACToken $token_instance = null;
43 protected int $type = PathType::FILE;
44 protected static int $token_max_lifetime_in_seconds = 3;
45 protected static int $cookie_max_lifetime_in_seconds = 300;
46 protected bool $checked = false;
49
53 public function __construct(ilWACPath $ilWACPath, GlobalHttpState $httpState, CookieFactory $cookieFactory)
54 {
55 $this->setPathObject($ilWACPath);
56 $this->httpService = $httpState;
57 $this->cookieFactory = $cookieFactory;
58 }
59
63 public function getSignedPath(): string
64 {
65 if ($this->getType() !== PathType::FILE) {
67 }
68 if ($this->getPathObject()->getOriginalRequest() === '' || $this->getPathObject()->getOriginalRequest() === '0') {
69 return '';
70 }
71 if (!$this->getPathObject()->fileExists()) {
72 // return $this->getPathObject()->getOriginalRequest();
73 }
74
75 if (strpos($this->getPathObject()->getPath(), '?')) {
76 $path = $this->getPathObject()->getPath() . '&' . self::WAC_TOKEN_ID . '='
77 . $this->getTokenInstance()->getToken();
78 } else {
79 $path = $this->getPathObject()->getPath() . '?' . self::WAC_TOKEN_ID . '='
80 . $this->getTokenInstance()->getToken();
81 }
82
83 $path .= '&' . self::WAC_TTL_ID . '=' . $this->getTokenInstance()->getTTL();
84
85 return $path . '&' . self::WAC_TIMESTAMP_ID . '='
86 . $this->getTokenInstance()->getTimestamp();
87 }
88
89 public function isFolderSigned(): bool
90 {
91 $this->httpService->cookieJar();
92
93 $this->setType(PathType::FOLDER);
94 $plain_token = $this->buildTokenInstance();
95 $name = $plain_token->getHashedId();
96
97 // Token
98 $default_token = '';
99 $token_cookie_value = $this->httpService->request()->getCookieParams()[$name] ?? $default_token;
100 // Timestamp
101 $default_timestamp = 0;
102 $timestamp_cookie_value = $this->httpService->request()->getCookieParams()[$name . self::TS_SUFFIX] ?? $default_timestamp;
103 $timestamp_cookie_value = (int) $timestamp_cookie_value;
104 // TTL
105 $default_ttl = 0;
106 $ttl_cookie_value = $this->httpService->request()->getCookieParams()[$name . self::TTL_SUFFIX] ?? $default_ttl;
107 $ttl_cookie_value = (int) $ttl_cookie_value;
108
109 $this->getPathObject()->setToken($token_cookie_value);
110 $this->getPathObject()->setTimestamp($timestamp_cookie_value);
111 $this->getPathObject()->setTTL($ttl_cookie_value);
113
114 return $this->getPathObject()->hasToken();
115 }
116
120 public function isFolderTokenValid(): bool
121 {
122 if (!$this->isFolderSigned()) {
123 return false;
124 }
125
126 return $this->checkToken();
127 }
128
129 protected function saveFolderToken(): void
130 {
131 $ttl = $this->getPathObject()->getTTL();
132 $cookie_lifetime = $ttl !== 0 ? $ttl : self::getCookieMaxLifetimeInSeconds();
133 $id = $this->getTokenInstance()->getHashedId();
134 $expire = time() + $cookie_lifetime + 3600;
135 $secure = true;
136 $domain = null;
137 $http_only = true;
138 $path = '/';
139
140 $tokenCookie = $this->cookieFactory->create($id, $this->getTokenInstance()->getToken())
141 ->withExpires($expire)
142 ->withPath($path)
143 ->withSecure($secure)
144 ->withDomain($domain)
145 ->withHttpOnly($http_only);
146
147 $timestampCookie = $this->cookieFactory->create($id . self::TS_SUFFIX, time())
148 ->withExpires($expire)
149 ->withPath($path)
150 ->withDomain($domain)
151 ->withSecure($secure)
152 ->withHttpOnly($http_only);
153
154 $ttlCookie = $this->cookieFactory->create($id . self::TTL_SUFFIX, $cookie_lifetime)
155 ->withExpires($expire)
156 ->withPath($path)
157 ->withDomain($domain)
158 ->withSecure($secure)
159 ->withHttpOnly($http_only);
160
161 $jar = $this->httpService->cookieJar()->with($tokenCookie)
162 ->with($timestampCookie)
163 ->with($ttlCookie);
164
165 // FIX: currently the cookies are never stored, we must use setcookie
166 foreach ($jar->getAll() as $cookie) {
167 setcookie(
168 $cookie->getName(),
169 $cookie->getValue(),
170 $cookie->getExpires(),
171 $cookie->getPath(),
172 $cookie->getDomain(),
173 $cookie->getSecure(),
174 $cookie->getHttpOnly()
175 );
176 }
177 }
178
179 public function revalidatingFolderToken(): bool
180 {
181 if ($this->getType() !== PathType::FOLDER) {
182 return false;
183 }
184 $this->buildAndSetTokenInstance(time(), $this->getPathObject()->getTTL());
185 $this->getPathObject()->setTTL($this->getTokenInstance()->getTTL());
186 $this->getPathObject()->setTimestamp($this->getTokenInstance()->getTimestamp());
187 $this->getPathObject()->setToken($this->getTokenInstance()->getToken());
188
189 $this->saveFolderToken();
190
191 return true;
192 }
193
194 public function isSignedPath(): bool
195 {
196 return ($this->getPathObject()->hasToken() && $this->getPathObject()->hasTimestamp()
197 && $this->getPathObject()->hasTTL());
198 }
199
203 public function isSignedPathValid(): bool
204 {
205 $this->buildAndSetTokenInstance($this->getPathObject()->getTimestamp(), $this->getPathObject()->getTTL());
206
207 return $this->checkToken();
208 }
209
215 public static function signFile(string $path_to_file): string
216 {
217 global $DIC;
218 if ($path_to_file === '' || $path_to_file === '0') {
219 return '';
220 }
221 $ilWACPath = new ilWACPath($path_to_file, false);
222 if ($ilWACPath->getClient() === '' || $ilWACPath->getClient() === '0') {
223 return $path_to_file;
224 }
225 $obj = new self($ilWACPath, $DIC->http(), new CookieFactoryImpl());
226 $obj->setType(PathType::FILE);
227 $obj->buildAndSetTokenInstance(time(), self::getTokenMaxLifetimeInSeconds());
228
229 return $obj->getSignedPath();
230 }
231
232 public static function signFolderOfStartFile(string $start_file_path): void
233 {
234 global $DIC;
235 $obj = new self(new ilWACPath($start_file_path, false), $DIC->http(), new CookieFactoryImpl());
236 $obj->setType(PathType::FOLDER);
237 $obj->buildAndSetTokenInstance(time(), self::getCookieMaxLifetimeInSeconds());
238 $obj->saveFolderToken();
239 }
240
241 public function getTokenInstance(): ?\ilWACToken
242 {
244 }
245
247 {
248 $this->token_instance = $token_instance;
249 }
250
251 public function getType(): int
252 {
253 return $this->type;
254 }
255
256 public function setType(int $type): void
257 {
258 $this->type = $type;
259 }
260
261 public function getPathObject(): ?\ilWACPath
262 {
263 return $this->path_object;
264 }
265
266 public function setPathObject(ilWACPath $path_object): void
267 {
268 $this->path_object = $path_object;
269 }
270
274 protected function checkToken(): bool
275 {
276 $request_token_string = $this->getPathObject()->getToken();
277 $request_ttl = $this->getPathObject()->getTTL();
278 $request_timestamp = $this->getPathObject()->getTimestamp();
279 $current_timestamp = time();
280
281 $timestamp_valid = ($current_timestamp < ($request_timestamp + $request_ttl));
282
283 if (!$timestamp_valid) {
284 $this->setChecked(true);
285
286 return false;
287 }
288
289 $simulated_token = $this->buildTokenInstance($request_timestamp, $request_ttl);
290 $simulated_token_string = $simulated_token->getToken();
291 $token_valid = ($simulated_token_string === $request_token_string);
292
293 if (!$token_valid) {
294 $this->setChecked(true);
295
296 return false;
297 }
298
299 return true;
300 }
301
306 protected function buildTokenInstance(int $timestamp = 0, int $ttl = 0): \ilWACToken
307 {
308 if ($this->getType() === 0) {
310 }
311
312 switch ($this->getType()) {
313 case PathType::FOLDER:
314 $path = $this->getPathObject()->getSecurePath();
315 break;
316 default:
317 $path = $this->getPathObject()->getPathWithoutQuery();
318 break;
319 }
320
321 $client = $this->getPathObject()->getClient();
322 $timestamp = $timestamp !== 0 ? $timestamp : $this->getPathObject()->getTimestamp();
323 $ttl = $ttl !== 0 ? $ttl : $this->getPathObject()->getTTL();
324
325 return new ilWACToken($path, $client, $timestamp, $ttl);
326 }
327
332 public function buildAndSetTokenInstance(int $timestamp = 0, int $ttl = 0): void
333 {
334 $this->setTokenInstance($this->buildTokenInstance($timestamp, $ttl));
335 }
336
337 public static function getTokenMaxLifetimeInSeconds(): int
338 {
340 }
341
347 {
348 if ($token_max_lifetime_in_seconds > self::MAX_LIFETIME) {
350 }
351 self::$token_max_lifetime_in_seconds = $token_max_lifetime_in_seconds;
352 }
353
354 public static function getCookieMaxLifetimeInSeconds(): int
355 {
357 }
358
365 {
366 if ($cookie_max_lifetime_in_seconds > self::MAX_LIFETIME) {
368 }
369 self::$cookie_max_lifetime_in_seconds = $cookie_max_lifetime_in_seconds;
370 }
371
372 protected function getRelevantLifeTime(): int
373 {
374 $request_ttl = $this->getPathObject()->getTTL();
375 if ($request_ttl > 0) {
376 return $request_ttl;
377 }
378 switch ($this->getType()) {
379 case PathType::FOLDER:
381 break;
382 case PathType::FILE:
384 break;
385 default:
386 $life_time = 0;
387 break;
388 }
389
390 return $life_time;
391 }
392
393 public function isChecked(): bool
394 {
395 return $this->checked;
396 }
397
398 public function setChecked(bool $checked): void
399 {
400 $this->checked = $checked;
401 }
402}
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
Definition: plugin.php:23
foreach($mandatory_scripts as $file) $timestamp
Definition: buildRTE.php:70
Class Services.
Definition: Services.php:38
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...
Class ilWACSignedPath.
static setCookieMaxLifetimeInSeconds(int $cookie_max_lifetime_in_seconds)
static setTokenMaxLifetimeInSeconds(int $token_max_lifetime_in_seconds)
CookieFactory $cookieFactory
static int $cookie_max_lifetime_in_seconds
GlobalHttpState $httpService
__construct(ilWACPath $ilWACPath, GlobalHttpState $httpState, CookieFactory $cookieFactory)
ilWACSignedPath constructor.
setChecked(bool $checked)
setTokenInstance(ilWACToken $token_instance)
static signFolderOfStartFile(string $start_file_path)
static signFile(string $path_to_file)
static getCookieMaxLifetimeInSeconds()
setPathObject(ilWACPath $path_object)
buildTokenInstance(int $timestamp=0, int $ttl=0)
static int $token_max_lifetime_in_seconds
static getTokenMaxLifetimeInSeconds()
buildAndSetTokenInstance(int $timestamp=0, int $ttl=0)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
$client
global $DIC
Definition: feed.php:28
Interface GlobalHttpState.
Interface PathType.
Definition: PathType.php:31
$path
Definition: ltiservices.php:32
if($format !==null) $name
Definition: metadata.php:247