Completed
Push — stable10 ( 0d72a8...d739df )
by Lukas
14:38 queued 07:27
created

OC::printUpgradePage()   C

Complexity

Conditions 9
Paths 35

Size

Total Lines 73
Code Lines 48

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 9
eloc 48
nc 35
nop 0
dl 0
loc 73
rs 5.9846
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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
			OC::$SERVERROOT . '/lib/private' . PATH_SEPARATOR .
221
			self::$configDir . PATH_SEPARATOR .
222
			OC::$SERVERROOT . '/3rdparty' . PATH_SEPARATOR .
223
			implode(PATH_SEPARATOR, $paths) . PATH_SEPARATOR .
224
			get_include_path() . PATH_SEPARATOR .
225
			OC::$SERVERROOT
226
		);
227
	}
228
229
	public static function checkConfig() {
230
		$l = \OC::$server->getL10N('lib');
231
232
		// Create config if it does not already exist
233
		$configFilePath = self::$configDir .'/config.php';
234
		if(!file_exists($configFilePath)) {
235
			@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...
236
		}
237
238
		// Check if config is writable
239
		$configFileWritable = is_writable($configFilePath);
240
		if (!$configFileWritable && !OC_Helper::isReadOnlyConfigEnabled()
241
			|| !$configFileWritable && self::checkUpgrade(false)) {
242
243
			$urlGenerator = \OC::$server->getURLGenerator();
244
245
			if (self::$CLI) {
246
				echo $l->t('Cannot write into "config" directory!')."\n";
247
				echo $l->t('This can usually be fixed by giving the webserver write access to the config directory')."\n";
248
				echo "\n";
249
				echo $l->t('See %s', [ $urlGenerator->linkToDocs('admin-dir_permissions') ])."\n";
250
				exit;
251
			} else {
252
				OC_Template::printErrorPage(
253
					$l->t('Cannot write into "config" directory!'),
254
					$l->t('This can usually be fixed by '
255
					. '%sgiving the webserver write access to the config directory%s.',
256
					 array('<a href="' . $urlGenerator->linkToDocs('admin-dir_permissions') . '" target="_blank" rel="noreferrer">', '</a>'))
257
				);
258
			}
259
		}
260
	}
261
262
	public static function checkInstalled() {
263
		if (defined('OC_CONSOLE')) {
264
			return;
265
		}
266
		// Redirect to installer if not installed
267
		if (!\OC::$server->getSystemConfig()->getValue('installed', false) && OC::$SUBURI !== '/index.php' && OC::$SUBURI !== '/status.php') {
268
			if (OC::$CLI) {
269
				throw new Exception('Not installed');
270
			} else {
271
				$url = 'http://' . $_SERVER['SERVER_NAME'] . OC::$WEBROOT . '/index.php';
272
				header('Location: ' . $url);
273
			}
274
			exit();
275
		}
276
	}
277
278
	public static function checkMaintenanceMode() {
279
		// Allow ajax update script to execute without being stopped
280
		if (\OC::$server->getSystemConfig()->getValue('maintenance', false) && OC::$SUBURI != '/core/ajax/update.php') {
281
			// send http status 503
282
			header('HTTP/1.1 503 Service Temporarily Unavailable');
283
			header('Status: 503 Service Temporarily Unavailable');
284
			header('Retry-After: 120');
285
286
			// render error page
287
			$template = new OC_Template('', 'update.user', 'guest');
288
			OC_Util::addScript('maintenance-check');
289
			$template->printPage();
290
			die();
291
		}
292
	}
293
294
	public static function checkSingleUserMode($lockIfNoUserLoggedIn = false) {
295
		if (!\OC::$server->getSystemConfig()->getValue('singleuser', false)) {
296
			return;
297
		}
298
		$user = OC_User::getUserSession()->getUser();
299
		if ($user) {
300
			$group = \OC::$server->getGroupManager()->get('admin');
301
			if ($group->inGroup($user)) {
0 ignored issues
show
Compatibility introduced by
$user of type object<OCP\IUser> is not a sub-type of object<OC\User\User>. It seems like you assume a concrete implementation of the interface OCP\IUser to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
302
				return;
303
			}
304
		} else {
305
			if(!$lockIfNoUserLoggedIn) {
306
				return;
307
			}
308
		}
309
		// send http status 503
310
		header('HTTP/1.1 503 Service Temporarily Unavailable');
311
		header('Status: 503 Service Temporarily Unavailable');
312
		header('Retry-After: 120');
313
314
		// render error page
315
		$template = new OC_Template('', 'singleuser.user', 'guest');
316
		$template->printPage();
317
		die();
318
	}
319
320
	/**
321
	 * Checks if the version requires an update and shows
322
	 * @param bool $showTemplate Whether an update screen should get shown
323
	 * @return bool|void
324
	 */
325
	public static function checkUpgrade($showTemplate = true) {
326
		if (\OCP\Util::needUpgrade()) {
327
			$systemConfig = \OC::$server->getSystemConfig();
328
			if ($showTemplate && !$systemConfig->getValue('maintenance', false)) {
329
				self::printUpgradePage();
330
				exit();
331
			} else {
332
				return true;
333
			}
334
		}
335
		return false;
336
	}
337
338
	/**
339
	 * Prints the upgrade page
340
	 */
341
	private static function printUpgradePage() {
342
		$systemConfig = \OC::$server->getSystemConfig();
343
344
		$disableWebUpdater = $systemConfig->getValue('upgrade.disable-web', false);
345
		$tooBig = false;
346
		if (!$disableWebUpdater) {
347
			$apps = \OC::$server->getAppManager();
348
			$tooBig = $apps->isInstalled('user_ldap') || $apps->isInstalled('user_shibboleth');
349
			if (!$tooBig) {
350
				// count users
351
				$stats = \OC::$server->getUserManager()->countUsers();
352
				$totalUsers = array_sum($stats);
353
				$tooBig = ($totalUsers > 50);
354
			}
355
		}
356
		if ($disableWebUpdater || $tooBig) {
357
			// send http status 503
358
			header('HTTP/1.1 503 Service Temporarily Unavailable');
359
			header('Status: 503 Service Temporarily Unavailable');
360
			header('Retry-After: 120');
361
362
			// render error page
363
			$template = new OC_Template('', 'update.use-cli', 'guest');
364
			$template->assign('productName', 'owncloud'); // for now
365
			$template->assign('version', OC_Util::getVersionString());
366
			$template->assign('tooBig', $tooBig);
367
368
			$template->printPage();
369
			die();
370
		}
371
372
		// check whether this is a core update or apps update
373
		$installedVersion = $systemConfig->getValue('version', '0.0.0');
374
		$currentVersion = implode('.', \OCP\Util::getVersion());
375
376
		// if not a core upgrade, then it's apps upgrade
377
		$isAppsOnlyUpgrade = (version_compare($currentVersion, $installedVersion, '='));
378
379
		$oldTheme = $systemConfig->getValue('theme');
380
		$systemConfig->setValue('theme', '');
381
		\OCP\Util::addScript('config'); // needed for web root
382
		\OCP\Util::addScript('update');
383
		\OCP\Util::addStyle('update');
384
385
		/** @var \OC\App\AppManager $appManager */
386
		$appManager = \OC::$server->getAppManager();
387
388
		$tmpl = new OC_Template('', 'update.admin', 'guest');
389
		$tmpl->assign('version', OC_Util::getVersionString());
390
		$tmpl->assign('isAppsOnlyUpgrade', $isAppsOnlyUpgrade);
391
392
		// get third party apps
393
		$ocVersion = \OCP\Util::getVersion();
394
		$incompatibleApps = $appManager->getIncompatibleApps($ocVersion);
395
		$incompatibleShippedApps = [];
396
		foreach ($incompatibleApps as $appInfo) {
397
			if ($appManager->isShipped($appInfo['id'])) {
398
				$incompatibleShippedApps[] = $appInfo['name'] . ' (' . $appInfo['id'] . ')';
399
			}
400
		}
401
402
		if (!empty($incompatibleShippedApps)) {
403
			$l = \OC::$server->getL10N('core');
404
			$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)]);
405
			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);
406
		}
407
408
		$tmpl->assign('appsToUpgrade', $appManager->getAppsNeedingUpgrade($ocVersion));
409
		$tmpl->assign('incompatibleAppsList', $incompatibleApps);
410
		$tmpl->assign('productName', 'Nextcloud'); // for now
411
		$tmpl->assign('oldTheme', $oldTheme);
412
		$tmpl->printPage();
413
	}
414
415
	public static function initSession() {
416
		// prevents javascript from accessing php session cookies
417
		ini_set('session.cookie_httponly', true);
418
419
		// set the cookie path to the Nextcloud directory
420
		$cookie_path = OC::$WEBROOT ? : '/';
421
		ini_set('session.cookie_path', $cookie_path);
422
423
		// Let the session name be changed in the initSession Hook
424
		$sessionName = OC_Util::getInstanceId();
425
426
		try {
427
			// Allow session apps to create a custom session object
428
			$useCustomSession = false;
429
			$session = self::$server->getSession();
430
			OC_Hook::emit('OC', 'initSession', array('session' => &$session, 'sessionName' => &$sessionName, 'useCustomSession' => &$useCustomSession));
431
			if (!$useCustomSession) {
432
				// set the session name to the instance id - which is unique
433
				$session = new \OC\Session\Internal($sessionName);
434
			}
435
436
			$cryptoWrapper = \OC::$server->getSessionCryptoWrapper();
437
			$session = $cryptoWrapper->wrapSession($session);
438
			self::$server->setSession($session);
439
440
			// if session can't be started break with http 500 error
441
		} catch (Exception $e) {
442
			\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...
443
			//show the user a detailed error page
444
			OC_Response::setStatus(OC_Response::STATUS_INTERNAL_SERVER_ERROR);
445
			OC_Template::printExceptionErrorPage($e);
446
			die();
447
		}
448
449
		$sessionLifeTime = self::getSessionLifeTime();
450
451
		// session timeout
452
		if ($session->exists('LAST_ACTIVITY') && (time() - $session->get('LAST_ACTIVITY') > $sessionLifeTime)) {
453
			if (isset($_COOKIE[session_name()])) {
454
				setcookie(session_name(), null, -1, self::$WEBROOT ? : '/');
455
			}
456
			\OC::$server->getUserSession()->logout();
457
		}
458
459
		$session->set('LAST_ACTIVITY', time());
460
	}
461
462
	/**
463
	 * @return string
464
	 */
465
	private static function getSessionLifeTime() {
466
		return \OC::$server->getConfig()->getSystemValue('session_lifetime', 60 * 60 * 24);
467
	}
468
469
	public static function loadAppClassPaths() {
470 View Code Duplication
		foreach (OC_App::getEnabledApps() as $app) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
471
			$appPath = OC_App::getAppPath($app);
472
			if ($appPath === false) {
473
				continue;
474
			}
475
476
			$file = $appPath . '/appinfo/classpath.php';
477
			if (file_exists($file)) {
478
				require_once $file;
479
			}
480
		}
481
	}
482
483
	/**
484
	 * Try to set some values to the required Nextcloud default
485
	 */
486
	public static function setRequiredIniValues() {
487
		@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...
488
		@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...
489
	}
490
491
	/**
492
	 * Send the same site cookies
493
	 */
494
	private static function sendSameSiteCookies() {
495
		$cookieParams = session_get_cookie_params();
496
		$secureCookie = ($cookieParams['secure'] === true) ? 'secure; ' : '';
497
		$policies = [
498
			'lax',
499
			'strict',
500
		];
501
		foreach($policies as $policy) {
502
			header(
503
				sprintf(
504
					'Set-Cookie: nc_sameSiteCookie%s=true; path=%s; httponly;' . $secureCookie . 'expires=Fri, 31-Dec-2100 23:59:59 GMT; SameSite=%s',
505
					$policy,
506
					$cookieParams['path'],
507
					$policy
508
				),
509
				false
510
			);
511
		}
512
	}
513
514
	/**
515
	 * Same Site cookie to further mitigate CSRF attacks. This cookie has to
516
	 * be set in every request if cookies are sent to add a second level of
517
	 * defense against CSRF.
518
	 *
519
	 * If the cookie is not sent this will set the cookie and reload the page.
520
	 * We use an additional cookie since we want to protect logout CSRF and
521
	 * also we can't directly interfere with PHP's session mechanism.
522
	 */
523
	private static function performSameSiteCookieProtection() {
524
		$request = \OC::$server->getRequest();
525
526
		// Some user agents are notorious and don't really properly follow HTTP
527
		// specifications. For those, have an automated opt-out. Since the protection
528
		// for remote.php is applied in base.php as starting point we need to opt out
529
		// here.
530
		$incompatibleUserAgents = [
531
			// OS X Finder
532
			'/^WebDAVFS/',
533
		];
534
		if($request->isUserAgent($incompatibleUserAgents)) {
535
			return;
536
		}
537
538
539
		if(count($_COOKIE) > 0) {
540
			$requestUri = $request->getScriptName();
541
			$processingScript = explode('/', $requestUri);
542
			$processingScript = $processingScript[count($processingScript)-1];
543
			// FIXME: In a SAML scenario we don't get any strict or lax cookie
544
			// send for the ACS endpoint. Since we have some legacy code in Nextcloud
545
			// (direct PHP files) the enforcement of lax cookies is performed here
546
			// instead of the middleware.
547
			//
548
			// This means we cannot exclude some routes from the cookie validation,
549
			// which normally is not a problem but is a little bit cumbersome for
550
			// this use-case.
551
			// Once the old legacy PHP endpoints have been removed we can move
552
			// the verification into a middleware and also adds some exemptions.
553
			//
554
			// Questions about this code? Ask Lukas ;-)
555
			$currentUrl = substr(explode('?',$request->getRequestUri(), 2)[0], strlen(\OC::$WEBROOT));
556
			if($currentUrl === '/index.php/apps/user_saml/saml/acs') {
557
				return;
558
			}
559
			// For the "index.php" endpoint only a lax cookie is required.
560
			if($processingScript === 'index.php') {
561
				if(!$request->passesLaxCookieCheck()) {
562
					self::sendSameSiteCookies();
563
					header('Location: '.$_SERVER['REQUEST_URI']);
564
					exit();
565
				}
566
			} else {
567
				// All other endpoints require the lax and the strict cookie
568
				if(!$request->passesStrictCookieCheck()) {
569
					self::sendSameSiteCookies();
570
					// Debug mode gets access to the resources without strict cookie
571
					// due to the fact that the SabreDAV browser also lives there.
572
					if(!\OC::$server->getConfig()->getSystemValue('debug', false)) {
573
						http_response_code(\OCP\AppFramework\Http::STATUS_SERVICE_UNAVAILABLE);
574
						exit();
575
					}
576
				}
577
			}
578
		} elseif(!isset($_COOKIE['nc_sameSiteCookielax']) || !isset($_COOKIE['nc_sameSiteCookiestrict'])) {
579
			self::sendSameSiteCookies();
580
		}
581
	}
582
583
	public static function init() {
584
		// calculate the root directories
585
		OC::$SERVERROOT = str_replace("\\", '/', substr(__DIR__, 0, -4));
586
587
		// register autoloader
588
		$loaderStart = microtime(true);
589
		require_once __DIR__ . '/autoloader.php';
590
		self::$loader = new \OC\Autoloader([
591
			OC::$SERVERROOT . '/lib/private/legacy',
592
		]);
593
		if (defined('PHPUNIT_RUN')) {
594
			self::$loader->addValidRoot(OC::$SERVERROOT . '/tests');
595
		}
596
		spl_autoload_register(array(self::$loader, 'load'));
597
		$loaderEnd = microtime(true);
598
599
		self::$CLI = (php_sapi_name() == 'cli');
600
601
		// Add default composer PSR-4 autoloader
602
		self::$composerAutoloader = require_once OC::$SERVERROOT . '/lib/composer/autoload.php';
603
604
		try {
605
			self::initPaths();
606
			// setup 3rdparty autoloader
607
			$vendorAutoLoad = OC::$SERVERROOT. '/3rdparty/autoload.php';
608
			if (!file_exists($vendorAutoLoad)) {
609
				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".');
610
			}
611
			require_once $vendorAutoLoad;
612
613
		} catch (\RuntimeException $e) {
614
			if (!self::$CLI) {
615
				$claimedProtocol = strtoupper($_SERVER['SERVER_PROTOCOL']);
616
				$protocol = in_array($claimedProtocol, ['HTTP/1.0', 'HTTP/1.1', 'HTTP/2']) ? $claimedProtocol : 'HTTP/1.1';
617
				header($protocol . ' ' . OC_Response::STATUS_SERVICE_UNAVAILABLE);
618
			}
619
			// we can't use the template error page here, because this needs the
620
			// DI container which isn't available yet
621
			print($e->getMessage());
622
			exit();
623
		}
624
625
		// setup the basic server
626
		self::$server = new \OC\Server(\OC::$WEBROOT, self::$config);
627
		\OC::$server->getEventLogger()->log('autoloader', 'Autoloader', $loaderStart, $loaderEnd);
628
		\OC::$server->getEventLogger()->start('boot', 'Initialize');
629
630
		// Don't display errors and log them
631
		error_reporting(E_ALL | E_STRICT);
632
		@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...
633
		@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...
634
635
		date_default_timezone_set('UTC');
636
637
		//try to configure php to enable big file uploads.
638
		//this doesn´t work always depending on the webserver and php configuration.
639
		//Let´s try to overwrite some defaults anyway
640
641
		//try to set the maximum execution time to 60min
642
		@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...
643
		@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...
644
		@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...
645
646
		//try to set the maximum filesize to 10G
647
		@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...
648
		@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...
649
		@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...
650
651
		self::setRequiredIniValues();
652
		self::handleAuthHeaders();
653
		self::registerAutoloaderCache();
654
655
		// initialize intl fallback is necessary
656
		\Patchwork\Utf8\Bootup::initIntl();
657
		OC_Util::isSetLocaleWorking();
658
659
		if (!defined('PHPUNIT_RUN')) {
660
			OC\Log\ErrorHandler::setLogger(\OC::$server->getLogger());
661
			$debug = \OC::$server->getConfig()->getSystemValue('debug', false);
662
			OC\Log\ErrorHandler::register($debug);
663
		}
664
665
		// register the stream wrappers
666
		stream_wrapper_register('fakedir', 'OC\Files\Stream\Dir');
667
		stream_wrapper_register('static', 'OC\Files\Stream\StaticStream');
668
		stream_wrapper_register('close', 'OC\Files\Stream\Close');
669
		stream_wrapper_register('quota', 'OC\Files\Stream\Quota');
670
		stream_wrapper_register('oc', 'OC\Files\Stream\OC');
671
672
		\OC::$server->getEventLogger()->start('init_session', 'Initialize session');
673
		OC_App::loadApps(array('session'));
674
		if (!self::$CLI) {
675
			self::initSession();
676
		}
677
		\OC::$server->getEventLogger()->end('init_session');
678
		self::checkConfig();
679
		self::checkInstalled();
680
681
		OC_Response::addSecurityHeaders();
682
		if(self::$server->getRequest()->getServerProtocol() === 'https') {
683
			ini_set('session.cookie_secure', true);
684
		}
685
686
		self::performSameSiteCookieProtection();
687
688
		if (!defined('OC_CONSOLE')) {
689
			$errors = OC_Util::checkServer(\OC::$server->getConfig());
690
			if (count($errors) > 0) {
691
				if (self::$CLI) {
692
					// Convert l10n string into regular string for usage in database
693
					$staticErrors = [];
694
					foreach ($errors as $error) {
695
						echo $error['error'] . "\n";
696
						echo $error['hint'] . "\n\n";
697
						$staticErrors[] = [
698
							'error' => (string)$error['error'],
699
							'hint' => (string)$error['hint'],
700
						];
701
					}
702
703
					try {
704
						\OC::$server->getConfig()->setAppValue('core', 'cronErrors', json_encode($staticErrors));
705
					} catch (\Exception $e) {
706
						echo('Writing to database failed');
707
					}
708
					exit(1);
709
				} else {
710
					OC_Response::setStatus(OC_Response::STATUS_SERVICE_UNAVAILABLE);
711
					OC_Template::printGuestPage('', 'error', array('errors' => $errors));
712
					exit;
713
				}
714 View Code Duplication
			} elseif (self::$CLI && \OC::$server->getConfig()->getSystemValue('installed', false)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
715
				\OC::$server->getConfig()->deleteAppValue('core', 'cronErrors');
716
			}
717
		}
718
		//try to set the session lifetime
719
		$sessionLifeTime = self::getSessionLifeTime();
720
		@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...
721
722
		$systemConfig = \OC::$server->getSystemConfig();
723
724
		// User and Groups
725
		if (!$systemConfig->getValue("installed", false)) {
726
			self::$server->getSession()->set('user_id', '');
727
		}
728
729
		OC_User::useBackend(new \OC\User\Database());
730
		OC_Group::useBackend(new \OC\Group\Database());
731
732
		// Subscribe to the hook
733
		\OCP\Util::connectHook(
734
			'\OCA\Files_Sharing\API\Server2Server',
735
			'preLoginNameUsedAsUserName',
736
			'\OC\User\Database',
737
			'preLoginNameUsedAsUserName'
738
		);
739
740
		//setup extra user backends
741
		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...
742
			OC_User::setupBackends();
743
		} else {
744
			// Run upgrades in incognito mode
745
			OC_User::setIncognitoMode(true);
746
		}
747
748
		self::registerCacheHooks();
749
		self::registerFilesystemHooks();
750
		if ($systemConfig->getValue('enable_previews', true)) {
751
			self::registerPreviewHooks();
752
		}
753
		self::registerShareHooks();
754
		self::registerLogRotate();
755
		self::registerEncryptionWrapper();
756
		self::registerEncryptionHooks();
757
		self::registerSettingsHooks();
758
759
		//make sure temporary files are cleaned up
760
		$tmpManager = \OC::$server->getTempManager();
761
		register_shutdown_function(array($tmpManager, 'clean'));
762
		$lockProvider = \OC::$server->getLockingProvider();
763
		register_shutdown_function(array($lockProvider, 'releaseAll'));
764
765
		// Check whether the sample configuration has been copied
766
		if($systemConfig->getValue('copied_sample_config', false)) {
767
			$l = \OC::$server->getL10N('lib');
768
			header('HTTP/1.1 503 Service Temporarily Unavailable');
769
			header('Status: 503 Service Temporarily Unavailable');
770
			OC_Template::printErrorPage(
771
				$l->t('Sample configuration detected'),
772
				$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')
773
			);
774
			return;
775
		}
776
777
		$request = \OC::$server->getRequest();
778
		$host = $request->getInsecureServerHost();
779
		/**
780
		 * if the host passed in headers isn't trusted
781
		 * FIXME: Should not be in here at all :see_no_evil:
782
		 */
783
		if (!OC::$CLI
784
			// overwritehost is always trusted, workaround to not have to make
785
			// \OC\AppFramework\Http\Request::getOverwriteHost public
786
			&& self::$server->getConfig()->getSystemValue('overwritehost') === ''
787
			&& !\OC::$server->getTrustedDomainHelper()->isTrustedDomain($host)
788
			&& self::$server->getConfig()->getSystemValue('installed', false)
789
		) {
790
			header('HTTP/1.1 400 Bad Request');
791
			header('Status: 400 Bad Request');
792
793
			\OC::$server->getLogger()->warning(
794
					'Trusted domain error. "{remoteAddress}" tried to access using "{host}" as host.',
795
					[
796
						'app' => 'core',
797
						'remoteAddress' => $request->getRemoteAddress(),
798
						'host' => $host,
799
					]
800
			);
801
802
			$tmpl = new OCP\Template('core', 'untrustedDomain', 'guest');
803
			$tmpl->assign('domain', $host);
804
			$tmpl->printPage();
805
806
			exit();
807
		}
808
		\OC::$server->getEventLogger()->end('boot');
809
	}
810
811
	/**
812
	 * register hooks for the cache
813
	 */
814
	public static function registerCacheHooks() {
815
		//don't try to do this before we are properly setup
816
		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...
817
818
			// NOTE: This will be replaced to use OCP
819
			$userSession = self::$server->getUserSession();
820
			$userSession->listen('\OC\User', 'postLogin', function () {
821
				try {
822
					$cache = new \OC\Cache\File();
823
					$cache->gc();
824
				} catch (\OC\ServerNotAvailableException $e) {
825
					// not a GC exception, pass it on
826
					throw $e;
827
				} catch (\Exception $e) {
828
					// a GC exception should not prevent users from using OC,
829
					// so log the exception
830
					\OC::$server->getLogger()->warning('Exception when running cache gc: ' . $e->getMessage(), array('app' => 'core'));
831
				}
832
			});
833
		}
834
	}
835
836
	public static function registerSettingsHooks() {
837
		$dispatcher = \OC::$server->getEventDispatcher();
838
		$dispatcher->addListener(OCP\App\ManagerEvent::EVENT_APP_DISABLE, function($event) {
839
			/** @var \OCP\App\ManagerEvent $event */
840
			\OC::$server->getSettingsManager()->onAppDisabled($event->getAppID());
841
		});
842
		$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...
843
			/** @var \OCP\App\ManagerEvent $event */
844
			$jobList = \OC::$server->getJobList();
845
			$job = 'OC\\Settings\\RemoveOrphaned';
846
			if(!($jobList->has($job, null))) {
847
				$jobList->add($job);
848
			}
849
		});
850
	}
851
852
	private static function registerEncryptionWrapper() {
853
		$manager = self::$server->getEncryptionManager();
854
		\OCP\Util::connectHook('OC_Filesystem', 'preSetup', $manager, 'setupStorage');
855
	}
856
857
	private static function registerEncryptionHooks() {
858
		$enabled = self::$server->getEncryptionManager()->isEnabled();
859
		if ($enabled) {
860
			\OCP\Util::connectHook('OCP\Share', 'post_shared', 'OC\Encryption\HookManager', 'postShared');
861
			\OCP\Util::connectHook('OCP\Share', 'post_unshare', 'OC\Encryption\HookManager', 'postUnshared');
862
			\OCP\Util::connectHook('OC_Filesystem', 'post_rename', 'OC\Encryption\HookManager', 'postRename');
863
			\OCP\Util::connectHook('\OCA\Files_Trashbin\Trashbin', 'post_restore', 'OC\Encryption\HookManager', 'postRestore');
864
		}
865
	}
866
867
	/**
868
	 * register hooks for the cache
869
	 */
870
	public static function registerLogRotate() {
871
		$systemConfig = \OC::$server->getSystemConfig();
872
		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...
873
			//don't try to do this before we are properly setup
874
			//use custom logfile path if defined, otherwise use default of nextcloud.log in data directory
875
			\OCP\BackgroundJob::registerJob('OC\Log\Rotate', $systemConfig->getValue('logfile', $systemConfig->getValue('datadirectory', OC::$SERVERROOT . '/data') . '/nextcloud.log'));
0 ignored issues
show
Deprecated Code introduced by
The method OCP\BackgroundJob::registerJob() has been deprecated with message: 8.1.0 Use \OC::$server->getJobList()->add() 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...
876
		}
877
	}
878
879
	/**
880
	 * register hooks for the filesystem
881
	 */
882
	public static function registerFilesystemHooks() {
883
		// Check for blacklisted files
884
		OC_Hook::connect('OC_Filesystem', 'write', 'OC\Files\Filesystem', 'isBlacklisted');
885
		OC_Hook::connect('OC_Filesystem', 'rename', 'OC\Files\Filesystem', 'isBlacklisted');
886
	}
887
888
	/**
889
	 * register hooks for previews
890
	 */
891
	public static function registerPreviewHooks() {
892
		OC_Hook::connect('OC_Filesystem', 'post_write', 'OC\Preview', 'post_write');
893
		OC_Hook::connect('OC_Filesystem', 'delete', 'OC\Preview', 'prepare_delete_files');
894
		OC_Hook::connect('\OCP\Versions', 'preDelete', 'OC\Preview', 'prepare_delete');
895
		OC_Hook::connect('\OCP\Trashbin', 'preDelete', 'OC\Preview', 'prepare_delete');
896
		OC_Hook::connect('OC_Filesystem', 'post_delete', 'OC\Preview', 'post_delete_files');
897
		OC_Hook::connect('\OCP\Versions', 'delete', 'OC\Preview', 'post_delete_versions');
898
		OC_Hook::connect('\OCP\Trashbin', 'delete', 'OC\Preview', 'post_delete');
899
		OC_Hook::connect('\OCP\Versions', 'rollback', 'OC\Preview', 'post_delete_versions');
900
	}
901
902
	/**
903
	 * register hooks for sharing
904
	 */
905
	public static function registerShareHooks() {
906
		if (\OC::$server->getSystemConfig()->getValue('installed')) {
907
			OC_Hook::connect('OC_User', 'post_deleteUser', 'OC\Share20\Hooks', 'post_deleteUser');
908
			OC_Hook::connect('OC_User', 'post_removeFromGroup', 'OC\Share20\Hooks', 'post_removeFromGroup');
909
			OC_Hook::connect('OC_User', 'post_deleteGroup', 'OC\Share20\Hooks', 'post_deleteGroup');
910
		}
911
	}
912
913
	protected static function registerAutoloaderCache() {
914
		// The class loader takes an optional low-latency cache, which MUST be
915
		// namespaced. The instanceid is used for namespacing, but might be
916
		// unavailable at this point. Furthermore, it might not be possible to
917
		// generate an instanceid via \OC_Util::getInstanceId() because the
918
		// config file may not be writable. As such, we only register a class
919
		// loader cache if instanceid is available without trying to create one.
920
		$instanceId = \OC::$server->getSystemConfig()->getValue('instanceid', null);
921
		if ($instanceId) {
922
			try {
923
				$memcacheFactory = \OC::$server->getMemCacheFactory();
924
				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...
925
			} catch (\Exception $ex) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
926
			}
927
		}
928
	}
929
930
	/**
931
	 * Handle the request
932
	 */
933
	public static function handleRequest() {
934
935
		\OC::$server->getEventLogger()->start('handle_request', 'Handle request');
936
		$systemConfig = \OC::$server->getSystemConfig();
937
		// load all the classpaths from the enabled apps so they are available
938
		// in the routing files of each app
939
		OC::loadAppClassPaths();
940
941
		// Check if Nextcloud is installed or in maintenance (update) mode
942
		if (!$systemConfig->getValue('installed', false)) {
943
			\OC::$server->getSession()->clear();
944
			$setupHelper = new OC\Setup(\OC::$server->getConfig(), \OC::$server->getIniWrapper(),
945
				\OC::$server->getL10N('lib'), \OC::$server->getThemingDefaults(), \OC::$server->getLogger(),
946
				\OC::$server->getSecureRandom());
947
			$controller = new OC\Core\Controller\SetupController($setupHelper);
948
			$controller->run($_POST);
949
			exit();
950
		}
951
952
		$request = \OC::$server->getRequest();
953
		$requestPath = $request->getRawPathInfo();
954
		if (substr($requestPath, -3) !== '.js') { // we need these files during the upgrade
955
			self::checkMaintenanceMode();
956
			self::checkUpgrade();
957
		}
958
959
		// emergency app disabling
960
		if ($requestPath === '/disableapp'
961
			&& $request->getMethod() === 'POST'
962
			&& ((string)$request->getParam('appid')) !== ''
963
		) {
964
			\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...
965
			\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...
966
			$appId = (string)$request->getParam('appid');
967
			$appId = \OC_App::cleanAppId($appId);
968
969
			\OC_App::disable($appId);
970
			\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...
971
			exit();
972
		}
973
974
		// Always load authentication apps
975
		OC_App::loadApps(['authentication']);
976
977
		// Load minimum set of apps
978
		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...
979
			&& !$systemConfig->getValue('maintenance', false)) {
980
			// For logged-in users: Load everything
981
			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...
982
				OC_App::loadApps();
983
			} else {
984
				// For guests: Load only filesystem and logging
985
				OC_App::loadApps(array('filesystem', 'logging'));
986
				self::handleLogin($request);
987
			}
988
		}
989
990
		if (!self::$CLI) {
991
			try {
992
				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...
993
					OC_App::loadApps(array('filesystem', 'logging'));
994
					OC_App::loadApps();
995
				}
996
				self::checkSingleUserMode();
997
				OC_Util::setupFS();
998
				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...
999
				return;
1000
			} 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...
1001
				//header('HTTP/1.0 404 Not Found');
1002
			} 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...
1003
				OC_Response::setStatus(405);
1004
				return;
1005
			}
1006
		}
1007
1008
		// Handle WebDAV
1009
		if ($_SERVER['REQUEST_METHOD'] == 'PROPFIND') {
1010
			// not allowed any more to prevent people
1011
			// mounting this root directly.
1012
			// Users need to mount remote.php/webdav instead.
1013
			header('HTTP/1.1 405 Method Not Allowed');
1014
			header('Status: 405 Method Not Allowed');
1015
			return;
1016
		}
1017
1018
		// Someone is logged in
1019
		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...
1020
			OC_App::loadApps();
1021
			OC_User::setupBackends();
1022
			OC_Util::setupFS();
1023
			// FIXME
1024
			// Redirect to default application
1025
			OC_Util::redirectToDefaultPage();
1026
		} else {
1027
			// Not handled and not logged in
1028
			header('Location: '.\OC::$server->getURLGenerator()->linkToRouteAbsolute('core.login.showLoginForm'));
1029
		}
1030
	}
1031
1032
	/**
1033
	 * Check login: apache auth, auth token, basic auth
1034
	 *
1035
	 * @param OCP\IRequest $request
1036
	 * @return boolean
1037
	 */
1038
	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...
1039
		$userSession = self::$server->getUserSession();
1040
		if (OC_User::handleApacheAuth()) {
1041
			return true;
1042
		}
1043
		if ($userSession->tryTokenLogin($request)) {
1044
			return true;
1045
		}
1046
		if ($userSession->tryBasicAuthLogin($request, \OC::$server->getBruteForceThrottler())) {
1047
			return true;
1048
		}
1049
		return false;
1050
	}
1051
1052
	protected static function handleAuthHeaders() {
1053
		//copy http auth headers for apache+php-fcgid work around
1054
		if (isset($_SERVER['HTTP_XAUTHORIZATION']) && !isset($_SERVER['HTTP_AUTHORIZATION'])) {
1055
			$_SERVER['HTTP_AUTHORIZATION'] = $_SERVER['HTTP_XAUTHORIZATION'];
1056
		}
1057
1058
		// Extract PHP_AUTH_USER/PHP_AUTH_PW from other headers if necessary.
1059
		$vars = array(
1060
			'HTTP_AUTHORIZATION', // apache+php-cgi work around
1061
			'REDIRECT_HTTP_AUTHORIZATION', // apache+php-cgi alternative
1062
		);
1063
		foreach ($vars as $var) {
1064
			if (isset($_SERVER[$var]) && preg_match('/Basic\s+(.*)$/i', $_SERVER[$var], $matches)) {
1065
				list($name, $password) = explode(':', base64_decode($matches[1]), 2);
1066
				$_SERVER['PHP_AUTH_USER'] = $name;
1067
				$_SERVER['PHP_AUTH_PW'] = $password;
1068
				break;
1069
			}
1070
		}
1071
	}
1072
}
1073
1074
OC::init();
1075