ILIAS  release_5-3 Revision v5.3.23-19-g915713cf615
class.ilWACSignedPath.php
Go to the documentation of this file.
1 <?php
2 // declare(strict_types=1);
3 
10 
11 require_once('./Services/WebAccessChecker/class.ilWACException.php');
12 require_once('class.ilWACToken.php');
13 require_once('./Services/WebAccessChecker/classes/class.ilWebAccessChecker.php');
14 require_once './Services/WebAccessChecker/interfaces/PathType.php';
15 require_once './Services/WebAccessChecker/classes/HttpServiceAware.php';
16 
24 {
25  use HttpServiceAware;
26  const WAC_TOKEN_ID = 'il_wac_token';
27  const WAC_TIMESTAMP_ID = 'il_wac_ts';
28  const WAC_TTL_ID = 'il_wac_ttl';
29  const TS_SUFFIX = 'ts';
30  const TTL_SUFFIX = 'ttl';
31  const MAX_LIFETIME = 600;
35  protected $path_object = null;
39  protected $token_instance = null;
43  protected $type = PathType::FILE;
47  protected static $token_max_lifetime_in_seconds = 3;
51  protected static $cookie_max_lifetime_in_seconds = 300;
55  protected $checked = false;
59  private $httpService;
63  private $cookieFactory;
64 
65 
73  public function __construct(ilWACPath $ilWACPath, GlobalHttpState $httpState, CookieFactory $cookieFactory)
74  {
75  $this->setPathObject($ilWACPath);
76  $this->httpService = $httpState;
77  $this->cookieFactory = $cookieFactory;
78  }
79 
80 
85  public function getSignedPath()
86  {
87  if ($this->getType() !== PathType::FILE) {
89  }
90  if (!$this->getPathObject()->getOriginalRequest()) {
91  return '';
92  }
93  if (!$this->getPathObject()->fileExists()) {
94  // return $this->getPathObject()->getOriginalRequest();
95  }
96 
97  if (strpos($this->getPathObject()->getPath(), '?')) {
98  $path = $this->getPathObject()->getPath() . '&' . self::WAC_TOKEN_ID . '='
99  . $this->getTokenInstance()->getToken();
100  } else {
101  $path = $this->getPathObject()->getPath() . '?' . self::WAC_TOKEN_ID . '='
102  . $this->getTokenInstance()->getToken();
103  }
104 
105  $path = $path . '&' . self::WAC_TTL_ID . '=' . $this->getTokenInstance()->getTTL();
106  $path = $path . '&' . self::WAC_TIMESTAMP_ID . '='
107  . $this->getTokenInstance()->getTimestamp();
108 
109  return $path;
110  }
111 
112 
116  public function isFolderSigned()
117  {
118  $cookieJar = $this->httpService->cookieJar();
119 
120  $this->setType(PathType::FOLDER);
121  $plain_token = $this->buildTokenInstance();
122  $name = $plain_token->getHashedId();
123 
124  $tokenCookie = $cookieJar->get($name);
125  $timestampCookie = $cookieJar->get($name . self::TS_SUFFIX);
126  $ttlCookie = $cookieJar->get($name . self::TTL_SUFFIX);
127 
128  $defaultToken = '';
129  $tokenCookieValue = is_null($tokenCookie) ? $defaultToken : is_a($tokenCookie->getValue(), Cookie::class) ? $tokenCookie->getValue() : $defaultToken;
130 
131  $defaultTimestamp = 0;
132  $timestampCookieValue = is_null($timestampCookie) ? $defaultTimestamp : is_a($timestampCookie->getValue(), Cookie::class) ? $timestampCookie->getValue() : $defaultTimestamp;
133  $timestampCookieValue = intval($timestampCookieValue);
134 
135  $defaultTtl = 0;
136  $ttlCookieValue = is_null($ttlCookie) ? $defaultTtl : is_a($ttlCookie->getValue(), Cookie::class) ? $ttlCookie->getValue() : $defaultTtl;
137  $ttlCookieValue = intval($ttlCookieValue);
138 
139  $this->getPathObject()->setToken($tokenCookieValue);
140  $this->getPathObject()->setTimestamp($timestampCookieValue);
141  $this->getPathObject()->setTTL($ttlCookieValue);
142  $this->buildAndSetTokenInstance();
143 
144  return $this->getPathObject()->hasToken();
145  }
146 
147 
152  public function isFolderTokenValid()
153  {
154  if (!$this->isFolderSigned()) {
155  return false;
156  }
157 
158  return $this->checkToken();
159  }
160 
161 
165  protected function saveFolderToken()
166  {
167  $cookie_lifetime = self::getCookieMaxLifetimeInSeconds();
168  //$str = 'save folder token for folder: ' . $this->getPathObject()->getDirName() . ', valid for ' . $cookie_lifetime . 's';
169  $id = $this->getTokenInstance()->getHashedId();
170  $expire = time() + $cookie_lifetime;
171 
172  $tokenCookie = $this->cookieFactory->create($id, $this->getTokenInstance()->getToken())->withExpires(time()
173  + 24
174  * 3600)->withPath('/')->withSecure(false)->withDomain(null)->withSecure(false)->withHttpOnly(false);
175 
176  $timestampCookie = $this->cookieFactory->create($id
177  . self::TS_SUFFIX, time())->withExpires($expire)->withPath('/')->withDomain(null)->withSecure(false)->withHttpOnly(false);
178 
179  $ttlCookie = $this->cookieFactory->create($id
180  . self::TTL_SUFFIX, self::getCookieMaxLifetimeInSeconds())->withExpires($expire)->withPath('/')->withDomain(null)->withSecure(false)->withHttpOnly(false);
181 
182  $cookieJar = $this->httpService->cookieJar();
183  $response = $cookieJar->with($tokenCookie)->with($timestampCookie)->with($ttlCookie)->renderIntoResponseHeader($this->httpService->response());
184 
185  $this->httpService->saveResponse($response);
186  }
187 
188 
192  public function revalidatingFolderToken()
193  {
194  if ($this->getType() !== PathType::FOLDER) {
195  return false;
196  }
197  $this->buildAndSetTokenInstance(time(), self::getCookieMaxLifetimeInSeconds());
198  $this->saveFolderToken();
199 
200  return true;
201  }
202 
203 
207  public function isSignedPath()
208  {
209  return ($this->getPathObject()->hasToken() && $this->getPathObject()->hasTimestamp()
210  && $this->getPathObject()->hasTTL());
211  }
212 
213 
218  public function isSignedPathValid()
219  {
220  $this->buildAndSetTokenInstance($this->getPathObject()->getTimestamp(), $this->getPathObject()->getTTL());
221 
222  return $this->checkToken();
223  }
224 
225 
233  public static function signFile($path_to_file)
234  {
235  if (!$path_to_file) {
236  return '';
237  }
238  $ilWACPath = new ilWACPath($path_to_file);
239  if (!$ilWACPath->getClient()) {
240  return $path_to_file;
241  }
242  $obj = new self($ilWACPath, self::http(), new CookieFactoryImpl());
243  $obj->setType(PathType::FILE);
244  $obj->buildAndSetTokenInstance(time(), self::getTokenMaxLifetimeInSeconds());
245 
246  return $obj->getSignedPath();
247  }
248 
249 
254  public static function signFolderOfStartFile($start_file_path)
255  {
256  $obj = new self(new ilWACPath($start_file_path), self::http(), new CookieFactoryImpl());
257  $obj->setType(PathType::FOLDER);
258  $obj->buildAndSetTokenInstance(time(), self::getCookieMaxLifetimeInSeconds());
259  $obj->saveFolderToken();
260  }
261 
262 
266  public function getTokenInstance()
267  {
268  return $this->token_instance;
269  }
270 
271 
277  {
278  $this->token_instance = $token_instance;
279  }
280 
281 
285  public function getType()
286  {
287  return (int) $this->type;
288  }
289 
290 
295  public function setType($type)
296  {
297  assert(is_int($type));
298  $this->type = $type;
299  }
300 
301 
305  public function getPathObject()
306  {
307  return $this->path_object;
308  }
309 
310 
316  {
317  $this->path_object = $path_object;
318  }
319 
320 
325  protected function checkToken()
326  {
327  $request_token = $this->getPathObject()->getToken();
328  $request_ttl = $this->getPathObject()->getTTL();
329  $request_timestamp = $this->getPathObject()->getTimestamp();
330  $current_timestamp = time();
331 
332  $timestamp_valid = ($current_timestamp < ($request_timestamp + $request_ttl));
333 
334  if (!$timestamp_valid) {
335  $this->setChecked(true);
336 
337  return false;
338  }
339 
340  $simulatedTokenInstance = $this->buildTokenInstance($request_timestamp, $request_ttl);
341  $token_valid = ($simulatedTokenInstance->getToken() == $request_token);
342 
343  if (!$token_valid) {
344  $this->setChecked(true);
345 
346  return false;
347  }
348 
349  return true;
350  }
351 
352 
360  protected function buildTokenInstance($timestamp = 0, $ttl = 0)
361  {
362  assert(is_int($timestamp));
363  assert(is_int($ttl));
364  if (!$this->getType()) {
366  }
367 
368  switch ($this->getType()) {
369  case PathType::FOLDER:
370  $path = $this->getPathObject()->getModulePath();
371  break;
372  case PathType::FILE:
373  $path = $this->getPathObject()->getPathWithoutQuery();
374  break;
375  default:
376  $path = $this->getPathObject()->getPathWithoutQuery();
377  break;
378  }
379 
380  $client = $this->getPathObject()->getClient();
381  $timestamp = $timestamp ? $timestamp : $this->getPathObject()->getTimestamp();
382  $ttl = $ttl ? $ttl : $this->getPathObject()->getTTL();
383 
384  return new ilWACToken($path, $client, $timestamp, $ttl);
385  }
386 
387 
395  public function buildAndSetTokenInstance($timestamp = 0, $ttl = 0)
396  {
397  assert(is_int($timestamp));
398  assert(is_int($ttl));
399 
400  $this->setTokenInstance($this->buildTokenInstance($timestamp, $ttl));
401  }
402 
403 
407  public static function getTokenMaxLifetimeInSeconds()
408  {
409  return self::$token_max_lifetime_in_seconds;
410  }
411 
412 
420  {
421  assert(is_int($token_max_lifetime_in_seconds));
422  if ($token_max_lifetime_in_seconds > self::MAX_LIFETIME) {
424  }
425  self::$token_max_lifetime_in_seconds = $token_max_lifetime_in_seconds;
426  }
427 
428 
432  public static function getCookieMaxLifetimeInSeconds()
433  {
434  return self::$cookie_max_lifetime_in_seconds;
435  }
436 
437 
446  {
447  assert(is_int($cookie_max_lifetime_in_seconds));
448  if ($cookie_max_lifetime_in_seconds > self::MAX_LIFETIME) {
450  }
451  self::$cookie_max_lifetime_in_seconds = $cookie_max_lifetime_in_seconds;
452  }
453 
454 
458  protected function getRelevantLifeTime()
459  {
460  $request_ttl = $this->getPathObject()->getTTL();
461  if ($request_ttl > 0) {
462  return $request_ttl;
463  }
464  switch ($this->getType()) {
465  case PathType::FOLDER:
466  $life_time = self::getCookieMaxLifetimeInSeconds();
467  break;
468  case PathType::FILE:
469  $life_time = self::getTokenMaxLifetimeInSeconds();
470  break;
471  default:
472  $life_time = 0;
473  break;
474  }
475 
476  return $life_time;
477  }
478 
479 
483  public function isChecked()
484  {
485  return (bool) $this->checked;
486  }
487 
488 
493  public function setChecked($checked)
494  {
495  assert(is_bool($checked));
496  $this->checked = $checked;
497  }
498 }
$expire
Definition: saml2-acs.php:140
Interface GlobalHttpState.
buildTokenInstance($timestamp=0, $ttl=0)
Class ilWACException.
static getCookieMaxLifetimeInSeconds()
setTokenInstance(ilWACToken $token_instance)
$client
Definition: resume.php:9
if(!array_key_exists('StateId', $_REQUEST)) $id
__construct(ilWACPath $ilWACPath, GlobalHttpState $httpState, CookieFactory $cookieFactory)
ilWACSignedPath constructor.
Class ilWACPath.
trait HttpServiceAware
Trait HttpServiceAware.
static signFolderOfStartFile($start_file_path)
if($format !==null) $name
Definition: metadata.php:146
static http()
Fetches the global http state from ILIAS.
setPathObject(ilWACPath $path_object)
static setCookieMaxLifetimeInSeconds($cookie_max_lifetime_in_seconds)
buildAndSetTokenInstance($timestamp=0, $ttl=0)
Class ilWACSignedPath.
static signFile($path_to_file)
Class ilWACToken.
foreach($mandatory_scripts as $file) $timestamp
Definition: buildRTE.php:81
trait HttpServiceAware
Trait HttpServiceAware.
static setTokenMaxLifetimeInSeconds($token_max_lifetime_in_seconds)
Add data(end) time
Method that wraps PHPs time in order to allow simulations with the workflow.
static getTokenMaxLifetimeInSeconds()
static $cookie_max_lifetime_in_seconds
$response