ILIAS  trunk Revision v11.0_alpha-2638-g80c1d007f79
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 true;
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  'ensure a proper session handling.'
91  );
92 
93  $client_ini->setVariable('session', 'expire', (string) $session_max_idle);
94 
95  return $environment;
96  } finally {
97  $curl?->close();
98  unlink("public/$filename");
99  }
100 
101  if ($result === '') {
102  $message =
103  "ILIAS could not determine the value for 'session.cookie_lifetime' and 'session.gc_maxlifetime'" . PHP_EOL .
104  'in your php.ini to check whether it complies with our expection to ensure a proper session handling.' . PHP_EOL .
105  'Do you like to continue, anyway?';
106 
107  if (!$io->confirmOrDeny($message)) {
108  throw new Setup\NoConfirmationException($message);
109  }
110  }
111 
112  [$cookie_lifetime, $gc_maxlifetime] = explode('&', $result);
113 
114  if ($cookie_lifetime != 0) {
115  $message =
116  "The value 'session.cookie_lifetime' in your php.ini does not correspond" . PHP_EOL .
117  "to the value '0' recommended by ILIAS. Do you want to continue anyway?";
118 
119  if (!$io->confirmOrDeny($message)) {
120  throw new Setup\NoConfirmationException($message);
121  }
122  }
123 
124  if ($gc_maxlifetime <= $session_max_idle) {
125  $message =
126  "The value 'session.gc_maxlifetime' in your php.ini is smaller or equal than" . PHP_EOL .
127  "'session_max_idle' in your ILIAS-Config. ILIAS recommends a bigger value." . PHP_EOL .
128  'Do you want to continue anyway?';
129 
130  if (!$io->confirmOrDeny($message)) {
131  throw new Setup\NoConfirmationException($message);
132  }
133  }
134 
135  $client_ini->setVariable('session', 'expire', (string) $session_max_idle);
136 
137  return $environment;
138  }
139 
140  public function isApplicable(Setup\Environment $environment): bool
141  {
142  $factory = $environment->getResource(Setup\Environment::RESOURCE_SETTINGS_FACTORY);
144  $settings = $factory->settingsFor('common');
146  $ini = $environment->getResource(Setup\Environment::RESOURCE_ILIAS_INI);
148  $io = $environment->getResource(Setup\Environment::RESOURCE_ADMIN_INTERACTION);
149 
150  $url = $ini->readVariable('server', 'http_path');
151 
153  try {
154  $curl = null;
155  $curl = $this->getCurlConnection($settings, $url);
156  $curl->exec();
157  $result = $curl->getInfo(CURLINFO_HTTP_CODE);
158  if ($result !== 200) {
159  throw new Exception();
160  }
161  } catch (Exception) {
162  $this->infoNoConnection($io);
163  return false;
164  } finally {
165  $curl?->close();
166  }
167  } else {
168  try {
170  } catch (Exception) {
171  $this->infoNoConnection($io);
172  return false;
173  }
174  }
175 
176  return true;
177  }
178 
179  private function generateServerInfoFile(string $filename, string $token): void
180  {
181  $content = <<<TEXT
182 <?php
183 if (!isset(\$_GET['token'])) {
184  return "";
185 }
186 
187 if (\$_GET['token'] !== "$token") {
188  return "";
189 }
190 
191 \$scl = ini_get('session.cookie_lifetime');
192 \$smlt = ini_get('session.gc_maxlifetime');
193 
194 echo \$scl . "&" . \$smlt;
195 TEXT;
196 
197  file_put_contents("public/$filename", $content);
198  }
199 
203  private function getCurlConnection(ilSetting $settings, string $url, ?string $token = null): ilCurlConnection
204  {
205  if ($token !== null) {
206  $url .= '?token=' . $token;
207  }
208 
209  $curl = new ilCurlConnection(
210  $url,
211  new ilProxySettings($settings)
212  );
213  $curl->init();
214  $curl->setOpt(CURLOPT_SSL_VERIFYPEER, 0);
215  $curl->setOpt(CURLOPT_SSL_VERIFYHOST, 0);
216  $curl->setOpt(CURLOPT_RETURNTRANSFER, 1);
217  $curl->setOpt(CURLOPT_FOLLOWLOCATION, 1);
218  $curl->setOpt(CURLOPT_MAXREDIRS, 1);
219 
220  return $curl;
221  }
222 
226  private function getPHPIniValuesByFileGetContents(string $url, ?string $token = null): string
227  {
228  set_error_handler(static function (int $severity, string $message, string $file, int $line): never {
229  throw new ErrorException($message, $severity, $severity, $file, $line);
230  });
231 
232  if ($token !== null) {
233  $url .= '?token=' . $token;
234  }
235 
236  try {
237  return file_get_contents($url);
238  } catch (ErrorException $e) {
239  restore_error_handler();
240  throw $e;
241  }
242  }
243 
244  private function infoNoConnection(Setup\CLI\IOWrapper $io): void
245  {
246  $message =
247  "ilSessionMaxIdleIsSetObjective:\n" .
248  "Cannot establish proper connection to webserver.\n" .
249  "In the event of an installation the value for session expire\n" .
250  "will be the default value.\n" .
251  "In the event of an update, the current value for session expire\n" .
252  'is retained.'
253  ;
254 
255  $io->inform($message);
256  }
257 }
getPHPIniValuesByFileGetContents(string $url, ?string $token=null)
$_GET["client_id"]
Definition: webdav.php:30
class ilProxySettings
$url
Definition: shib_logout.php:68
getCurlConnection(ilSetting $settings, string $url, ?string $token=null)
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
getPreconditions(Setup\Environment $environment)
$token
Definition: xapitoken.php:70
$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
$message
Definition: xapiexit.php:31
A configuration for the setup.
Definition: Config.php:26
generateServerInfoFile(string $filename, string $token)
$ini
Definition: raiseError.php:20