Completed
Push — master ( 080572...37869d )
by Morris
150:57 queued 132:00
created
settings/Controller/CheckSetupController.php 1 patch
Indentation   +548 added lines, -548 removed lines patch added patch discarded remove patch
@@ -61,289 +61,289 @@  discard block
 block discarded – undo
61 61
  * @package OC\Settings\Controller
62 62
  */
63 63
 class CheckSetupController extends Controller {
64
-	/** @var IConfig */
65
-	private $config;
66
-	/** @var IClientService */
67
-	private $clientService;
68
-	/** @var \OC_Util */
69
-	private $util;
70
-	/** @var IURLGenerator */
71
-	private $urlGenerator;
72
-	/** @var IL10N */
73
-	private $l10n;
74
-	/** @var Checker */
75
-	private $checker;
76
-	/** @var ILogger */
77
-	private $logger;
78
-	/** @var EventDispatcherInterface */
79
-	private $dispatcher;
80
-	/** @var IDBConnection|Connection */
81
-	private $db;
82
-	/** @var ILockingProvider */
83
-	private $lockingProvider;
84
-	/** @var IDateTimeFormatter */
85
-	private $dateTimeFormatter;
86
-
87
-	public function __construct($AppName,
88
-								IRequest $request,
89
-								IConfig $config,
90
-								IClientService $clientService,
91
-								IURLGenerator $urlGenerator,
92
-								\OC_Util $util,
93
-								IL10N $l10n,
94
-								Checker $checker,
95
-								ILogger $logger,
96
-								EventDispatcherInterface $dispatcher,
97
-								IDBConnection $db,
98
-								ILockingProvider $lockingProvider,
99
-								IDateTimeFormatter $dateTimeFormatter) {
100
-		parent::__construct($AppName, $request);
101
-		$this->config = $config;
102
-		$this->clientService = $clientService;
103
-		$this->util = $util;
104
-		$this->urlGenerator = $urlGenerator;
105
-		$this->l10n = $l10n;
106
-		$this->checker = $checker;
107
-		$this->logger = $logger;
108
-		$this->dispatcher = $dispatcher;
109
-		$this->db = $db;
110
-		$this->lockingProvider = $lockingProvider;
111
-		$this->dateTimeFormatter = $dateTimeFormatter;
112
-	}
113
-
114
-	/**
115
-	 * Checks if the server can connect to the internet using HTTPS and HTTP
116
-	 * @return bool
117
-	 */
118
-	private function isInternetConnectionWorking() {
119
-		if ($this->config->getSystemValue('has_internet_connection', true) === false) {
120
-			return false;
121
-		}
122
-
123
-		$siteArray = ['www.nextcloud.com',
124
-						'www.startpage.com',
125
-						'www.eff.org',
126
-						'www.edri.org',
127
-			];
128
-
129
-		foreach($siteArray as $site) {
130
-			if ($this->isSiteReachable($site)) {
131
-				return true;
132
-			}
133
-		}
134
-		return false;
135
-	}
136
-
137
-	/**
138
-	* Checks if the Nextcloud server can connect to a specific URL using both HTTPS and HTTP
139
-	* @return bool
140
-	*/
141
-	private function isSiteReachable($sitename) {
142
-		$httpSiteName = 'http://' . $sitename . '/';
143
-		$httpsSiteName = 'https://' . $sitename . '/';
144
-
145
-		try {
146
-			$client = $this->clientService->newClient();
147
-			$client->get($httpSiteName);
148
-			$client->get($httpsSiteName);
149
-		} catch (\Exception $e) {
150
-			$this->logger->logException($e, ['app' => 'internet_connection_check']);
151
-			return false;
152
-		}
153
-		return true;
154
-	}
155
-
156
-	/**
157
-	 * Checks whether a local memcache is installed or not
158
-	 * @return bool
159
-	 */
160
-	private function isMemcacheConfigured() {
161
-		return $this->config->getSystemValue('memcache.local', null) !== null;
162
-	}
163
-
164
-	/**
165
-	 * Whether /dev/urandom is available to the PHP controller
166
-	 *
167
-	 * @return bool
168
-	 */
169
-	private function isUrandomAvailable() {
170
-		if(@file_exists('/dev/urandom')) {
171
-			$file = fopen('/dev/urandom', 'rb');
172
-			if($file) {
173
-				fclose($file);
174
-				return true;
175
-			}
176
-		}
177
-
178
-		return false;
179
-	}
180
-
181
-	/**
182
-	 * Public for the sake of unit-testing
183
-	 *
184
-	 * @return array
185
-	 */
186
-	protected function getCurlVersion() {
187
-		return curl_version();
188
-	}
189
-
190
-	/**
191
-	 * Check if the used  SSL lib is outdated. Older OpenSSL and NSS versions do
192
-	 * have multiple bugs which likely lead to problems in combination with
193
-	 * functionality required by ownCloud such as SNI.
194
-	 *
195
-	 * @link https://github.com/owncloud/core/issues/17446#issuecomment-122877546
196
-	 * @link https://bugzilla.redhat.com/show_bug.cgi?id=1241172
197
-	 * @return string
198
-	 */
199
-	private function isUsedTlsLibOutdated() {
200
-		// Don't run check when:
201
-		// 1. Server has `has_internet_connection` set to false
202
-		// 2. AppStore AND S2S is disabled
203
-		if(!$this->config->getSystemValue('has_internet_connection', true)) {
204
-			return '';
205
-		}
206
-		if(!$this->config->getSystemValue('appstoreenabled', true)
207
-			&& $this->config->getAppValue('files_sharing', 'outgoing_server2server_share_enabled', 'yes') === 'no'
208
-			&& $this->config->getAppValue('files_sharing', 'incoming_server2server_share_enabled', 'yes') === 'no') {
209
-			return '';
210
-		}
211
-
212
-		$versionString = $this->getCurlVersion();
213
-		if(isset($versionString['ssl_version'])) {
214
-			$versionString = $versionString['ssl_version'];
215
-		} else {
216
-			return '';
217
-		}
218
-
219
-		$features = (string)$this->l10n->t('installing and updating apps via the app store or Federated Cloud Sharing');
220
-		if(!$this->config->getSystemValue('appstoreenabled', true)) {
221
-			$features = (string)$this->l10n->t('Federated Cloud Sharing');
222
-		}
223
-
224
-		// Check if at least OpenSSL after 1.01d or 1.0.2b
225
-		if(strpos($versionString, 'OpenSSL/') === 0) {
226
-			$majorVersion = substr($versionString, 8, 5);
227
-			$patchRelease = substr($versionString, 13, 6);
228
-
229
-			if(($majorVersion === '1.0.1' && ord($patchRelease) < ord('d')) ||
230
-				($majorVersion === '1.0.2' && ord($patchRelease) < ord('b'))) {
231
-				return (string) $this->l10n->t('cURL is using an outdated %s version (%s). Please update your operating system or features such as %s will not work reliably.', ['OpenSSL', $versionString, $features]);
232
-			}
233
-		}
234
-
235
-		// Check if NSS and perform heuristic check
236
-		if(strpos($versionString, 'NSS/') === 0) {
237
-			try {
238
-				$firstClient = $this->clientService->newClient();
239
-				$firstClient->get('https://nextcloud.com/');
240
-
241
-				$secondClient = $this->clientService->newClient();
242
-				$secondClient->get('https://nextcloud.com/');
243
-			} catch (ClientException $e) {
244
-				if($e->getResponse()->getStatusCode() === 400) {
245
-					return (string) $this->l10n->t('cURL is using an outdated %s version (%s). Please update your operating system or features such as %s will not work reliably.', ['NSS', $versionString, $features]);
246
-				}
247
-			}
248
-		}
249
-
250
-		return '';
251
-	}
252
-
253
-	/**
254
-	 * Whether the version is outdated
255
-	 *
256
-	 * @return bool
257
-	 */
258
-	protected function isPhpOutdated() {
259
-		if (version_compare(PHP_VERSION, '7.0.0', '<')) {
260
-			return true;
261
-		}
262
-
263
-		return false;
264
-	}
265
-
266
-	/**
267
-	 * Whether the php version is still supported (at time of release)
268
-	 * according to: https://secure.php.net/supported-versions.php
269
-	 *
270
-	 * @return array
271
-	 */
272
-	private function isPhpSupported() {
273
-		return ['eol' => $this->isPhpOutdated(), 'version' => PHP_VERSION];
274
-	}
275
-
276
-	/**
277
-	 * Check if the reverse proxy configuration is working as expected
278
-	 *
279
-	 * @return bool
280
-	 */
281
-	private function forwardedForHeadersWorking() {
282
-		$trustedProxies = $this->config->getSystemValue('trusted_proxies', []);
283
-		$remoteAddress = $this->request->getRemoteAddress();
284
-
285
-		if (is_array($trustedProxies) && in_array($remoteAddress, $trustedProxies)) {
286
-			return false;
287
-		}
288
-
289
-		// either not enabled or working correctly
290
-		return true;
291
-	}
292
-
293
-	/**
294
-	 * Checks if the correct memcache module for PHP is installed. Only
295
-	 * fails if memcached is configured and the working module is not installed.
296
-	 *
297
-	 * @return bool
298
-	 */
299
-	private function isCorrectMemcachedPHPModuleInstalled() {
300
-		if ($this->config->getSystemValue('memcache.distributed', null) !== '\OC\Memcache\Memcached') {
301
-			return true;
302
-		}
303
-
304
-		// there are two different memcached modules for PHP
305
-		// we only support memcached and not memcache
306
-		// https://code.google.com/p/memcached/wiki/PHPClientComparison
307
-		return !(!extension_loaded('memcached') && extension_loaded('memcache'));
308
-	}
309
-
310
-	/**
311
-	 * Checks if set_time_limit is not disabled.
312
-	 *
313
-	 * @return bool
314
-	 */
315
-	private function isSettimelimitAvailable() {
316
-		if (function_exists('set_time_limit')
317
-			&& strpos(@ini_get('disable_functions'), 'set_time_limit') === false) {
318
-			return true;
319
-		}
320
-
321
-		return false;
322
-	}
323
-
324
-	/**
325
-	 * @return RedirectResponse
326
-	 */
327
-	public function rescanFailedIntegrityCheck() {
328
-		$this->checker->runInstanceVerification();
329
-		return new RedirectResponse(
330
-			$this->urlGenerator->linkToRoute('settings.AdminSettings.index')
331
-		);
332
-	}
333
-
334
-	/**
335
-	 * @NoCSRFRequired
336
-	 * @return DataResponse
337
-	 */
338
-	public function getFailedIntegrityCheckFiles() {
339
-		if(!$this->checker->isCodeCheckEnforced()) {
340
-			return new DataDisplayResponse('Integrity checker has been disabled. Integrity cannot be verified.');
341
-		}
342
-
343
-		$completeResults = $this->checker->getResults();
344
-
345
-		if(!empty($completeResults)) {
346
-			$formattedTextResponse = 'Technical information
64
+    /** @var IConfig */
65
+    private $config;
66
+    /** @var IClientService */
67
+    private $clientService;
68
+    /** @var \OC_Util */
69
+    private $util;
70
+    /** @var IURLGenerator */
71
+    private $urlGenerator;
72
+    /** @var IL10N */
73
+    private $l10n;
74
+    /** @var Checker */
75
+    private $checker;
76
+    /** @var ILogger */
77
+    private $logger;
78
+    /** @var EventDispatcherInterface */
79
+    private $dispatcher;
80
+    /** @var IDBConnection|Connection */
81
+    private $db;
82
+    /** @var ILockingProvider */
83
+    private $lockingProvider;
84
+    /** @var IDateTimeFormatter */
85
+    private $dateTimeFormatter;
86
+
87
+    public function __construct($AppName,
88
+                                IRequest $request,
89
+                                IConfig $config,
90
+                                IClientService $clientService,
91
+                                IURLGenerator $urlGenerator,
92
+                                \OC_Util $util,
93
+                                IL10N $l10n,
94
+                                Checker $checker,
95
+                                ILogger $logger,
96
+                                EventDispatcherInterface $dispatcher,
97
+                                IDBConnection $db,
98
+                                ILockingProvider $lockingProvider,
99
+                                IDateTimeFormatter $dateTimeFormatter) {
100
+        parent::__construct($AppName, $request);
101
+        $this->config = $config;
102
+        $this->clientService = $clientService;
103
+        $this->util = $util;
104
+        $this->urlGenerator = $urlGenerator;
105
+        $this->l10n = $l10n;
106
+        $this->checker = $checker;
107
+        $this->logger = $logger;
108
+        $this->dispatcher = $dispatcher;
109
+        $this->db = $db;
110
+        $this->lockingProvider = $lockingProvider;
111
+        $this->dateTimeFormatter = $dateTimeFormatter;
112
+    }
113
+
114
+    /**
115
+     * Checks if the server can connect to the internet using HTTPS and HTTP
116
+     * @return bool
117
+     */
118
+    private function isInternetConnectionWorking() {
119
+        if ($this->config->getSystemValue('has_internet_connection', true) === false) {
120
+            return false;
121
+        }
122
+
123
+        $siteArray = ['www.nextcloud.com',
124
+                        'www.startpage.com',
125
+                        'www.eff.org',
126
+                        'www.edri.org',
127
+            ];
128
+
129
+        foreach($siteArray as $site) {
130
+            if ($this->isSiteReachable($site)) {
131
+                return true;
132
+            }
133
+        }
134
+        return false;
135
+    }
136
+
137
+    /**
138
+     * Checks if the Nextcloud server can connect to a specific URL using both HTTPS and HTTP
139
+     * @return bool
140
+     */
141
+    private function isSiteReachable($sitename) {
142
+        $httpSiteName = 'http://' . $sitename . '/';
143
+        $httpsSiteName = 'https://' . $sitename . '/';
144
+
145
+        try {
146
+            $client = $this->clientService->newClient();
147
+            $client->get($httpSiteName);
148
+            $client->get($httpsSiteName);
149
+        } catch (\Exception $e) {
150
+            $this->logger->logException($e, ['app' => 'internet_connection_check']);
151
+            return false;
152
+        }
153
+        return true;
154
+    }
155
+
156
+    /**
157
+     * Checks whether a local memcache is installed or not
158
+     * @return bool
159
+     */
160
+    private function isMemcacheConfigured() {
161
+        return $this->config->getSystemValue('memcache.local', null) !== null;
162
+    }
163
+
164
+    /**
165
+     * Whether /dev/urandom is available to the PHP controller
166
+     *
167
+     * @return bool
168
+     */
169
+    private function isUrandomAvailable() {
170
+        if(@file_exists('/dev/urandom')) {
171
+            $file = fopen('/dev/urandom', 'rb');
172
+            if($file) {
173
+                fclose($file);
174
+                return true;
175
+            }
176
+        }
177
+
178
+        return false;
179
+    }
180
+
181
+    /**
182
+     * Public for the sake of unit-testing
183
+     *
184
+     * @return array
185
+     */
186
+    protected function getCurlVersion() {
187
+        return curl_version();
188
+    }
189
+
190
+    /**
191
+     * Check if the used  SSL lib is outdated. Older OpenSSL and NSS versions do
192
+     * have multiple bugs which likely lead to problems in combination with
193
+     * functionality required by ownCloud such as SNI.
194
+     *
195
+     * @link https://github.com/owncloud/core/issues/17446#issuecomment-122877546
196
+     * @link https://bugzilla.redhat.com/show_bug.cgi?id=1241172
197
+     * @return string
198
+     */
199
+    private function isUsedTlsLibOutdated() {
200
+        // Don't run check when:
201
+        // 1. Server has `has_internet_connection` set to false
202
+        // 2. AppStore AND S2S is disabled
203
+        if(!$this->config->getSystemValue('has_internet_connection', true)) {
204
+            return '';
205
+        }
206
+        if(!$this->config->getSystemValue('appstoreenabled', true)
207
+            && $this->config->getAppValue('files_sharing', 'outgoing_server2server_share_enabled', 'yes') === 'no'
208
+            && $this->config->getAppValue('files_sharing', 'incoming_server2server_share_enabled', 'yes') === 'no') {
209
+            return '';
210
+        }
211
+
212
+        $versionString = $this->getCurlVersion();
213
+        if(isset($versionString['ssl_version'])) {
214
+            $versionString = $versionString['ssl_version'];
215
+        } else {
216
+            return '';
217
+        }
218
+
219
+        $features = (string)$this->l10n->t('installing and updating apps via the app store or Federated Cloud Sharing');
220
+        if(!$this->config->getSystemValue('appstoreenabled', true)) {
221
+            $features = (string)$this->l10n->t('Federated Cloud Sharing');
222
+        }
223
+
224
+        // Check if at least OpenSSL after 1.01d or 1.0.2b
225
+        if(strpos($versionString, 'OpenSSL/') === 0) {
226
+            $majorVersion = substr($versionString, 8, 5);
227
+            $patchRelease = substr($versionString, 13, 6);
228
+
229
+            if(($majorVersion === '1.0.1' && ord($patchRelease) < ord('d')) ||
230
+                ($majorVersion === '1.0.2' && ord($patchRelease) < ord('b'))) {
231
+                return (string) $this->l10n->t('cURL is using an outdated %s version (%s). Please update your operating system or features such as %s will not work reliably.', ['OpenSSL', $versionString, $features]);
232
+            }
233
+        }
234
+
235
+        // Check if NSS and perform heuristic check
236
+        if(strpos($versionString, 'NSS/') === 0) {
237
+            try {
238
+                $firstClient = $this->clientService->newClient();
239
+                $firstClient->get('https://nextcloud.com/');
240
+
241
+                $secondClient = $this->clientService->newClient();
242
+                $secondClient->get('https://nextcloud.com/');
243
+            } catch (ClientException $e) {
244
+                if($e->getResponse()->getStatusCode() === 400) {
245
+                    return (string) $this->l10n->t('cURL is using an outdated %s version (%s). Please update your operating system or features such as %s will not work reliably.', ['NSS', $versionString, $features]);
246
+                }
247
+            }
248
+        }
249
+
250
+        return '';
251
+    }
252
+
253
+    /**
254
+     * Whether the version is outdated
255
+     *
256
+     * @return bool
257
+     */
258
+    protected function isPhpOutdated() {
259
+        if (version_compare(PHP_VERSION, '7.0.0', '<')) {
260
+            return true;
261
+        }
262
+
263
+        return false;
264
+    }
265
+
266
+    /**
267
+     * Whether the php version is still supported (at time of release)
268
+     * according to: https://secure.php.net/supported-versions.php
269
+     *
270
+     * @return array
271
+     */
272
+    private function isPhpSupported() {
273
+        return ['eol' => $this->isPhpOutdated(), 'version' => PHP_VERSION];
274
+    }
275
+
276
+    /**
277
+     * Check if the reverse proxy configuration is working as expected
278
+     *
279
+     * @return bool
280
+     */
281
+    private function forwardedForHeadersWorking() {
282
+        $trustedProxies = $this->config->getSystemValue('trusted_proxies', []);
283
+        $remoteAddress = $this->request->getRemoteAddress();
284
+
285
+        if (is_array($trustedProxies) && in_array($remoteAddress, $trustedProxies)) {
286
+            return false;
287
+        }
288
+
289
+        // either not enabled or working correctly
290
+        return true;
291
+    }
292
+
293
+    /**
294
+     * Checks if the correct memcache module for PHP is installed. Only
295
+     * fails if memcached is configured and the working module is not installed.
296
+     *
297
+     * @return bool
298
+     */
299
+    private function isCorrectMemcachedPHPModuleInstalled() {
300
+        if ($this->config->getSystemValue('memcache.distributed', null) !== '\OC\Memcache\Memcached') {
301
+            return true;
302
+        }
303
+
304
+        // there are two different memcached modules for PHP
305
+        // we only support memcached and not memcache
306
+        // https://code.google.com/p/memcached/wiki/PHPClientComparison
307
+        return !(!extension_loaded('memcached') && extension_loaded('memcache'));
308
+    }
309
+
310
+    /**
311
+     * Checks if set_time_limit is not disabled.
312
+     *
313
+     * @return bool
314
+     */
315
+    private function isSettimelimitAvailable() {
316
+        if (function_exists('set_time_limit')
317
+            && strpos(@ini_get('disable_functions'), 'set_time_limit') === false) {
318
+            return true;
319
+        }
320
+
321
+        return false;
322
+    }
323
+
324
+    /**
325
+     * @return RedirectResponse
326
+     */
327
+    public function rescanFailedIntegrityCheck() {
328
+        $this->checker->runInstanceVerification();
329
+        return new RedirectResponse(
330
+            $this->urlGenerator->linkToRoute('settings.AdminSettings.index')
331
+        );
332
+    }
333
+
334
+    /**
335
+     * @NoCSRFRequired
336
+     * @return DataResponse
337
+     */
338
+    public function getFailedIntegrityCheckFiles() {
339
+        if(!$this->checker->isCodeCheckEnforced()) {
340
+            return new DataDisplayResponse('Integrity checker has been disabled. Integrity cannot be verified.');
341
+        }
342
+
343
+        $completeResults = $this->checker->getResults();
344
+
345
+        if(!empty($completeResults)) {
346
+            $formattedTextResponse = 'Technical information
347 347
 =====================
348 348
 The following list covers which files have failed the integrity check. Please read
349 349
 the previous linked documentation to learn more about the errors and how to fix
@@ -352,272 +352,272 @@  discard block
 block discarded – undo
352 352
 Results
353 353
 =======
354 354
 ';
355
-			foreach($completeResults as $context => $contextResult) {
356
-				$formattedTextResponse .= "- $context\n";
357
-
358
-				foreach($contextResult as $category => $result) {
359
-					$formattedTextResponse .= "\t- $category\n";
360
-					if($category !== 'EXCEPTION') {
361
-						foreach ($result as $key => $results) {
362
-							$formattedTextResponse .= "\t\t- $key\n";
363
-						}
364
-					} else {
365
-						foreach ($result as $key => $results) {
366
-							$formattedTextResponse .= "\t\t- $results\n";
367
-						}
368
-					}
369
-
370
-				}
371
-			}
372
-
373
-			$formattedTextResponse .= '
355
+            foreach($completeResults as $context => $contextResult) {
356
+                $formattedTextResponse .= "- $context\n";
357
+
358
+                foreach($contextResult as $category => $result) {
359
+                    $formattedTextResponse .= "\t- $category\n";
360
+                    if($category !== 'EXCEPTION') {
361
+                        foreach ($result as $key => $results) {
362
+                            $formattedTextResponse .= "\t\t- $key\n";
363
+                        }
364
+                    } else {
365
+                        foreach ($result as $key => $results) {
366
+                            $formattedTextResponse .= "\t\t- $results\n";
367
+                        }
368
+                    }
369
+
370
+                }
371
+            }
372
+
373
+            $formattedTextResponse .= '
374 374
 Raw output
375 375
 ==========
376 376
 ';
377
-			$formattedTextResponse .= print_r($completeResults, true);
378
-		} else {
379
-			$formattedTextResponse = 'No errors have been found.';
380
-		}
381
-
382
-
383
-		$response = new DataDisplayResponse(
384
-			$formattedTextResponse,
385
-			Http::STATUS_OK,
386
-			[
387
-				'Content-Type' => 'text/plain',
388
-			]
389
-		);
390
-
391
-		return $response;
392
-	}
393
-
394
-	/**
395
-	 * Checks whether a PHP opcache is properly set up
396
-	 * @return bool
397
-	 */
398
-	protected function isOpcacheProperlySetup() {
399
-		$iniWrapper = new IniGetWrapper();
400
-
401
-		if(!$iniWrapper->getBool('opcache.enable')) {
402
-			return false;
403
-		}
404
-
405
-		if(!$iniWrapper->getBool('opcache.save_comments')) {
406
-			return false;
407
-		}
408
-
409
-		if(!$iniWrapper->getBool('opcache.enable_cli')) {
410
-			return false;
411
-		}
412
-
413
-		if($iniWrapper->getNumeric('opcache.max_accelerated_files') < 10000) {
414
-			return false;
415
-		}
416
-
417
-		if($iniWrapper->getNumeric('opcache.memory_consumption') < 128) {
418
-			return false;
419
-		}
420
-
421
-		if($iniWrapper->getNumeric('opcache.interned_strings_buffer') < 8) {
422
-			return false;
423
-		}
424
-
425
-		return true;
426
-	}
427
-
428
-	/**
429
-	 * Check if the required FreeType functions are present
430
-	 * @return bool
431
-	 */
432
-	protected function hasFreeTypeSupport() {
433
-		return function_exists('imagettfbbox') && function_exists('imagettftext');
434
-	}
435
-
436
-	protected function hasMissingIndexes(): array {
437
-		$indexInfo = new MissingIndexInformation();
438
-		// Dispatch event so apps can also hint for pending index updates if needed
439
-		$event = new GenericEvent($indexInfo);
440
-		$this->dispatcher->dispatch(IDBConnection::CHECK_MISSING_INDEXES_EVENT, $event);
441
-
442
-		return $indexInfo->getListOfMissingIndexes();
443
-	}
444
-
445
-	/**
446
-	 * warn if outdated version of a memcache module is used
447
-	 */
448
-	protected function getOutdatedCaches(): array {
449
-		$caches = [
450
-			'apcu'	=> ['name' => 'APCu', 'version' => '4.0.6'],
451
-			'redis'	=> ['name' => 'Redis', 'version' => '2.2.5'],
452
-		];
453
-		$outdatedCaches = [];
454
-		foreach ($caches as $php_module => $data) {
455
-			$isOutdated = extension_loaded($php_module) && version_compare(phpversion($php_module), $data['version'], '<');
456
-			if ($isOutdated) {
457
-				$outdatedCaches[] = $data;
458
-			}
459
-		}
460
-
461
-		return $outdatedCaches;
462
-	}
463
-
464
-	protected function isSqliteUsed() {
465
-		return strpos($this->config->getSystemValue('dbtype'), 'sqlite') !== false;
466
-	}
467
-
468
-	protected function isReadOnlyConfig(): bool {
469
-		return \OC_Helper::isReadOnlyConfigEnabled();
470
-	}
471
-
472
-	protected function hasValidTransactionIsolationLevel(): bool {
473
-		try {
474
-			if ($this->db->getDatabasePlatform() instanceof SqlitePlatform) {
475
-				return true;
476
-			}
477
-
478
-			return $this->db->getTransactionIsolation() === Connection::TRANSACTION_READ_COMMITTED;
479
-		} catch (DBALException $e) {
480
-			// ignore
481
-		}
482
-
483
-		return true;
484
-	}
485
-
486
-	protected function hasFileinfoInstalled(): bool {
487
-		return \OC_Util::fileInfoLoaded();
488
-	}
489
-
490
-	protected function hasWorkingFileLocking(): bool {
491
-		return !($this->lockingProvider instanceof NoopLockingProvider);
492
-	}
493
-
494
-	protected function getSuggestedOverwriteCliURL(): string {
495
-		$suggestedOverwriteCliUrl = '';
496
-		if ($this->config->getSystemValue('overwrite.cli.url', '') === '') {
497
-			$suggestedOverwriteCliUrl = $this->request->getServerProtocol() . '://' . $this->request->getInsecureServerHost() . \OC::$WEBROOT;
498
-			if (!$this->config->getSystemValue('config_is_read_only', false)) {
499
-				// Set the overwrite URL when it was not set yet.
500
-				$this->config->setSystemValue('overwrite.cli.url', $suggestedOverwriteCliUrl);
501
-				$suggestedOverwriteCliUrl = '';
502
-			}
503
-		}
504
-		return $suggestedOverwriteCliUrl;
505
-	}
506
-
507
-	protected function getLastCronInfo(): array {
508
-		$lastCronRun = $this->config->getAppValue('core', 'lastcron', 0);
509
-		return [
510
-			'diffInSeconds' => time() - $lastCronRun,
511
-			'relativeTime' => $this->dateTimeFormatter->formatTimeSpan($lastCronRun),
512
-			'backgroundJobsUrl' => $this->urlGenerator->linkToRoute('settings.AdminSettings.index', ['section' => 'server']) . '#backgroundjobs',
513
-		];
514
-	}
515
-
516
-	protected function getCronErrors() {
517
-		$errors = json_decode($this->config->getAppValue('core', 'cronErrors', ''), true);
518
-
519
-		if (is_array($errors)) {
520
-			return $errors;
521
-		}
522
-
523
-		return [];
524
-	}
525
-
526
-	protected function isPhpMailerUsed(): bool {
527
-		return $this->config->getSystemValue('mail_smtpmode', 'php') === 'php';
528
-	}
529
-
530
-	protected function hasOpcacheLoaded(): bool {
531
-		return function_exists('opcache_get_status');
532
-	}
533
-
534
-	/**
535
-	 * Iterates through the configured app roots and
536
-	 * tests if the subdirectories are owned by the same user than the current user.
537
-	 *
538
-	 * @return array
539
-	 */
540
-	protected function getAppDirsWithDifferentOwner(): array {
541
-		$currentUser = posix_getpwuid(posix_getuid());
542
-		$appDirsWithDifferentOwner = [];
543
-
544
-		foreach (OC::$APPSROOTS as $appRoot) {
545
-			if ($appRoot['writable'] === true) {
546
-				$appDirsWithDifferentOwner = array_merge(
547
-					$appDirsWithDifferentOwner,
548
-					$this->getAppDirsWithDifferentOwnerForAppRoot($currentUser, $appRoot)
549
-				);
550
-			}
551
-		}
552
-
553
-		sort($appDirsWithDifferentOwner);
554
-		return $appDirsWithDifferentOwner;
555
-	}
556
-
557
-	/**
558
-	 * Tests if the directories for one apps directory are writable by the current user.
559
-	 *
560
-	 * @param array $currentUser The current user
561
-	 * @param array $appRoot The app root config
562
-	 * @return string[] The none writable directory paths inside the app root
563
-	 */
564
-	private function getAppDirsWithDifferentOwnerForAppRoot(array $currentUser, array $appRoot): array {
565
-		$appDirsWithDifferentOwner = [];
566
-		$appsPath = $appRoot['path'];
567
-		$appsDir = new DirectoryIterator($appRoot['path']);
568
-
569
-		foreach ($appsDir as $fileInfo) {
570
-			if ($fileInfo->isDir() && !$fileInfo->isDot()) {
571
-				$absAppPath = $appsPath . DIRECTORY_SEPARATOR . $fileInfo->getFilename();
572
-				$appDirUser = posix_getpwuid(fileowner($absAppPath));
573
-				if ($appDirUser !== $currentUser) {
574
-					$appDirsWithDifferentOwner[] = $absAppPath . DIRECTORY_SEPARATOR . $fileInfo->getFilename();
575
-				}
576
-			}
577
-		}
578
-
579
-		return $appDirsWithDifferentOwner;
580
-	}
581
-
582
-	/**
583
-	 * @return DataResponse
584
-	 */
585
-	public function check() {
586
-		return new DataResponse(
587
-			[
588
-				'isGetenvServerWorking' => !empty(getenv('PATH')),
589
-				'isReadOnlyConfig' => $this->isReadOnlyConfig(),
590
-				'hasValidTransactionIsolationLevel' => $this->hasValidTransactionIsolationLevel(),
591
-				'outdatedCaches' => $this->getOutdatedCaches(),
592
-				'hasFileinfoInstalled' => $this->hasFileinfoInstalled(),
593
-				'hasWorkingFileLocking' => $this->hasWorkingFileLocking(),
594
-				'suggestedOverwriteCliURL' => $this->getSuggestedOverwriteCliURL(),
595
-				'cronInfo' => $this->getLastCronInfo(),
596
-				'cronErrors' => $this->getCronErrors(),
597
-				'serverHasInternetConnection' => $this->isInternetConnectionWorking(),
598
-				'isMemcacheConfigured' => $this->isMemcacheConfigured(),
599
-				'memcacheDocs' => $this->urlGenerator->linkToDocs('admin-performance'),
600
-				'isUrandomAvailable' => $this->isUrandomAvailable(),
601
-				'securityDocs' => $this->urlGenerator->linkToDocs('admin-security'),
602
-				'isUsedTlsLibOutdated' => $this->isUsedTlsLibOutdated(),
603
-				'phpSupported' => $this->isPhpSupported(),
604
-				'forwardedForHeadersWorking' => $this->forwardedForHeadersWorking(),
605
-				'reverseProxyDocs' => $this->urlGenerator->linkToDocs('admin-reverse-proxy'),
606
-				'isCorrectMemcachedPHPModuleInstalled' => $this->isCorrectMemcachedPHPModuleInstalled(),
607
-				'hasPassedCodeIntegrityCheck' => $this->checker->hasPassedCheck(),
608
-				'codeIntegrityCheckerDocumentation' => $this->urlGenerator->linkToDocs('admin-code-integrity'),
609
-				'isOpcacheProperlySetup' => $this->isOpcacheProperlySetup(),
610
-				'hasOpcacheLoaded' => $this->hasOpcacheLoaded(),
611
-				'phpOpcacheDocumentation' => $this->urlGenerator->linkToDocs('admin-php-opcache'),
612
-				'isSettimelimitAvailable' => $this->isSettimelimitAvailable(),
613
-				'hasFreeTypeSupport' => $this->hasFreeTypeSupport(),
614
-				'missingIndexes' => $this->hasMissingIndexes(),
615
-				'isSqliteUsed' => $this->isSqliteUsed(),
616
-				'databaseConversionDocumentation' => $this->urlGenerator->linkToDocs('admin-db-conversion'),
617
-				'isPhpMailerUsed' => $this->isPhpMailerUsed(),
618
-				'mailSettingsDocumentation' => $this->urlGenerator->getAbsoluteURL('index.php/settings/admin'),
619
-				'appDirsWithDifferentOwner' => $this->getAppDirsWithDifferentOwner(),
620
-			]
621
-		);
622
-	}
377
+            $formattedTextResponse .= print_r($completeResults, true);
378
+        } else {
379
+            $formattedTextResponse = 'No errors have been found.';
380
+        }
381
+
382
+
383
+        $response = new DataDisplayResponse(
384
+            $formattedTextResponse,
385
+            Http::STATUS_OK,
386
+            [
387
+                'Content-Type' => 'text/plain',
388
+            ]
389
+        );
390
+
391
+        return $response;
392
+    }
393
+
394
+    /**
395
+     * Checks whether a PHP opcache is properly set up
396
+     * @return bool
397
+     */
398
+    protected function isOpcacheProperlySetup() {
399
+        $iniWrapper = new IniGetWrapper();
400
+
401
+        if(!$iniWrapper->getBool('opcache.enable')) {
402
+            return false;
403
+        }
404
+
405
+        if(!$iniWrapper->getBool('opcache.save_comments')) {
406
+            return false;
407
+        }
408
+
409
+        if(!$iniWrapper->getBool('opcache.enable_cli')) {
410
+            return false;
411
+        }
412
+
413
+        if($iniWrapper->getNumeric('opcache.max_accelerated_files') < 10000) {
414
+            return false;
415
+        }
416
+
417
+        if($iniWrapper->getNumeric('opcache.memory_consumption') < 128) {
418
+            return false;
419
+        }
420
+
421
+        if($iniWrapper->getNumeric('opcache.interned_strings_buffer') < 8) {
422
+            return false;
423
+        }
424
+
425
+        return true;
426
+    }
427
+
428
+    /**
429
+     * Check if the required FreeType functions are present
430
+     * @return bool
431
+     */
432
+    protected function hasFreeTypeSupport() {
433
+        return function_exists('imagettfbbox') && function_exists('imagettftext');
434
+    }
435
+
436
+    protected function hasMissingIndexes(): array {
437
+        $indexInfo = new MissingIndexInformation();
438
+        // Dispatch event so apps can also hint for pending index updates if needed
439
+        $event = new GenericEvent($indexInfo);
440
+        $this->dispatcher->dispatch(IDBConnection::CHECK_MISSING_INDEXES_EVENT, $event);
441
+
442
+        return $indexInfo->getListOfMissingIndexes();
443
+    }
444
+
445
+    /**
446
+     * warn if outdated version of a memcache module is used
447
+     */
448
+    protected function getOutdatedCaches(): array {
449
+        $caches = [
450
+            'apcu'	=> ['name' => 'APCu', 'version' => '4.0.6'],
451
+            'redis'	=> ['name' => 'Redis', 'version' => '2.2.5'],
452
+        ];
453
+        $outdatedCaches = [];
454
+        foreach ($caches as $php_module => $data) {
455
+            $isOutdated = extension_loaded($php_module) && version_compare(phpversion($php_module), $data['version'], '<');
456
+            if ($isOutdated) {
457
+                $outdatedCaches[] = $data;
458
+            }
459
+        }
460
+
461
+        return $outdatedCaches;
462
+    }
463
+
464
+    protected function isSqliteUsed() {
465
+        return strpos($this->config->getSystemValue('dbtype'), 'sqlite') !== false;
466
+    }
467
+
468
+    protected function isReadOnlyConfig(): bool {
469
+        return \OC_Helper::isReadOnlyConfigEnabled();
470
+    }
471
+
472
+    protected function hasValidTransactionIsolationLevel(): bool {
473
+        try {
474
+            if ($this->db->getDatabasePlatform() instanceof SqlitePlatform) {
475
+                return true;
476
+            }
477
+
478
+            return $this->db->getTransactionIsolation() === Connection::TRANSACTION_READ_COMMITTED;
479
+        } catch (DBALException $e) {
480
+            // ignore
481
+        }
482
+
483
+        return true;
484
+    }
485
+
486
+    protected function hasFileinfoInstalled(): bool {
487
+        return \OC_Util::fileInfoLoaded();
488
+    }
489
+
490
+    protected function hasWorkingFileLocking(): bool {
491
+        return !($this->lockingProvider instanceof NoopLockingProvider);
492
+    }
493
+
494
+    protected function getSuggestedOverwriteCliURL(): string {
495
+        $suggestedOverwriteCliUrl = '';
496
+        if ($this->config->getSystemValue('overwrite.cli.url', '') === '') {
497
+            $suggestedOverwriteCliUrl = $this->request->getServerProtocol() . '://' . $this->request->getInsecureServerHost() . \OC::$WEBROOT;
498
+            if (!$this->config->getSystemValue('config_is_read_only', false)) {
499
+                // Set the overwrite URL when it was not set yet.
500
+                $this->config->setSystemValue('overwrite.cli.url', $suggestedOverwriteCliUrl);
501
+                $suggestedOverwriteCliUrl = '';
502
+            }
503
+        }
504
+        return $suggestedOverwriteCliUrl;
505
+    }
506
+
507
+    protected function getLastCronInfo(): array {
508
+        $lastCronRun = $this->config->getAppValue('core', 'lastcron', 0);
509
+        return [
510
+            'diffInSeconds' => time() - $lastCronRun,
511
+            'relativeTime' => $this->dateTimeFormatter->formatTimeSpan($lastCronRun),
512
+            'backgroundJobsUrl' => $this->urlGenerator->linkToRoute('settings.AdminSettings.index', ['section' => 'server']) . '#backgroundjobs',
513
+        ];
514
+    }
515
+
516
+    protected function getCronErrors() {
517
+        $errors = json_decode($this->config->getAppValue('core', 'cronErrors', ''), true);
518
+
519
+        if (is_array($errors)) {
520
+            return $errors;
521
+        }
522
+
523
+        return [];
524
+    }
525
+
526
+    protected function isPhpMailerUsed(): bool {
527
+        return $this->config->getSystemValue('mail_smtpmode', 'php') === 'php';
528
+    }
529
+
530
+    protected function hasOpcacheLoaded(): bool {
531
+        return function_exists('opcache_get_status');
532
+    }
533
+
534
+    /**
535
+     * Iterates through the configured app roots and
536
+     * tests if the subdirectories are owned by the same user than the current user.
537
+     *
538
+     * @return array
539
+     */
540
+    protected function getAppDirsWithDifferentOwner(): array {
541
+        $currentUser = posix_getpwuid(posix_getuid());
542
+        $appDirsWithDifferentOwner = [];
543
+
544
+        foreach (OC::$APPSROOTS as $appRoot) {
545
+            if ($appRoot['writable'] === true) {
546
+                $appDirsWithDifferentOwner = array_merge(
547
+                    $appDirsWithDifferentOwner,
548
+                    $this->getAppDirsWithDifferentOwnerForAppRoot($currentUser, $appRoot)
549
+                );
550
+            }
551
+        }
552
+
553
+        sort($appDirsWithDifferentOwner);
554
+        return $appDirsWithDifferentOwner;
555
+    }
556
+
557
+    /**
558
+     * Tests if the directories for one apps directory are writable by the current user.
559
+     *
560
+     * @param array $currentUser The current user
561
+     * @param array $appRoot The app root config
562
+     * @return string[] The none writable directory paths inside the app root
563
+     */
564
+    private function getAppDirsWithDifferentOwnerForAppRoot(array $currentUser, array $appRoot): array {
565
+        $appDirsWithDifferentOwner = [];
566
+        $appsPath = $appRoot['path'];
567
+        $appsDir = new DirectoryIterator($appRoot['path']);
568
+
569
+        foreach ($appsDir as $fileInfo) {
570
+            if ($fileInfo->isDir() && !$fileInfo->isDot()) {
571
+                $absAppPath = $appsPath . DIRECTORY_SEPARATOR . $fileInfo->getFilename();
572
+                $appDirUser = posix_getpwuid(fileowner($absAppPath));
573
+                if ($appDirUser !== $currentUser) {
574
+                    $appDirsWithDifferentOwner[] = $absAppPath . DIRECTORY_SEPARATOR . $fileInfo->getFilename();
575
+                }
576
+            }
577
+        }
578
+
579
+        return $appDirsWithDifferentOwner;
580
+    }
581
+
582
+    /**
583
+     * @return DataResponse
584
+     */
585
+    public function check() {
586
+        return new DataResponse(
587
+            [
588
+                'isGetenvServerWorking' => !empty(getenv('PATH')),
589
+                'isReadOnlyConfig' => $this->isReadOnlyConfig(),
590
+                'hasValidTransactionIsolationLevel' => $this->hasValidTransactionIsolationLevel(),
591
+                'outdatedCaches' => $this->getOutdatedCaches(),
592
+                'hasFileinfoInstalled' => $this->hasFileinfoInstalled(),
593
+                'hasWorkingFileLocking' => $this->hasWorkingFileLocking(),
594
+                'suggestedOverwriteCliURL' => $this->getSuggestedOverwriteCliURL(),
595
+                'cronInfo' => $this->getLastCronInfo(),
596
+                'cronErrors' => $this->getCronErrors(),
597
+                'serverHasInternetConnection' => $this->isInternetConnectionWorking(),
598
+                'isMemcacheConfigured' => $this->isMemcacheConfigured(),
599
+                'memcacheDocs' => $this->urlGenerator->linkToDocs('admin-performance'),
600
+                'isUrandomAvailable' => $this->isUrandomAvailable(),
601
+                'securityDocs' => $this->urlGenerator->linkToDocs('admin-security'),
602
+                'isUsedTlsLibOutdated' => $this->isUsedTlsLibOutdated(),
603
+                'phpSupported' => $this->isPhpSupported(),
604
+                'forwardedForHeadersWorking' => $this->forwardedForHeadersWorking(),
605
+                'reverseProxyDocs' => $this->urlGenerator->linkToDocs('admin-reverse-proxy'),
606
+                'isCorrectMemcachedPHPModuleInstalled' => $this->isCorrectMemcachedPHPModuleInstalled(),
607
+                'hasPassedCodeIntegrityCheck' => $this->checker->hasPassedCheck(),
608
+                'codeIntegrityCheckerDocumentation' => $this->urlGenerator->linkToDocs('admin-code-integrity'),
609
+                'isOpcacheProperlySetup' => $this->isOpcacheProperlySetup(),
610
+                'hasOpcacheLoaded' => $this->hasOpcacheLoaded(),
611
+                'phpOpcacheDocumentation' => $this->urlGenerator->linkToDocs('admin-php-opcache'),
612
+                'isSettimelimitAvailable' => $this->isSettimelimitAvailable(),
613
+                'hasFreeTypeSupport' => $this->hasFreeTypeSupport(),
614
+                'missingIndexes' => $this->hasMissingIndexes(),
615
+                'isSqliteUsed' => $this->isSqliteUsed(),
616
+                'databaseConversionDocumentation' => $this->urlGenerator->linkToDocs('admin-db-conversion'),
617
+                'isPhpMailerUsed' => $this->isPhpMailerUsed(),
618
+                'mailSettingsDocumentation' => $this->urlGenerator->getAbsoluteURL('index.php/settings/admin'),
619
+                'appDirsWithDifferentOwner' => $this->getAppDirsWithDifferentOwner(),
620
+            ]
621
+        );
622
+    }
623 623
 }
Please login to merge, or discard this patch.