ILIAS  release_10 Revision v10.1-43-ga1241a92c2f
class.ilSessionMaxIdleIsSetObjective.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
21 use ILIAS\Setup;
22 
23 class ilSessionMaxIdleIsSetObjective implements Setup\Objective
24 {
25  public function __construct(
26  protected Setup\Config $config
27  ) {
28  }
29 
30  public function getHash(): string
31  {
32  return hash('sha256', self::class);
33  }
34 
35  public function getLabel(): string
36  {
37  return "Ensures 'session_max_idle' is set properly";
38  }
39 
40  public function isNotable(): bool
41  {
42  return false;
43  }
44 
45  public function getPreconditions(Setup\Environment $environment): array
46  {
47  $http_config = $environment->getConfigFor('http');
48 
49  return [
53  new ilHttpConfigStoredObjective($http_config)
54  ];
55  }
56 
57  public function achieve(Setup\Environment $environment): Setup\Environment
58  {
60  $client_ini = $environment->getResource(Setup\Environment::RESOURCE_CLIENT_INI);
62  $ini = $environment->getResource(Setup\Environment::RESOURCE_ILIAS_INI);
64  $io = $environment->getResource(Setup\Environment::RESOURCE_ADMIN_INTERACTION);
65  $factory = $environment->getResource(Setup\Environment::RESOURCE_SETTINGS_FACTORY);
67  $settings = $factory->settingsFor('common');
68 
69  $session_max_idle = $this->config->getSessionMaxIdle();
70 
71  $url = $ini->readVariable('server', 'http_path');
72  $filename = uniqid((string) mt_rand(), true) . '.php';
73  $url .= '/' . $filename;
74  $token = bin2hex(random_bytes(32));
76 
77  try {
78  $curl = null;
80  $curl = $this->getCurlConnection($settings, $url, $token);
81  $result = $curl->exec();
82  } else {
83  $result = $this->getPHPIniValuesByFileGetContents($url, $token);
84  }
85  } catch (Throwable $e) {
86  $io->inform(
87  "An error occurred while trying to determine the values for 'session.cookie_lifetime' and" . PHP_EOL .
88  "'session.gc_maxlifetime' in your php.ini: {$e->getMessage()}" . PHP_EOL .
89  'You can IGNORE the the error if you are sure these settings comply with our expection to' . PHP_EOL .
90  'to ensure a proper session handling.' . PHP_EOL .
91  $e->getTraceAsString()
92  );
93 
94  $client_ini->setVariable('session', 'expire', (string) $session_max_idle);
95 
96  return $environment;
97  } finally {
98  if (!is_null($curl)) {
99  $curl->close();
100  }
101  unlink("public/$filename");
102  }
103 
104  if ($result === '') {
105  $message =
106  "ILIAS could not determine the value for 'session.cookie_lifetime' and 'session.gc_maxlifetime'" . PHP_EOL .
107  'in your php.ini to check whether it complies with our expection to ensure a proper session handling.' . PHP_EOL .
108  'Do you like to continue, anyway?';
109 
110  if (!$io->confirmOrDeny($message)) {
111  throw new Setup\NoConfirmationException($message);
112  }
113  }
114 
115  [$cookie_lifetime, $gc_maxlifetime] = explode('&', $result);
116 
117  if ($cookie_lifetime != 0) {
118  $message =
119  "The value 'session.cookie_lifetime' in your php.ini does not correspond" . PHP_EOL .
120  "to the value '0' recommended by ILIAS. Do you want to continue anyway?";
121 
122  if (!$io->confirmOrDeny($message)) {
123  throw new Setup\NoConfirmationException($message);
124  }
125  }
126 
127  if ($gc_maxlifetime <= $session_max_idle) {
128  $message =
129  "The value 'session.gc_maxlifetime' in your php.ini is smaller or equal than" . PHP_EOL .
130  "'session_max_idle' in your ILIAS-Config. ILIAS recommends a bigger value." . PHP_EOL .
131  'Do you want to continue anyway?';
132 
133  if (!$io->confirmOrDeny($message)) {
134  throw new Setup\NoConfirmationException($message);
135  }
136  }
137 
138  $client_ini->setVariable('session', 'expire', (string) $session_max_idle);
139 
140  return $environment;
141  }
142 
143  public function isApplicable(Setup\Environment $environment): bool
144  {
145  $factory = $environment->getResource(Setup\Environment::RESOURCE_SETTINGS_FACTORY);
147  $settings = $factory->settingsFor('common');
149  $ini = $environment->getResource(Setup\Environment::RESOURCE_ILIAS_INI);
151  $io = $environment->getResource(Setup\Environment::RESOURCE_ADMIN_INTERACTION);
152 
153  $url = $ini->readVariable('server', 'http_path');
154 
156  try {
157  $curl = $this->getCurlConnection($settings, $url);
158  $curl->exec();
159  $result = $curl->getInfo(CURLINFO_HTTP_CODE);
160  if ($result !== 200) {
161  throw new \Exception();
162  }
163  } catch (\Exception $e) {
164  $this->infoNoConnection($io);
165  return false;
166  } finally {
167  $curl->close();
168  }
169  } else {
170  try {
172  } catch (Exception $e) {
173  $this->infoNoConnection($io);
174  return false;
175  }
176  }
177 
178  return true;
179  }
180 
181  private function generateServerInfoFile(string $filename, string $token): void
182  {
183  $content = <<<TEXT
184 <?php
185 if (!isset(\$_GET['token'])) {
186  return "";
187 }
188 
189 if (\$_GET['token'] !== "$token") {
190  return "";
191 }
192 
193 \$scl = ini_get('session.cookie_lifetime');
194 \$smlt = ini_get('session.gc_maxlifetime');
195 
196 echo \$scl . "&" . \$smlt;
197 TEXT;
198 
199  file_put_contents("public/$filename", $content);
200  }
201 
205  private function getCurlConnection(ilSetting $settings, string $url, ?string $token = null): ilCurlConnection
206  {
207  if (!is_null($token)) {
208  $url = $url . "?token=" . $token;
209  }
210 
211  $curl = new ilCurlConnection(
212  $url,
213  new ilProxySettings($settings)
214  );
215  $curl->init();
216  $curl->setOpt(CURLOPT_SSL_VERIFYPEER, 0);
217  $curl->setOpt(CURLOPT_SSL_VERIFYHOST, 0);
218  $curl->setOpt(CURLOPT_RETURNTRANSFER, 1);
219  $curl->setOpt(CURLOPT_FOLLOWLOCATION, 1);
220  $curl->setOpt(CURLOPT_MAXREDIRS, 1);
221 
222  return $curl;
223  }
224 
228  private function getPHPIniValuesByFileGetContents(string $url, ?string $token = null): string
229  {
230  set_error_handler(static function (int $severity, string $message, string $file, int $line): never {
231  throw new ErrorException($message, $severity, $severity, $file, $line);
232  });
233 
234  if (!is_null($token)) {
235  $url = $url . "?token=" . $token;
236  }
237 
238  try {
239  return file_get_contents($url);
240  } catch (ErrorException $e) {
241  restore_error_handler();
242  throw $e;
243  }
244  }
245 
246  private function infoNoConnection(Setup\CLI\IOWrapper $io): void
247  {
248  $message =
249  "ilSessionMaxIdleIsSetObjective:\n" .
250  "Cannot establish proper connection to webserver.\n" .
251  "In the event of an installation the value for session expire\n" .
252  "will be the default value.\n" .
253  "In the event of an update, the current value for session expire\n" .
254  "is retained."
255  ;
256 
257  $io->inform($message);
258  }
259 }
getPHPIniValuesByFileGetContents(string $url, ?string $token=null)
class ilProxySettings
$url
Definition: shib_logout.php:63
getCurlConnection(ilSetting $settings, string $url, ?string $token=null)
getPreconditions(Setup\Environment $environment)
$token
Definition: xapitoken.php:67
$_GET['cmd']
Definition: lti.php:26
$filename
Definition: buildRTE.php:78
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
An environment holds resources to be used in the setup process.
Definition: Environment.php:27
A configuration for the setup.
Definition: Config.php:26
generateServerInfoFile(string $filename, string $token)
$ini
Definition: raiseError.php:4