Completed
Push — master ( 97b6c1...b26568 )
by Joas
12:33
created

OC::checkInstalled()   B

Complexity

Conditions 6
Paths 4

Size

Total Lines 15
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 10
nc 4
nop 0
dl 0
loc 15
rs 8.8571
c 0
b 0
f 0
1
<?php
2
/**
3
 * @copyright Copyright (c) 2016, ownCloud, Inc.
4
 *
5
 * @author Adam Williamson <[email protected]>
6
 * @author Andreas Fischer <[email protected]>
7
 * @author Arthur Schiwon <[email protected]>
8
 * @author Bart Visscher <[email protected]>
9
 * @author Bernhard Posselt <[email protected]>
10
 * @author Björn Schießle <[email protected]>
11
 * @author Christoph Wurst <[email protected]>
12
 * @author davidgumberg <[email protected]>
13
 * @author Florin Peter <[email protected]>
14
 * @author Georg Ehrke <[email protected]>
15
 * @author Hugo Gonzalez Labrador <[email protected]>
16
 * @author Individual IT Services <[email protected]>
17
 * @author Jakob Sack <[email protected]>
18
 * @author Joachim Bauch <[email protected]>
19
 * @author Joachim Sokolowski <[email protected]>
20
 * @author Joas Schilling <[email protected]>
21
 * @author Jörn Friedrich Dreyer <[email protected]>
22
 * @author Lukas Reschke <[email protected]>
23
 * @author Michael Gapczynski <[email protected]>
24
 * @author Morris Jobke <[email protected]>
25
 * @author Owen Winkler <[email protected]>
26
 * @author Phil Davis <[email protected]>
27
 * @author Ramiro Aparicio <[email protected]>
28
 * @author Robin Appelman <[email protected]>
29
 * @author Robin McCorkell <[email protected]>
30
 * @author Roeland Jago Douma <[email protected]>
31
 * @author Stefan Weil <[email protected]>
32
 * @author Thomas Müller <[email protected]>
33
 * @author Thomas Pulzer <[email protected]>
34
 * @author Thomas Tanghus <[email protected]>
35
 * @author Vincent Petry <[email protected]>
36
 * @author Volkan Gezer <[email protected]>
37
 *
38
 * @license AGPL-3.0
39
 *
40
 * This code is free software: you can redistribute it and/or modify
41
 * it under the terms of the GNU Affero General Public License, version 3,
42
 * as published by the Free Software Foundation.
43
 *
44
 * This program is distributed in the hope that it will be useful,
45
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
46
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
47
 * GNU Affero General Public License for more details.
48
 *
49
 * You should have received a copy of the GNU Affero General Public License, version 3,
50
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
51
 *
52
 */
53
54
require_once 'public/Constants.php';
55
56
/**
57
 * Class that is a namespace for all global OC variables
58
 * No, we can not put this class in its own file because it is used by
59
 * OC_autoload!
60
 */
61
class OC {
62
	/**
63
	 * Associative array for autoloading. classname => filename
64
	 */
65
	public static $CLASSPATH = array();
66
	/**
67
	 * The installation path for Nextcloud  on the server (e.g. /srv/http/nextcloud)
68
	 */
69
	public static $SERVERROOT = '';
70
	/**
71
	 * the current request path relative to the Nextcloud root (e.g. files/index.php)
72
	 */
73
	private static $SUBURI = '';
74
	/**
75
	 * the Nextcloud root path for http requests (e.g. nextcloud/)
76
	 */
77
	public static $WEBROOT = '';
78
	/**
79
	 * The installation path array of the apps folder on the server (e.g. /srv/http/nextcloud) 'path' and
80
	 * web path in 'url'
81
	 */
82
	public static $APPSROOTS = array();
83
84
	/**
85
	 * @var string
86
	 */
87
	public static $configDir;
88
89
	/**
90
	 * requested app
91
	 */
92
	public static $REQUESTEDAPP = '';
93
94
	/**
95
	 * check if Nextcloud runs in cli mode
96
	 */
97
	public static $CLI = false;
98
99
	/**
100
	 * @var \OC\Autoloader $loader
101
	 */
102
	public static $loader = null;
103
104
	/** @var \Composer\Autoload\ClassLoader $composerAutoloader */
105
	public static $composerAutoloader = null;
106
107
	/**
108
	 * @var \OC\Server
109
	 */
110
	public static $server = null;
111
112
	/**
113
	 * @var \OC\Config
114
	 */
115
	private static $config = null;
116
117
	/**
118
	 * @throws \RuntimeException when the 3rdparty directory is missing or
119
	 * the app path list is empty or contains an invalid path
120
	 */
121
	public static function initPaths() {
122
		if(defined('PHPUNIT_CONFIG_DIR')) {
123
			self::$configDir = OC::$SERVERROOT . '/' . PHPUNIT_CONFIG_DIR . '/';
124
		} elseif(defined('PHPUNIT_RUN') and PHPUNIT_RUN and is_dir(OC::$SERVERROOT . '/tests/config/')) {
125
			self::$configDir = OC::$SERVERROOT . '/tests/config/';
126
		} elseif($dir = getenv('NEXTCLOUD_CONFIG_DIR')) {
127
			self::$configDir = rtrim($dir, '/') . '/';
128
		} else {
129
			self::$configDir = OC::$SERVERROOT . '/config/';
130
		}
131
		self::$config = new \OC\Config(self::$configDir);
132
133
		OC::$SUBURI = str_replace("\\", "/", substr(realpath($_SERVER["SCRIPT_FILENAME"]), strlen(OC::$SERVERROOT)));
134
		/**
135
		 * FIXME: The following lines are required because we can't yet instantiiate
136
		 *        \OC::$server->getRequest() since \OC::$server does not yet exist.
137
		 */
138
		$params = [
139
			'server' => [
140
				'SCRIPT_NAME' => $_SERVER['SCRIPT_NAME'],
141
				'SCRIPT_FILENAME' => $_SERVER['SCRIPT_FILENAME'],
142
			],
143
		];
144
		$fakeRequest = new \OC\AppFramework\Http\Request($params, null, new \OC\AllConfig(new \OC\SystemConfig(self::$config)));
145
		$scriptName = $fakeRequest->getScriptName();
146
		if (substr($scriptName, -1) == '/') {
147
			$scriptName .= 'index.php';
148
			//make sure suburi follows the same rules as scriptName
149
			if (substr(OC::$SUBURI, -9) != 'index.php') {
150
				if (substr(OC::$SUBURI, -1) != '/') {
151
					OC::$SUBURI = OC::$SUBURI . '/';
152
				}
153
				OC::$SUBURI = OC::$SUBURI . 'index.php';
154
			}
155
		}
156
157
158
		if (OC::$CLI) {
159
			OC::$WEBROOT = self::$config->getValue('overwritewebroot', '');
160
		} else {
161
			if (substr($scriptName, 0 - strlen(OC::$SUBURI)) === OC::$SUBURI) {
162
				OC::$WEBROOT = substr($scriptName, 0, 0 - strlen(OC::$SUBURI));
163
164
				if (OC::$WEBROOT != '' && OC::$WEBROOT[0] !== '/') {
165
					OC::$WEBROOT = '/' . OC::$WEBROOT;
166
				}
167
			} else {
168
				// The scriptName is not ending with OC::$SUBURI
169
				// This most likely means that we are calling from CLI.
170
				// However some cron jobs still need to generate
171
				// a web URL, so we use overwritewebroot as a fallback.
172
				OC::$WEBROOT = self::$config->getValue('overwritewebroot', '');
173
			}
174
175
			// Resolve /nextcloud to /nextcloud/ to ensure to always have a trailing
176
			// slash which is required by URL generation.
177
			if($_SERVER['REQUEST_URI'] === \OC::$WEBROOT &&
178
					substr($_SERVER['REQUEST_URI'], -1) !== '/') {
179
				header('Location: '.\OC::$WEBROOT.'/');
180
				exit();
181
			}
182
		}
183
184
		// search the apps folder
185
		$config_paths = self::$config->getValue('apps_paths', array());
186
		if (!empty($config_paths)) {
187
			foreach ($config_paths as $paths) {
188
				if (isset($paths['url']) && isset($paths['path'])) {
189
					$paths['url'] = rtrim($paths['url'], '/');
190
					$paths['path'] = rtrim($paths['path'], '/');
191
					OC::$APPSROOTS[] = $paths;
192
				}
193
			}
194
		} elseif (file_exists(OC::$SERVERROOT . '/apps')) {
195
			OC::$APPSROOTS[] = array('path' => OC::$SERVERROOT . '/apps', 'url' => '/apps', 'writable' => true);
196
		} elseif (file_exists(OC::$SERVERROOT . '/../apps')) {
197
			OC::$APPSROOTS[] = array(
198
				'path' => rtrim(dirname(OC::$SERVERROOT), '/') . '/apps',
199
				'url' => '/apps',
200
				'writable' => true
201
			);
202
		}
203
204
		if (empty(OC::$APPSROOTS)) {
205
			throw new \RuntimeException('apps directory not found! Please put the Nextcloud apps folder in the Nextcloud folder'
206
				. ' or the folder above. You can also configure the location in the config.php file.');
207
		}
208
		$paths = array();
209
		foreach (OC::$APPSROOTS as $path) {
210
			$paths[] = $path['path'];
211
			if (!is_dir($path['path'])) {
212
				throw new \RuntimeException(sprintf('App directory "%s" not found! Please put the Nextcloud apps folder in the'
213
					. ' Nextcloud folder or the folder above. You can also configure the location in the'
214
					. ' config.php file.', $path['path']));
215
			}
216
		}
217
218
		// set the right include path
219
		set_include_path(
220
			implode(PATH_SEPARATOR, $paths)
221
		);
222
	}
223
224
	public static function checkConfig() {
225
		$l = \OC::$server->getL10N('lib');
226
227
		// Create config if it does not already exist
228
		$configFilePath = self::$configDir .'/config.php';
229
		if(!file_exists($configFilePath)) {
230
			@touch($configFilePath);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
231
		}
232
233
		// Check if config is writable
234
		$configFileWritable = is_writable($configFilePath);
235
		if (!$configFileWritable && !OC_Helper::isReadOnlyConfigEnabled()
236
			|| !$configFileWritable && self::checkUpgrade(false)) {
237
238
			$urlGenerator = \OC::$server->getURLGenerator();
239
240
			if (self::$CLI) {
241
				echo $l->t('Cannot write into "config" directory!')."\n";
242
				echo $l->t('This can usually be fixed by giving the webserver write access to the config directory')."\n";
243
				echo "\n";
244
				echo $l->t('See %s', [ $urlGenerator->linkToDocs('admin-dir_permissions') ])."\n";
245
				exit;
246
			} else {
247
				OC_Template::printErrorPage(
248
					$l->t('Cannot write into "config" directory!'),
249
					$l->t('This can usually be fixed by '
250
					. '%sgiving the webserver write access to the config directory%s.',
251
					 array('<a href="' . $urlGenerator->linkToDocs('admin-dir_permissions') . '" target="_blank" rel="noreferrer">', '</a>'))
252
				);
253
			}
254
		}
255
	}
256
257
	public static function checkInstalled() {
258
		if (defined('OC_CONSOLE')) {
259
			return;
260
		}
261
		// Redirect to installer if not installed
262
		if (!\OC::$server->getSystemConfig()->getValue('installed', false) && OC::$SUBURI !== '/index.php' && OC::$SUBURI !== '/status.php') {
263
			if (OC::$CLI) {
264
				throw new Exception('Not installed');
265
			} else {
266
				$url = OC::$WEBROOT . '/index.php';
267
				header('Location: ' . $url);
268
			}
269
			exit();
270
		}
271
	}
272
273
	public static function checkMaintenanceMode() {
274
		// Allow ajax update script to execute without being stopped
275
		if (\OC::$server->getSystemConfig()->getValue('maintenance', false) && OC::$SUBURI != '/core/ajax/update.php') {
276
			// send http status 503
277
			header('HTTP/1.1 503 Service Temporarily Unavailable');
278
			header('Status: 503 Service Temporarily Unavailable');
279
			header('Retry-After: 120');
280
281
			// render error page
282
			$template = new OC_Template('', 'update.user', 'guest');
283
			OC_Util::addScript('maintenance-check');
284
			$template->printPage();
285
			die();
286
		}
287
	}
288
289
	/**
290
	 * Checks if the version requires an update and shows
291
	 * @param bool $showTemplate Whether an update screen should get shown
292
	 * @return bool|void
293
	 */
294
	public static function checkUpgrade($showTemplate = true) {
295
		if (\OCP\Util::needUpgrade()) {
296
			$systemConfig = \OC::$server->getSystemConfig();
297
			if ($showTemplate && !$systemConfig->getValue('maintenance', false)) {
298
				self::printUpgradePage();
299
				exit();
300
			} else {
301
				return true;
302
			}
303
		}
304
		return false;
305
	}
306
307
	/**
308
	 * Prints the upgrade page
309
	 */
310
	private static function printUpgradePage() {
311
		$systemConfig = \OC::$server->getSystemConfig();
312
313
		$disableWebUpdater = $systemConfig->getValue('upgrade.disable-web', false);
314
		$tooBig = false;
315
		if (!$disableWebUpdater) {
316
			$apps = \OC::$server->getAppManager();
317
			$tooBig = $apps->isInstalled('user_ldap') || $apps->isInstalled('user_shibboleth');
318
			if (!$tooBig) {
319
				// count users
320
				$stats = \OC::$server->getUserManager()->countUsers();
321
				$totalUsers = array_sum($stats);
322
				$tooBig = ($totalUsers > 50);
323
			}
324
		}
325
		if ($disableWebUpdater || $tooBig) {
326
			// send http status 503
327
			header('HTTP/1.1 503 Service Temporarily Unavailable');
328
			header('Status: 503 Service Temporarily Unavailable');
329
			header('Retry-After: 120');
330
331
			// render error page
332
			$template = new OC_Template('', 'update.use-cli', 'guest');
333
			$template->assign('productName', 'nextcloud'); // for now
334
			$template->assign('version', OC_Util::getVersionString());
335
			$template->assign('tooBig', $tooBig);
336
337
			$template->printPage();
338
			die();
339
		}
340
341
		// check whether this is a core update or apps update
342
		$installedVersion = $systemConfig->getValue('version', '0.0.0');
343
		$currentVersion = implode('.', \OCP\Util::getVersion());
344
345
		// if not a core upgrade, then it's apps upgrade
346
		$isAppsOnlyUpgrade = (version_compare($currentVersion, $installedVersion, '='));
347
348
		$oldTheme = $systemConfig->getValue('theme');
349
		$systemConfig->setValue('theme', '');
350
		OC_Util::addScript('config'); // needed for web root
351
		OC_Util::addScript('update');
352
353
		/** @var \OC\App\AppManager $appManager */
354
		$appManager = \OC::$server->getAppManager();
355
356
		$tmpl = new OC_Template('', 'update.admin', 'guest');
357
		$tmpl->assign('version', OC_Util::getVersionString());
358
		$tmpl->assign('isAppsOnlyUpgrade', $isAppsOnlyUpgrade);
359
360
		// get third party apps
361
		$ocVersion = \OCP\Util::getVersion();
362
		$incompatibleApps = $appManager->getIncompatibleApps($ocVersion);
363
		$incompatibleShippedApps = [];
364
		foreach ($incompatibleApps as $appInfo) {
365
			if ($appManager->isShipped($appInfo['id'])) {
366
				$incompatibleShippedApps[] = $appInfo['name'] . ' (' . $appInfo['id'] . ')';
367
			}
368
		}
369
370
		if (!empty($incompatibleShippedApps)) {
371
			$l = \OC::$server->getL10N('core');
372
			$hint = $l->t('The files of the app %$1s were not replaced correctly. Make sure it is a version compatible with the server.', [implode(', ', $incompatibleShippedApps)]);
373
			throw new \OC\HintException('The files of the app ' . implode(', ', $incompatibleShippedApps) . ' were not replaced correctly. Make sure it is a version compatible with the server.', $hint);
374
		}
375
376
		$tmpl->assign('appsToUpgrade', $appManager->getAppsNeedingUpgrade($ocVersion));
377
		$tmpl->assign('incompatibleAppsList', $incompatibleApps);
378
		$tmpl->assign('productName', 'Nextcloud'); // for now
379
		$tmpl->assign('oldTheme', $oldTheme);
380
		$tmpl->printPage();
381
	}
382
383
	public static function initSession() {
384
		// prevents javascript from accessing php session cookies
385
		ini_set('session.cookie_httponly', true);
386
387
		// set the cookie path to the Nextcloud directory
388
		$cookie_path = OC::$WEBROOT ? : '/';
389
		ini_set('session.cookie_path', $cookie_path);
390
391
		// Let the session name be changed in the initSession Hook
392
		$sessionName = OC_Util::getInstanceId();
393
394
		try {
395
			// Allow session apps to create a custom session object
396
			$useCustomSession = false;
397
			$session = self::$server->getSession();
398
			OC_Hook::emit('OC', 'initSession', array('session' => &$session, 'sessionName' => &$sessionName, 'useCustomSession' => &$useCustomSession));
399
			if (!$useCustomSession) {
400
				// set the session name to the instance id - which is unique
401
				$session = new \OC\Session\Internal($sessionName);
402
			}
403
404
			$cryptoWrapper = \OC::$server->getSessionCryptoWrapper();
405
			$session = $cryptoWrapper->wrapSession($session);
406
			self::$server->setSession($session);
407
408
			// if session can't be started break with http 500 error
409
		} catch (Exception $e) {
410
			\OCP\Util::logException('base', $e);
0 ignored issues
show
Deprecated Code introduced by
The method OCP\Util::logException() has been deprecated with message: 8.2.0 use logException of \OCP\ILogger

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
411
			//show the user a detailed error page
412
			OC_Response::setStatus(OC_Response::STATUS_INTERNAL_SERVER_ERROR);
413
			OC_Template::printExceptionErrorPage($e);
414
			die();
415
		}
416
417
		$sessionLifeTime = self::getSessionLifeTime();
418
419
		// session timeout
420
		if ($session->exists('LAST_ACTIVITY') && (time() - $session->get('LAST_ACTIVITY') > $sessionLifeTime)) {
421
			if (isset($_COOKIE[session_name()])) {
422
				setcookie(session_name(), null, -1, self::$WEBROOT ? : '/');
423
			}
424
			\OC::$server->getUserSession()->logout();
425
		}
426
427
		$session->set('LAST_ACTIVITY', time());
428
	}
429
430
	/**
431
	 * @return string
432
	 */
433
	private static function getSessionLifeTime() {
434
		return \OC::$server->getConfig()->getSystemValue('session_lifetime', 60 * 60 * 24);
435
	}
436
437
	public static function loadAppClassPaths() {
438 View Code Duplication
		foreach (OC_App::getEnabledApps() as $app) {
439
			$appPath = OC_App::getAppPath($app);
440
			if ($appPath === false) {
441
				continue;
442
			}
443
444
			$file = $appPath . '/appinfo/classpath.php';
445
			if (file_exists($file)) {
446
				require_once $file;
447
			}
448
		}
449
	}
450
451
	/**
452
	 * Try to set some values to the required Nextcloud default
453
	 */
454
	public static function setRequiredIniValues() {
455
		@ini_set('default_charset', 'UTF-8');
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
456
		@ini_set('gd.jpeg_ignore_warning', 1);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
457
	}
458
459
	/**
460
	 * Send the same site cookies
461
	 */
462
	private static function sendSameSiteCookies() {
463
		$cookieParams = session_get_cookie_params();
464
		$secureCookie = ($cookieParams['secure'] === true) ? 'secure; ' : '';
465
		$policies = [
466
			'lax',
467
			'strict',
468
		];
469
470
		// Append __Host to the cookie if it meets the requirements
471
		$cookiePrefix = '';
472
		if($cookieParams['secure'] === true && $cookieParams['path'] === '/') {
473
			$cookiePrefix = '__Host-';
474
		}
475
476
		foreach($policies as $policy) {
477
			header(
478
				sprintf(
479
					'Set-Cookie: %snc_sameSiteCookie%s=true; path=%s; httponly;' . $secureCookie . 'expires=Fri, 31-Dec-2100 23:59:59 GMT; SameSite=%s',
480
					$cookiePrefix,
481
					$policy,
482
					$cookieParams['path'],
483
					$policy
484
				),
485
				false
486
			);
487
		}
488
	}
489
490
	/**
491
	 * Same Site cookie to further mitigate CSRF attacks. This cookie has to
492
	 * be set in every request if cookies are sent to add a second level of
493
	 * defense against CSRF.
494
	 *
495
	 * If the cookie is not sent this will set the cookie and reload the page.
496
	 * We use an additional cookie since we want to protect logout CSRF and
497
	 * also we can't directly interfere with PHP's session mechanism.
498
	 */
499
	private static function performSameSiteCookieProtection() {
500
		$request = \OC::$server->getRequest();
501
502
		// Some user agents are notorious and don't really properly follow HTTP
503
		// specifications. For those, have an automated opt-out. Since the protection
504
		// for remote.php is applied in base.php as starting point we need to opt out
505
		// here.
506
		$incompatibleUserAgents = [
507
			// OS X Finder
508
			'/^WebDAVFS/',
509
		];
510
		if($request->isUserAgent($incompatibleUserAgents)) {
511
			return;
512
		}
513
514
		if(count($_COOKIE) > 0) {
515
			$requestUri = $request->getScriptName();
516
			$processingScript = explode('/', $requestUri);
517
			$processingScript = $processingScript[count($processingScript)-1];
518
			// FIXME: In a SAML scenario we don't get any strict or lax cookie
519
			// send for the ACS endpoint. Since we have some legacy code in Nextcloud
520
			// (direct PHP files) the enforcement of lax cookies is performed here
521
			// instead of the middleware.
522
			//
523
			// This means we cannot exclude some routes from the cookie validation,
524
			// which normally is not a problem but is a little bit cumbersome for
525
			// this use-case.
526
			// Once the old legacy PHP endpoints have been removed we can move
527
			// the verification into a middleware and also adds some exemptions.
528
			//
529
			// Questions about this code? Ask Lukas ;-)
530
			$currentUrl = substr(explode('?',$request->getRequestUri(), 2)[0], strlen(\OC::$WEBROOT));
531
			if($currentUrl === '/index.php/apps/user_saml/saml/acs') {
532
				return;
533
			}
534
			// For the "index.php" endpoint only a lax cookie is required.
535
			if($processingScript === 'index.php') {
536
				if(!$request->passesLaxCookieCheck()) {
537
					self::sendSameSiteCookies();
538
					header('Location: '.$_SERVER['REQUEST_URI']);
539
					exit();
540
				}
541
			} else {
542
				// All other endpoints require the lax and the strict cookie
543
				if(!$request->passesStrictCookieCheck()) {
544
					self::sendSameSiteCookies();
545
					// Debug mode gets access to the resources without strict cookie
546
					// due to the fact that the SabreDAV browser also lives there.
547
					if(!\OC::$server->getConfig()->getSystemValue('debug', false)) {
548
						http_response_code(\OCP\AppFramework\Http::STATUS_SERVICE_UNAVAILABLE);
549
						exit();
550
					}
551
				}
552
			}
553
		} elseif(!isset($_COOKIE['nc_sameSiteCookielax']) || !isset($_COOKIE['nc_sameSiteCookiestrict'])) {
554
			self::sendSameSiteCookies();
555
		}
556
	}
557
558
	public static function init() {
559
		// calculate the root directories
560
		OC::$SERVERROOT = str_replace("\\", '/', substr(__DIR__, 0, -4));
561
562
		// register autoloader
563
		$loaderStart = microtime(true);
564
		require_once __DIR__ . '/autoloader.php';
565
		self::$loader = new \OC\Autoloader([
566
			OC::$SERVERROOT . '/lib/private/legacy',
567
		]);
568
		if (defined('PHPUNIT_RUN')) {
569
			self::$loader->addValidRoot(OC::$SERVERROOT . '/tests');
570
		}
571
		spl_autoload_register(array(self::$loader, 'load'));
572
		$loaderEnd = microtime(true);
573
574
		self::$CLI = (php_sapi_name() == 'cli');
575
576
		// Add default composer PSR-4 autoloader
577
		self::$composerAutoloader = require_once OC::$SERVERROOT . '/lib/composer/autoload.php';
578
579
		try {
580
			self::initPaths();
581
			// setup 3rdparty autoloader
582
			$vendorAutoLoad = OC::$SERVERROOT. '/3rdparty/autoload.php';
583
			if (!file_exists($vendorAutoLoad)) {
584
				throw new \RuntimeException('Composer autoloader not found, unable to continue. Check the folder "3rdparty". Running "git submodule update --init" will initialize the git submodule that handles the subfolder "3rdparty".');
585
			}
586
			require_once $vendorAutoLoad;
587
588
		} catch (\RuntimeException $e) {
589
			if (!self::$CLI) {
590
				$claimedProtocol = strtoupper($_SERVER['SERVER_PROTOCOL']);
591
				$protocol = in_array($claimedProtocol, ['HTTP/1.0', 'HTTP/1.1', 'HTTP/2']) ? $claimedProtocol : 'HTTP/1.1';
592
				header($protocol . ' ' . OC_Response::STATUS_SERVICE_UNAVAILABLE);
593
			}
594
			// we can't use the template error page here, because this needs the
595
			// DI container which isn't available yet
596
			print($e->getMessage());
597
			exit();
598
		}
599
600
		// setup the basic server
601
		self::$server = new \OC\Server(\OC::$WEBROOT, self::$config);
602
		\OC::$server->getEventLogger()->log('autoloader', 'Autoloader', $loaderStart, $loaderEnd);
603
		\OC::$server->getEventLogger()->start('boot', 'Initialize');
604
605
		// Don't display errors and log them
606
		error_reporting(E_ALL | E_STRICT);
607
		@ini_set('display_errors', 0);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
608
		@ini_set('log_errors', 1);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
609
610
		if(!date_default_timezone_set('UTC')) {
611
			throw new \RuntimeException('Could not set timezone to UTC');
612
		};
613
614
		//try to configure php to enable big file uploads.
615
		//this doesn´t work always depending on the webserver and php configuration.
616
		//Let´s try to overwrite some defaults anyway
617
618
		//try to set the maximum execution time to 60min
619
		@set_time_limit(3600);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
620
		@ini_set('max_execution_time', 3600);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
621
		@ini_set('max_input_time', 3600);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
622
623
		//try to set the maximum filesize to 10G
624
		@ini_set('upload_max_filesize', '10G');
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
625
		@ini_set('post_max_size', '10G');
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
626
		@ini_set('file_uploads', '50');
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
627
628
		self::setRequiredIniValues();
629
		self::handleAuthHeaders();
630
		self::registerAutoloaderCache();
631
632
		// initialize intl fallback is necessary
633
		\Patchwork\Utf8\Bootup::initIntl();
634
		OC_Util::isSetLocaleWorking();
635
636
		if (!defined('PHPUNIT_RUN')) {
637
			OC\Log\ErrorHandler::setLogger(\OC::$server->getLogger());
638
			$debug = \OC::$server->getConfig()->getSystemValue('debug', false);
639
			OC\Log\ErrorHandler::register($debug);
640
		}
641
642
		\OC::$server->getEventLogger()->start('init_session', 'Initialize session');
643
		OC_App::loadApps(array('session'));
644
		if (!self::$CLI) {
645
			self::initSession();
646
		}
647
		\OC::$server->getEventLogger()->end('init_session');
648
		self::checkConfig();
649
		self::checkInstalled();
650
651
		OC_Response::addSecurityHeaders();
652
		if(self::$server->getRequest()->getServerProtocol() === 'https') {
653
			ini_set('session.cookie_secure', true);
654
		}
655
656
		self::performSameSiteCookieProtection();
657
658
		if (!defined('OC_CONSOLE')) {
659
			$errors = OC_Util::checkServer(\OC::$server->getConfig());
660
			if (count($errors) > 0) {
661
				if (self::$CLI) {
662
					// Convert l10n string into regular string for usage in database
663
					$staticErrors = [];
664
					foreach ($errors as $error) {
665
						echo $error['error'] . "\n";
666
						echo $error['hint'] . "\n\n";
667
						$staticErrors[] = [
668
							'error' => (string)$error['error'],
669
							'hint' => (string)$error['hint'],
670
						];
671
					}
672
673
					try {
674
						\OC::$server->getConfig()->setAppValue('core', 'cronErrors', json_encode($staticErrors));
675
					} catch (\Exception $e) {
676
						echo('Writing to database failed');
677
					}
678
					exit(1);
679
				} else {
680
					OC_Response::setStatus(OC_Response::STATUS_SERVICE_UNAVAILABLE);
681
					OC_Util::addStyle('guest');
682
					OC_Template::printGuestPage('', 'error', array('errors' => $errors));
683
					exit;
684
				}
685 View Code Duplication
			} elseif (self::$CLI && \OC::$server->getConfig()->getSystemValue('installed', false)) {
686
				\OC::$server->getConfig()->deleteAppValue('core', 'cronErrors');
687
			}
688
		}
689
		//try to set the session lifetime
690
		$sessionLifeTime = self::getSessionLifeTime();
691
		@ini_set('gc_maxlifetime', (string)$sessionLifeTime);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
692
693
		$systemConfig = \OC::$server->getSystemConfig();
694
695
		// User and Groups
696
		if (!$systemConfig->getValue("installed", false)) {
697
			self::$server->getSession()->set('user_id', '');
698
		}
699
700
		OC_User::useBackend(new \OC\User\Database());
701
		OC_Group::useBackend(new \OC\Group\Database());
702
703
		// Subscribe to the hook
704
		\OCP\Util::connectHook(
705
			'\OCA\Files_Sharing\API\Server2Server',
706
			'preLoginNameUsedAsUserName',
707
			'\OC\User\Database',
708
			'preLoginNameUsedAsUserName'
709
		);
710
711
		//setup extra user backends
712
		if (!self::checkUpgrade(false)) {
0 ignored issues
show
Bug Best Practice introduced by
The expression self::checkUpgrade(false) of type null|boolean is loosely compared to false; this is ambiguous if the boolean can be false. You might want to explicitly use !== null instead.

If an expression can have both false, and null as possible values. It is generally a good practice to always use strict comparison to clearly distinguish between those two values.

$a = canBeFalseAndNull();

// Instead of
if ( ! $a) { }

// Better use one of the explicit versions:
if ($a !== null) { }
if ($a !== false) { }
if ($a !== null && $a !== false) { }
Loading history...
713
			OC_User::setupBackends();
714
		} else {
715
			// Run upgrades in incognito mode
716
			OC_User::setIncognitoMode(true);
717
		}
718
719
		self::registerCacheHooks();
720
		self::registerFilesystemHooks();
721
		self::registerShareHooks();
722
		self::registerLogRotate();
723
		self::registerEncryptionWrapper();
724
		self::registerEncryptionHooks();
725
		self::registerAccountHooks();
726
		self::registerSettingsHooks();
727
728
		//make sure temporary files are cleaned up
729
		$tmpManager = \OC::$server->getTempManager();
730
		register_shutdown_function(array($tmpManager, 'clean'));
731
		$lockProvider = \OC::$server->getLockingProvider();
732
		register_shutdown_function(array($lockProvider, 'releaseAll'));
733
734
		// Check whether the sample configuration has been copied
735
		if($systemConfig->getValue('copied_sample_config', false)) {
736
			$l = \OC::$server->getL10N('lib');
737
			header('HTTP/1.1 503 Service Temporarily Unavailable');
738
			header('Status: 503 Service Temporarily Unavailable');
739
			OC_Template::printErrorPage(
740
				$l->t('Sample configuration detected'),
741
				$l->t('It has been detected that the sample configuration has been copied. This can break your installation and is unsupported. Please read the documentation before performing changes on config.php')
742
			);
743
			return;
744
		}
745
746
		$request = \OC::$server->getRequest();
747
		$host = $request->getInsecureServerHost();
748
		/**
749
		 * if the host passed in headers isn't trusted
750
		 * FIXME: Should not be in here at all :see_no_evil:
751
		 */
752
		if (!OC::$CLI
753
			// overwritehost is always trusted, workaround to not have to make
754
			// \OC\AppFramework\Http\Request::getOverwriteHost public
755
			&& self::$server->getConfig()->getSystemValue('overwritehost') === ''
756
			&& !\OC::$server->getTrustedDomainHelper()->isTrustedDomain($host)
757
			&& self::$server->getConfig()->getSystemValue('installed', false)
758
		) {
759
			// Allow access to CSS resources
760
			$isScssRequest = false;
761
			if(strpos($request->getPathInfo(), '/css/') === 0) {
762
				$isScssRequest = true;
763
			}
764
765
			if (!$isScssRequest) {
766
				header('HTTP/1.1 400 Bad Request');
767
				header('Status: 400 Bad Request');
768
769
				\OC::$server->getLogger()->warning(
770
					'Trusted domain error. "{remoteAddress}" tried to access using "{host}" as host.',
771
					[
772
						'app' => 'core',
773
						'remoteAddress' => $request->getRemoteAddress(),
774
						'host' => $host,
775
					]
776
				);
777
778
				$tmpl = new OCP\Template('core', 'untrustedDomain', 'guest');
779
				$tmpl->assign('domain', $host);
780
				$tmpl->printPage();
781
782
				exit();
783
			}
784
		}
785
		\OC::$server->getEventLogger()->end('boot');
786
	}
787
788
	/**
789
	 * register hooks for the cache
790
	 */
791
	public static function registerCacheHooks() {
792
		//don't try to do this before we are properly setup
793
		if (\OC::$server->getSystemConfig()->getValue('installed', false) && !self::checkUpgrade(false)) {
0 ignored issues
show
Bug Best Practice introduced by
The expression self::checkUpgrade(false) of type null|boolean is loosely compared to false; this is ambiguous if the boolean can be false. You might want to explicitly use !== null instead.

If an expression can have both false, and null as possible values. It is generally a good practice to always use strict comparison to clearly distinguish between those two values.

$a = canBeFalseAndNull();

// Instead of
if ( ! $a) { }

// Better use one of the explicit versions:
if ($a !== null) { }
if ($a !== false) { }
if ($a !== null && $a !== false) { }
Loading history...
794
795
			// NOTE: This will be replaced to use OCP
796
			$userSession = self::$server->getUserSession();
797
			$userSession->listen('\OC\User', 'postLogin', function () {
798
				try {
799
					$cache = new \OC\Cache\File();
800
					$cache->gc();
801
				} catch (\OC\ServerNotAvailableException $e) {
802
					// not a GC exception, pass it on
803
					throw $e;
804
				} catch (\Exception $e) {
805
					// a GC exception should not prevent users from using OC,
806
					// so log the exception
807
					\OC::$server->getLogger()->warning('Exception when running cache gc: ' . $e->getMessage(), array('app' => 'core'));
808
				}
809
			});
810
		}
811
	}
812
813
	public static function registerSettingsHooks() {
814
		$dispatcher = \OC::$server->getEventDispatcher();
815
		$dispatcher->addListener(OCP\App\ManagerEvent::EVENT_APP_DISABLE, function($event) {
816
			/** @var \OCP\App\ManagerEvent $event */
817
			\OC::$server->getSettingsManager()->onAppDisabled($event->getAppID());
818
		});
819
		$dispatcher->addListener(OCP\App\ManagerEvent::EVENT_APP_UPDATE, function($event) {
0 ignored issues
show
Unused Code introduced by
The parameter $event is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
820
			/** @var \OCP\App\ManagerEvent $event */
821
			$jobList = \OC::$server->getJobList();
822
			$job = 'OC\\Settings\\RemoveOrphaned';
823
			if(!($jobList->has($job, null))) {
824
				$jobList->add($job);
825
			}
826
		});
827
	}
828
829
	private static function registerEncryptionWrapper() {
830
		$manager = self::$server->getEncryptionManager();
831
		\OCP\Util::connectHook('OC_Filesystem', 'preSetup', $manager, 'setupStorage');
832
	}
833
834
	private static function registerEncryptionHooks() {
835
		$enabled = self::$server->getEncryptionManager()->isEnabled();
836
		if ($enabled) {
837
			\OCP\Util::connectHook('OCP\Share', 'post_shared', 'OC\Encryption\HookManager', 'postShared');
838
			\OCP\Util::connectHook('OCP\Share', 'post_unshare', 'OC\Encryption\HookManager', 'postUnshared');
839
			\OCP\Util::connectHook('OC_Filesystem', 'post_rename', 'OC\Encryption\HookManager', 'postRename');
840
			\OCP\Util::connectHook('\OCA\Files_Trashbin\Trashbin', 'post_restore', 'OC\Encryption\HookManager', 'postRestore');
841
		}
842
	}
843
844
	private static function registerAccountHooks() {
845
		$hookHandler = new \OC\Accounts\Hooks(\OC::$server->getLogger());
846
		\OCP\Util::connectHook('OC_User', 'changeUser', $hookHandler, 'changeUserHook');
847
	}
848
849
	/**
850
	 * register hooks for the cache
851
	 */
852
	public static function registerLogRotate() {
853
		$systemConfig = \OC::$server->getSystemConfig();
854
		if ($systemConfig->getValue('installed', false) && $systemConfig->getValue('log_rotate_size', false) && !self::checkUpgrade(false)) {
0 ignored issues
show
Bug Best Practice introduced by
The expression self::checkUpgrade(false) of type null|boolean is loosely compared to false; this is ambiguous if the boolean can be false. You might want to explicitly use !== null instead.

If an expression can have both false, and null as possible values. It is generally a good practice to always use strict comparison to clearly distinguish between those two values.

$a = canBeFalseAndNull();

// Instead of
if ( ! $a) { }

// Better use one of the explicit versions:
if ($a !== null) { }
if ($a !== false) { }
if ($a !== null && $a !== false) { }
Loading history...
855
			//don't try to do this before we are properly setup
856
			//use custom logfile path if defined, otherwise use default of nextcloud.log in data directory
857
			\OC::$server->getJobList()->add('OC\Log\Rotate');
858
		}
859
	}
860
861
	/**
862
	 * register hooks for the filesystem
863
	 */
864
	public static function registerFilesystemHooks() {
865
		// Check for blacklisted files
866
		OC_Hook::connect('OC_Filesystem', 'write', 'OC\Files\Filesystem', 'isBlacklisted');
867
		OC_Hook::connect('OC_Filesystem', 'rename', 'OC\Files\Filesystem', 'isBlacklisted');
868
	}
869
870
	/**
871
	 * register hooks for sharing
872
	 */
873
	public static function registerShareHooks() {
874
		if (\OC::$server->getSystemConfig()->getValue('installed')) {
875
			OC_Hook::connect('OC_User', 'post_deleteUser', 'OC\Share20\Hooks', 'post_deleteUser');
876
			OC_Hook::connect('OC_User', 'post_removeFromGroup', 'OC\Share20\Hooks', 'post_removeFromGroup');
877
			OC_Hook::connect('OC_User', 'post_deleteGroup', 'OC\Share20\Hooks', 'post_deleteGroup');
878
		}
879
	}
880
881
	protected static function registerAutoloaderCache() {
882
		// The class loader takes an optional low-latency cache, which MUST be
883
		// namespaced. The instanceid is used for namespacing, but might be
884
		// unavailable at this point. Furthermore, it might not be possible to
885
		// generate an instanceid via \OC_Util::getInstanceId() because the
886
		// config file may not be writable. As such, we only register a class
887
		// loader cache if instanceid is available without trying to create one.
888
		$instanceId = \OC::$server->getSystemConfig()->getValue('instanceid', null);
889
		if ($instanceId) {
890
			try {
891
				$memcacheFactory = \OC::$server->getMemCacheFactory();
892
				self::$loader->setMemoryCache($memcacheFactory->createLocal('Autoloader'));
0 ignored issues
show
Bug introduced by
The method createLocal() does not exist on OCP\ICacheFactory. Did you maybe mean create()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
893
			} catch (\Exception $ex) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
894
			}
895
		}
896
	}
897
898
	/**
899
	 * Handle the request
900
	 */
901
	public static function handleRequest() {
902
903
		\OC::$server->getEventLogger()->start('handle_request', 'Handle request');
904
		$systemConfig = \OC::$server->getSystemConfig();
905
		// load all the classpaths from the enabled apps so they are available
906
		// in the routing files of each app
907
		OC::loadAppClassPaths();
908
909
		// Check if Nextcloud is installed or in maintenance (update) mode
910
		if (!$systemConfig->getValue('installed', false)) {
911
			\OC::$server->getSession()->clear();
912
			$setupHelper = new OC\Setup(\OC::$server->getConfig(), \OC::$server->getIniWrapper(),
913
				\OC::$server->getL10N('lib'), \OC::$server->getThemingDefaults(), \OC::$server->getLogger(),
914
				\OC::$server->getSecureRandom());
915
			$controller = new OC\Core\Controller\SetupController($setupHelper);
916
			$controller->run($_POST);
917
			exit();
918
		}
919
920
		$request = \OC::$server->getRequest();
921
		$requestPath = $request->getRawPathInfo();
922
		if ($requestPath === '/heartbeat') {
923
			return;
924
		}
925
		if (substr($requestPath, -3) !== '.js') { // we need these files during the upgrade
926
			self::checkMaintenanceMode();
927
			self::checkUpgrade();
928
		}
929
930
		// emergency app disabling
931
		if ($requestPath === '/disableapp'
932
			&& $request->getMethod() === 'POST'
933
			&& ((string)$request->getParam('appid')) !== ''
934
		) {
935
			\OCP\JSON::callCheck();
0 ignored issues
show
Deprecated Code introduced by
The method OCP\JSON::callCheck() has been deprecated with message: 8.1.0 Use annotation based CSRF checks from the AppFramework instead

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
936
			\OCP\JSON::checkAdminUser();
0 ignored issues
show
Deprecated Code introduced by
The method OCP\JSON::checkAdminUser() has been deprecated with message: 8.1.0 Use annotation based ACLs from the AppFramework instead

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
937
			$appId = (string)$request->getParam('appid');
938
			$appId = \OC_App::cleanAppId($appId);
939
940
			\OC_App::disable($appId);
941
			\OC_JSON::success();
0 ignored issues
show
Deprecated Code introduced by
The method OC_JSON::success() has been deprecated with message: Use a AppFramework JSONResponse instead

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
942
			exit();
943
		}
944
945
		// Always load authentication apps
946
		OC_App::loadApps(['authentication']);
947
948
		// Load minimum set of apps
949
		if (!self::checkUpgrade(false)
0 ignored issues
show
Bug Best Practice introduced by
The expression self::checkUpgrade(false) of type null|boolean is loosely compared to false; this is ambiguous if the boolean can be false. You might want to explicitly use !== null instead.

If an expression can have both false, and null as possible values. It is generally a good practice to always use strict comparison to clearly distinguish between those two values.

$a = canBeFalseAndNull();

// Instead of
if ( ! $a) { }

// Better use one of the explicit versions:
if ($a !== null) { }
if ($a !== false) { }
if ($a !== null && $a !== false) { }
Loading history...
950
			&& !$systemConfig->getValue('maintenance', false)) {
951
			// For logged-in users: Load everything
952
			if(OC_User::isLoggedIn()) {
0 ignored issues
show
Deprecated Code introduced by
The method OC_User::isLoggedIn() has been deprecated with message: use \OC::$server->getUserSession()->isLoggedIn()

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
953
				OC_App::loadApps();
954
			} else {
955
				// For guests: Load only filesystem and logging
956
				OC_App::loadApps(array('filesystem', 'logging'));
957
				self::handleLogin($request);
958
			}
959
		}
960
961
		if (!self::$CLI) {
962
			try {
963
				if (!$systemConfig->getValue('maintenance', false) && !self::checkUpgrade(false)) {
0 ignored issues
show
Bug Best Practice introduced by
The expression self::checkUpgrade(false) of type null|boolean is loosely compared to false; this is ambiguous if the boolean can be false. You might want to explicitly use !== null instead.

If an expression can have both false, and null as possible values. It is generally a good practice to always use strict comparison to clearly distinguish between those two values.

$a = canBeFalseAndNull();

// Instead of
if ( ! $a) { }

// Better use one of the explicit versions:
if ($a !== null) { }
if ($a !== false) { }
if ($a !== null && $a !== false) { }
Loading history...
964
					OC_App::loadApps(array('filesystem', 'logging'));
965
					OC_App::loadApps();
966
				}
967
				OC_Util::setupFS();
968
				OC::$server->getRouter()->match(\OC::$server->getRequest()->getRawPathInfo());
0 ignored issues
show
Deprecated Code introduced by
The method OCP\Route\IRouter::match() has been deprecated with message: 9.0.0

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
969
				return;
970
			} catch (Symfony\Component\Routing\Exception\ResourceNotFoundException $e) {
0 ignored issues
show
Bug introduced by
The class Symfony\Component\Routin...sourceNotFoundException does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
971
				//header('HTTP/1.0 404 Not Found');
972
			} catch (Symfony\Component\Routing\Exception\MethodNotAllowedException $e) {
0 ignored issues
show
Bug introduced by
The class Symfony\Component\Routin...thodNotAllowedException does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
973
				OC_Response::setStatus(405);
974
				return;
975
			}
976
		}
977
978
		// Handle WebDAV
979
		if ($_SERVER['REQUEST_METHOD'] == 'PROPFIND') {
980
			// not allowed any more to prevent people
981
			// mounting this root directly.
982
			// Users need to mount remote.php/webdav instead.
983
			header('HTTP/1.1 405 Method Not Allowed');
984
			header('Status: 405 Method Not Allowed');
985
			return;
986
		}
987
988
		// Someone is logged in
989
		if (OC_User::isLoggedIn()) {
0 ignored issues
show
Deprecated Code introduced by
The method OC_User::isLoggedIn() has been deprecated with message: use \OC::$server->getUserSession()->isLoggedIn()

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
990
			OC_App::loadApps();
991
			OC_User::setupBackends();
992
			OC_Util::setupFS();
993
			// FIXME
994
			// Redirect to default application
995
			OC_Util::redirectToDefaultPage();
996
		} else {
997
			// Not handled and not logged in
998
			header('Location: '.\OC::$server->getURLGenerator()->linkToRouteAbsolute('core.login.showLoginForm'));
999
		}
1000
	}
1001
1002
	/**
1003
	 * Check login: apache auth, auth token, basic auth
1004
	 *
1005
	 * @param OCP\IRequest $request
1006
	 * @return boolean
1007
	 */
1008
	static function handleLogin(OCP\IRequest $request) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1009
		$userSession = self::$server->getUserSession();
1010
		if (OC_User::handleApacheAuth()) {
1011
			return true;
1012
		}
1013
		if ($userSession->tryTokenLogin($request)) {
1014
			return true;
1015
		}
1016
		if (isset($_COOKIE['nc_username'])
1017
			&& isset($_COOKIE['nc_token'])
1018
			&& isset($_COOKIE['nc_session_id'])
1019
			&& $userSession->loginWithCookie($_COOKIE['nc_username'], $_COOKIE['nc_token'], $_COOKIE['nc_session_id'])) {
1020
			return true;
1021
		}
1022
		if ($userSession->tryBasicAuthLogin($request, \OC::$server->getBruteForceThrottler())) {
1023
			return true;
1024
		}
1025
		return false;
1026
	}
1027
1028
	protected static function handleAuthHeaders() {
1029
		//copy http auth headers for apache+php-fcgid work around
1030
		if (isset($_SERVER['HTTP_XAUTHORIZATION']) && !isset($_SERVER['HTTP_AUTHORIZATION'])) {
1031
			$_SERVER['HTTP_AUTHORIZATION'] = $_SERVER['HTTP_XAUTHORIZATION'];
1032
		}
1033
1034
		// Extract PHP_AUTH_USER/PHP_AUTH_PW from other headers if necessary.
1035
		$vars = array(
1036
			'HTTP_AUTHORIZATION', // apache+php-cgi work around
1037
			'REDIRECT_HTTP_AUTHORIZATION', // apache+php-cgi alternative
1038
		);
1039
		foreach ($vars as $var) {
1040
			if (isset($_SERVER[$var]) && preg_match('/Basic\s+(.*)$/i', $_SERVER[$var], $matches)) {
1041
				list($name, $password) = explode(':', base64_decode($matches[1]), 2);
1042
				$_SERVER['PHP_AUTH_USER'] = $name;
1043
				$_SERVER['PHP_AUTH_PW'] = $password;
1044
				break;
1045
			}
1046
		}
1047
	}
1048
}
1049
1050
OC::init();
1051