Completed
Push — master ( 656b54...a1444d )
by Morris
83:46
created

OC   F

Complexity

Total Complexity 169

Size/Duplication

Total Lines 1029
Duplicated Lines 0.58 %

Coupling/Cohesion

Components 1
Dependencies 44

Test Coverage

Coverage 2.94%
Metric Value
wmc 169
lcom 1
cbo 44
dl 6
loc 1029
ccs 18
cts 613
cp 0.0294
rs 0.8922

29 Methods

Rating   Name   Duplication   Size   Complexity  
A getSessionLifeTime() 0 3 1
F initPaths() 3 124 29
C checkConfig() 0 32 7
B checkInstalled() 0 15 5
A checkMaintenanceMode() 0 15 3
B checkSingleUserMode() 0 25 5
A needUpgrade() 0 3 1
A checkUpgrade() 0 12 4
B printUpgradePage() 0 31 2
C initSession() 0 46 8
A loadAppClassPaths() 0 13 4
A setRequiredIniValues() 0 3 1
F init() 3 223 22
A registerLocalAddressBook() 0 7 1
A registerCacheHooks() 0 18 4
A registerEncryptionWrapper() 0 3 1
A registerEncryptionHooks() 0 9 2
A registerLogRotate() 0 8 4
A registerFilesystemHooks() 0 5 1
A registerPreviewHooks() 0 10 1
A registerShareHooks() 0 9 2
A registerAutoloaderCache() 0 16 3
F handleRequest() 0 110 23
B handleAuthHeaders() 0 20 6
B handleLogin() 0 26 6
A cleanupLoginTokens() 0 11 3
A tryApacheAuth() 0 13 3
D tryRememberLogin() 0 34 9
C tryFormLogin() 0 39 8

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like OC often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use OC, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 * @author Adam Williamson <[email protected]>
4
 * @author Andreas Fischer <[email protected]>
5
 * @author Arthur Schiwon <[email protected]>
6
 * @author Bart Visscher <[email protected]>
7
 * @author Bernhard Posselt <[email protected]>
8
 * @author Björn Schießle <[email protected]>
9
 * @author Christopher Schäpers <[email protected]>
10
 * @author davidgumberg <[email protected]>
11
 * @author Florian Scholz <[email protected]>
12
 * @author Florin Peter <[email protected]>
13
 * @author Frank Karlitschek <[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 Joas Schilling <[email protected]>
19
 * @author Jörn Friedrich Dreyer <[email protected]>
20
 * @author Lukas Reschke <[email protected]>
21
 * @author marc0s <[email protected]>
22
 * @author Martin Mattel <[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 scolebrook <[email protected]>
31
 * @author Stefan Herbrechtsmeier <[email protected]>
32
 * @author Thomas Müller <[email protected]>
33
 * @author Thomas Tanghus <[email protected]>
34
 * @author Victor Dubiniuk <[email protected]>
35
 * @author Vincent Petry <[email protected]>
36
 * @author Volkan Gezer <[email protected]>
37
 *
38
 * @copyright Copyright (c) 2015, ownCloud, Inc.
39
 * @license AGPL-3.0
40
 *
41
 * This code is free software: you can redistribute it and/or modify
42
 * it under the terms of the GNU Affero General Public License, version 3,
43
 * as published by the Free Software Foundation.
44
 *
45
 * This program is distributed in the hope that it will be useful,
46
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
47
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
48
 * GNU Affero General Public License for more details.
49
 *
50
 * You should have received a copy of the GNU Affero General Public License, version 3,
51
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
52
 *
53
 */
54
55
require_once 'public/constants.php';
56
57
/**
58
 * Class that is a namespace for all global OC variables
59
 * No, we can not put this class in its own file because it is used by
60
 * OC_autoload!
61
 */
62
class OC {
63
	/**
64
	 * Associative array for autoloading. classname => filename
65
	 */
66
	public static $CLASSPATH = array();
67
	/**
68
	 * The installation path for owncloud on the server (e.g. /srv/http/owncloud)
69
	 */
70
	public static $SERVERROOT = '';
71
	/**
72
	 * the current request path relative to the owncloud root (e.g. files/index.php)
73
	 */
74
	private static $SUBURI = '';
75
	/**
76
	 * the owncloud root path for http requests (e.g. owncloud/)
77
	 */
78
	public static $WEBROOT = '';
79
	/**
80
	 * The installation path of the 3rdparty folder on the server (e.g. /srv/http/owncloud/3rdparty)
81
	 */
82
	public static $THIRDPARTYROOT = '';
83
	/**
84
	 * the root path of the 3rdparty folder for http requests (e.g. owncloud/3rdparty)
85
	 */
86
	public static $THIRDPARTYWEBROOT = '';
87
	/**
88
	 * The installation path array of the apps folder on the server (e.g. /srv/http/owncloud) 'path' and
89
	 * web path in 'url'
90
	 */
91
	public static $APPSROOTS = array();
92
93
	public static $configDir;
94
95
	/**
96
	 * requested app
97
	 */
98
	public static $REQUESTEDAPP = '';
99
100
	/**
101
	 * check if ownCloud runs in cli mode
102
	 */
103
	public static $CLI = false;
104
105
	/**
106
	 * @var \OC\Autoloader $loader
107
	 */
108
	public static $loader = null;
109
110
	/**
111
	 * @var \OC\Server
112
	 */
113
	public static $server = null;
114
115
	/**
116
	 * @var \OC\Config
117
	 */
118
	private static $config = null;
119
120
	/**
121
	 * @throws \RuntimeException when the 3rdparty directory is missing or
122
	 * the app path list is empty or contains an invalid path
123
	 */
124
	public static function initPaths() {
125
		if(defined('PHPUNIT_CONFIG_DIR')) {
126
			self::$configDir = OC::$SERVERROOT . '/' . PHPUNIT_CONFIG_DIR . '/';
127
		} elseif(defined('PHPUNIT_RUN') and PHPUNIT_RUN and is_dir(OC::$SERVERROOT . '/tests/config/')) {
128
			self::$configDir = OC::$SERVERROOT . '/tests/config/';
129
		} else {
130
			self::$configDir = OC::$SERVERROOT . '/config/';
131
		}
132
		self::$config = new \OC\Config(self::$configDir);
133
134
		OC::$SUBURI = str_replace("\\", "/", substr(realpath($_SERVER["SCRIPT_FILENAME"]), strlen(OC::$SERVERROOT)));
135
		/**
136
		 * FIXME: The following lines are required because we can't yet instantiiate
137
		 *        \OC::$server->getRequest() since \OC::$server does not yet exist.
138
		 */
139
		$params = [
140
			'server' => [
141
				'SCRIPT_NAME' => $_SERVER['SCRIPT_NAME'],
142
				'SCRIPT_FILENAME' => $_SERVER['SCRIPT_FILENAME'],
143
			],
144
		];
145
		$fakeRequest = new \OC\AppFramework\Http\Request($params, null, new \OC\AllConfig(new \OC\SystemConfig(self::$config)));
146
		$scriptName = $fakeRequest->getScriptName();
147
		if (substr($scriptName, -1) == '/') {
148
			$scriptName .= 'index.php';
149
			//make sure suburi follows the same rules as scriptName
150
			if (substr(OC::$SUBURI, -9) != 'index.php') {
151
				if (substr(OC::$SUBURI, -1) != '/') {
152
					OC::$SUBURI = OC::$SUBURI . '/';
153
				}
154
				OC::$SUBURI = OC::$SUBURI . 'index.php';
155
			}
156
		}
157
158
159
		if (OC::$CLI) {
160
			OC::$WEBROOT = self::$config->getValue('overwritewebroot', '');
161
		} else {
162
			if (substr($scriptName, 0 - strlen(OC::$SUBURI)) === OC::$SUBURI) {
163
				OC::$WEBROOT = substr($scriptName, 0, 0 - strlen(OC::$SUBURI));
164
165
				if (OC::$WEBROOT != '' && OC::$WEBROOT[0] !== '/') {
166
					OC::$WEBROOT = '/' . OC::$WEBROOT;
167
				}
168
			} else {
169
				// The scriptName is not ending with OC::$SUBURI
170
				// This most likely means that we are calling from CLI.
171
				// However some cron jobs still need to generate
172
				// a web URL, so we use overwritewebroot as a fallback.
173
				OC::$WEBROOT = self::$config->getValue('overwritewebroot', '');
174
			}
175
176
			// Resolve /owncloud to /owncloud/ to ensure to always have a trailing
177
			// slash which is required by URL generation.
178
			if($_SERVER['REQUEST_URI'] === \OC::$WEBROOT &&
179
					substr($_SERVER['REQUEST_URI'], -1) !== '/') {
180
				header('Location: '.\OC::$WEBROOT.'/');
181
				exit();
182
			}
183
		}
184
185
		// search the 3rdparty folder
186
		OC::$THIRDPARTYROOT = self::$config->getValue('3rdpartyroot', null);
187
		OC::$THIRDPARTYWEBROOT = self::$config->getValue('3rdpartyurl', null);
188
189
		if (empty(OC::$THIRDPARTYROOT) && empty(OC::$THIRDPARTYWEBROOT)) {
190
			if (file_exists(OC::$SERVERROOT . '/3rdparty')) {
191
				OC::$THIRDPARTYROOT = OC::$SERVERROOT;
192
				OC::$THIRDPARTYWEBROOT = OC::$WEBROOT;
193
			} elseif (file_exists(OC::$SERVERROOT . '/../3rdparty')) {
194
				OC::$THIRDPARTYWEBROOT = rtrim(dirname(OC::$WEBROOT), '/');
195
				OC::$THIRDPARTYROOT = rtrim(dirname(OC::$SERVERROOT), '/');
196
			}
197
		}
198
		if (empty(OC::$THIRDPARTYROOT) || !file_exists(OC::$THIRDPARTYROOT)) {
199
			throw new \RuntimeException('3rdparty directory not found! Please put the ownCloud 3rdparty'
200
				. ' folder in the ownCloud folder or the folder above.'
201
				. ' You can also configure the location in the config.php file.');
202
		}
203
204
		// search the apps folder
205
		$config_paths = self::$config->getValue('apps_paths', array());
206
		if (!empty($config_paths)) {
207
			foreach ($config_paths as $paths) {
208
				if (isset($paths['url']) && isset($paths['path'])) {
209
					$paths['url'] = rtrim($paths['url'], '/');
210
					$paths['path'] = rtrim($paths['path'], '/');
211
					OC::$APPSROOTS[] = $paths;
212
				}
213
			}
214 View Code Duplication
		} elseif (file_exists(OC::$SERVERROOT . '/apps')) {
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...
215
			OC::$APPSROOTS[] = array('path' => OC::$SERVERROOT . '/apps', 'url' => '/apps', 'writable' => true);
216
		} elseif (file_exists(OC::$SERVERROOT . '/../apps')) {
217
			OC::$APPSROOTS[] = array(
218
				'path' => rtrim(dirname(OC::$SERVERROOT), '/') . '/apps',
219
				'url' => '/apps',
220
				'writable' => true
221
			);
222
		}
223
224
		if (empty(OC::$APPSROOTS)) {
225
			throw new \RuntimeException('apps directory not found! Please put the ownCloud apps folder in the ownCloud folder'
226
				. ' or the folder above. You can also configure the location in the config.php file.');
227
		}
228
		$paths = array();
229
		foreach (OC::$APPSROOTS as $path) {
230
			$paths[] = $path['path'];
231
			if (!is_dir($path['path'])) {
232
				throw new \RuntimeException(sprintf('App directory "%s" not found! Please put the ownCloud apps folder in the'
233
					. ' ownCloud folder or the folder above. You can also configure the location in the'
234
					. ' config.php file.', $path['path']));
235
			}
236
		}
237
238
		// set the right include path
239
		set_include_path(
240
			OC::$SERVERROOT . '/lib/private' . PATH_SEPARATOR .
241
			OC::$SERVERROOT . '/config' . PATH_SEPARATOR .
242
			OC::$THIRDPARTYROOT . '/3rdparty' . PATH_SEPARATOR .
243
			implode(PATH_SEPARATOR, $paths) . PATH_SEPARATOR .
244
			get_include_path() . PATH_SEPARATOR .
245
			OC::$SERVERROOT
246
		);
247
	}
248
249
	public static function checkConfig() {
250
		$l = \OC::$server->getL10N('lib');
251
252
		// Create config if it does not already exist
253
		$configFilePath = self::$configDir .'/config.php';
254
		if(!file_exists($configFilePath)) {
255
			@touch($configFilePath);
256
		}
257
258
		// Check if config is writable
259
		$configFileWritable = is_writable($configFilePath);
260
		if (!$configFileWritable && !OC_Helper::isReadOnlyConfigEnabled()
261
			|| !$configFileWritable && self::checkUpgrade(false)) {
262
263
			$urlGenerator = \OC::$server->getURLGenerator();
264
265
			if (self::$CLI) {
266
				echo $l->t('Cannot write into "config" directory!')."\n";
267
				echo $l->t('This can usually be fixed by giving the webserver write access to the config directory')."\n";
268
				echo "\n";
269
				echo $l->t('See %s', [ $urlGenerator->linkToDocs('admin-dir_permissions') ])."\n";
270
				exit;
271
			} else {
272
				OC_Template::printErrorPage(
273
					$l->t('Cannot write into "config" directory!'),
274
					$l->t('This can usually be fixed by '
275
					. '%sgiving the webserver write access to the config directory%s.',
276
					 array('<a href="' . $urlGenerator->linkToDocs('admin-dir_permissions') . '" target="_blank">', '</a>'))
277
				);
278
			}
279
		}
280
	}
281
282
	public static function checkInstalled() {
283
		if (defined('OC_CONSOLE')) {
284
			return;
285
		}
286
		// Redirect to installer if not installed
287
		if (!\OC::$server->getSystemConfig()->getValue('installed', false) && OC::$SUBURI != '/index.php') {
288
			if (OC::$CLI) {
289
				throw new Exception('Not installed');
290
			} else {
291
				$url = 'http://' . $_SERVER['SERVER_NAME'] . OC::$WEBROOT . '/index.php';
292
				header('Location: ' . $url);
293
			}
294
			exit();
295
		}
296
	}
297
298
	public static function checkMaintenanceMode() {
299
		// Allow ajax update script to execute without being stopped
300
		if (\OC::$server->getSystemConfig()->getValue('maintenance', false) && OC::$SUBURI != '/core/ajax/update.php') {
301
			// send http status 503
302
			header('HTTP/1.1 503 Service Temporarily Unavailable');
303
			header('Status: 503 Service Temporarily Unavailable');
304
			header('Retry-After: 120');
305
306
			// render error page
307
			$template = new OC_Template('', 'update.user', 'guest');
308
			OC_Util::addscript('maintenance-check');
309
			$template->printPage();
310
			die();
311
		}
312
	}
313
314
	public static function checkSingleUserMode($lockIfNoUserLoggedIn = false) {
315
		if (!\OC::$server->getSystemConfig()->getValue('singleuser', false)) {
316
			return;
317
		}
318
		$user = OC_User::getUserSession()->getUser();
319
		if ($user) {
320
			$group = \OC::$server->getGroupManager()->get('admin');
321
			if ($group->inGroup($user)) {
322
				return;
323
			}
324
		} else {
325
			if(!$lockIfNoUserLoggedIn) {
326
				return;
327
			}
328
		}
329
		// send http status 503
330
		header('HTTP/1.1 503 Service Temporarily Unavailable');
331
		header('Status: 503 Service Temporarily Unavailable');
332
		header('Retry-After: 120');
333
334
		// render error page
335
		$template = new OC_Template('', 'singleuser.user', 'guest');
336
		$template->printPage();
337
		die();
338
	}
339
340
	/**
341
	 * check if the instance needs to perform an upgrade
342
	 *
343
	 * @return bool
344
	 * @deprecated use \OCP\Util::needUpgrade() instead
345
	 */
346
	public static function needUpgrade() {
347
		return \OCP\Util::needUpgrade();
348
	}
349
350
	/**
351
	 * Checks if the version requires an update and shows
352
	 * @param bool $showTemplate Whether an update screen should get shown
353
	 * @return bool|void
354
	 */
355 21
	public static function checkUpgrade($showTemplate = true) {
356 21
		if (\OCP\Util::needUpgrade()) {
357
			$systemConfig = \OC::$server->getSystemConfig();
358
			if ($showTemplate && !$systemConfig->getValue('maintenance', false)) {
359
				self::printUpgradePage();
360
				exit();
361
			} else {
362
				return true;
363
			}
364
		}
365 21
		return false;
366
	}
367
368
	/**
369
	 * Prints the upgrade page
370
	 */
371
	private static function printUpgradePage() {
372
		$systemConfig = \OC::$server->getSystemConfig();
373
		$oldTheme = $systemConfig->getValue('theme');
374
		$systemConfig->setValue('theme', '');
375
		\OCP\Util::addScript('config'); // needed for web root
376
		\OCP\Util::addScript('update');
377
378
		// check whether this is a core update or apps update
379
		$installedVersion = $systemConfig->getValue('version', '0.0.0');
380
		$currentVersion = implode('.', \OCP\Util::getVersion());
381
382
		$appManager = \OC::$server->getAppManager();
383
384
		$tmpl = new OC_Template('', 'update.admin', 'guest');
385
		$tmpl->assign('version', OC_Util::getVersionString());
386
387
		// if not a core upgrade, then it's apps upgrade
388
		if (version_compare($currentVersion, $installedVersion, '=')) {
389
			$tmpl->assign('isAppsOnlyUpgrade', true);
390
		} else {
391
			$tmpl->assign('isAppsOnlyUpgrade', false);
392
		}
393
394
		// get third party apps
395
		$ocVersion = \OCP\Util::getVersion();
396
		$tmpl->assign('appsToUpgrade', $appManager->getAppsNeedingUpgrade($ocVersion));
397
		$tmpl->assign('incompatibleAppsList', $appManager->getIncompatibleApps($ocVersion));
398
		$tmpl->assign('productName', 'ownCloud'); // for now
399
		$tmpl->assign('oldTheme', $oldTheme);
400
		$tmpl->printPage();
401
	}
402
403
	public static function initSession() {
404
		// prevents javascript from accessing php session cookies
405
		ini_set('session.cookie_httponly', true);
406
407
		// set the cookie path to the ownCloud directory
408
		$cookie_path = OC::$WEBROOT ? : '/';
409
		ini_set('session.cookie_path', $cookie_path);
410
411
		// Let the session name be changed in the initSession Hook
412
		$sessionName = OC_Util::getInstanceId();
413
414
		try {
415
			// Allow session apps to create a custom session object
416
			$useCustomSession = false;
417
			$session = self::$server->getSession();
418
			OC_Hook::emit('OC', 'initSession', array('session' => &$session, 'sessionName' => &$sessionName, 'useCustomSession' => &$useCustomSession));
419
			if (!$useCustomSession) {
420
				// set the session name to the instance id - which is unique
421
				$session = new \OC\Session\Internal($sessionName);
422
			}
423
424
			$cryptoWrapper = \OC::$server->getSessionCryptoWrapper();
425
			$session = $cryptoWrapper->wrapSession($session);
426
			self::$server->setSession($session);
427
428
			// if session cant be started break with http 500 error
429
		} catch (Exception $e) {
430
			\OCP\Util::logException('base', $e);
431
			//show the user a detailed error page
432
			OC_Response::setStatus(OC_Response::STATUS_INTERNAL_SERVER_ERROR);
433
			OC_Template::printExceptionErrorPage($e);
434
			die();
435
		}
436
437
		$sessionLifeTime = self::getSessionLifeTime();
438
439
		// session timeout
440
		if ($session->exists('LAST_ACTIVITY') && (time() - $session->get('LAST_ACTIVITY') > $sessionLifeTime)) {
441
			if (isset($_COOKIE[session_name()])) {
442
				setcookie(session_name(), null, -1, self::$WEBROOT ? : '/');
443
			}
444
			$session->clear();
445
		}
446
447
		$session->set('LAST_ACTIVITY', time());
448
	}
449
450
	/**
451
	 * @return string
452
	 */
453
	private static function getSessionLifeTime() {
454
		return \OC::$server->getConfig()->getSystemValue('session_lifetime', 60 * 60 * 24);
455
	}
456
457
	public static function loadAppClassPaths() {
458
		foreach (OC_APP::getEnabledApps() as $app) {
459
			$appPath = OC_App::getAppPath($app);
460
			if ($appPath === false) {
461
				continue;
462
			}
463
464
			$file = $appPath . '/appinfo/classpath.php';
465
			if (file_exists($file)) {
466
				require_once $file;
467
			}
468
		}
469
	}
470
471
	/**
472
	 * Try to set some values to the required ownCloud default
473
	 */
474
	public static function setRequiredIniValues() {
475
		@ini_set('default_charset', 'UTF-8');
476
	}
477
478
	public static function init() {
479
		// calculate the root directories
480
		OC::$SERVERROOT = str_replace("\\", '/', substr(__DIR__, 0, -4));
481
482
		// register autoloader
483
		$loaderStart = microtime(true);
484
		require_once __DIR__ . '/autoloader.php';
485
		self::$loader = new \OC\Autoloader([
486
			OC::$SERVERROOT . '/lib',
487
			OC::$SERVERROOT . '/core',
488
			OC::$SERVERROOT . '/settings',
489
			OC::$SERVERROOT . '/ocs',
490
			OC::$SERVERROOT . '/ocs-provider',
491
			OC::$SERVERROOT . '/3rdparty',
492
			OC::$SERVERROOT . '/tests',
493
		]);
494
		spl_autoload_register(array(self::$loader, 'load'));
495
		$loaderEnd = microtime(true);
496
497
		self::$CLI = (php_sapi_name() == 'cli');
498
499
		try {
500
			self::initPaths();
501
			// setup 3rdparty autoloader
502
			$vendorAutoLoad = OC::$THIRDPARTYROOT . '/3rdparty/autoload.php';
503
			if (!file_exists($vendorAutoLoad)) {
504
				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".');
505
			}
506
			require_once $vendorAutoLoad;
507
508
		} catch (\RuntimeException $e) {
509
			OC_Response::setStatus(OC_Response::STATUS_SERVICE_UNAVAILABLE);
510
			// we can't use the template error page here, because this needs the
511
			// DI container which isn't available yet
512
			print($e->getMessage());
513
			exit();
514
		}
515
516
		// setup the basic server
517
		self::$server = new \OC\Server(\OC::$WEBROOT, self::$config);
518
		\OC::$server->getEventLogger()->log('autoloader', 'Autoloader', $loaderStart, $loaderEnd);
519
		\OC::$server->getEventLogger()->start('boot', 'Initialize');
520
521
		// Don't display errors and log them
522
		error_reporting(E_ALL | E_STRICT);
523
		@ini_set('display_errors', 0);
524
		@ini_set('log_errors', 1);
525
526
		date_default_timezone_set('UTC');
527
528
		//try to configure php to enable big file uploads.
529
		//this doesn´t work always depending on the webserver and php configuration.
530
		//Let´s try to overwrite some defaults anyway
531
532
		//try to set the maximum execution time to 60min
533
		@set_time_limit(3600);
534
		@ini_set('max_execution_time', 3600);
535
		@ini_set('max_input_time', 3600);
536
537
		//try to set the maximum filesize to 10G
538
		@ini_set('upload_max_filesize', '10G');
539
		@ini_set('post_max_size', '10G');
540
		@ini_set('file_uploads', '50');
541
542
		self::setRequiredIniValues();
543
		self::handleAuthHeaders();
544
		self::registerAutoloaderCache();
545
546
		// initialize intl fallback is necessary
547
		\Patchwork\Utf8\Bootup::initIntl();
548
		OC_Util::isSetLocaleWorking();
549
550
		if (!defined('PHPUNIT_RUN')) {
551
			$logger = \OC::$server->getLogger();
552
			OC\Log\ErrorHandler::setLogger($logger);
553
			if (\OC::$server->getConfig()->getSystemValue('debug', false)) {
554
				OC\Log\ErrorHandler::register(true);
555
				set_exception_handler(array('OC_Template', 'printExceptionErrorPage'));
556
			} else {
557
				OC\Log\ErrorHandler::register();
558
			}
559
		}
560
561
		// register the stream wrappers
562
		stream_wrapper_register('fakedir', 'OC\Files\Stream\Dir');
563
		stream_wrapper_register('static', 'OC\Files\Stream\StaticStream');
564
		stream_wrapper_register('close', 'OC\Files\Stream\Close');
565
		stream_wrapper_register('quota', 'OC\Files\Stream\Quota');
566
		stream_wrapper_register('oc', 'OC\Files\Stream\OC');
567
568
		\OC::$server->getEventLogger()->start('init_session', 'Initialize session');
569
		OC_App::loadApps(array('session'));
570
		if (!self::$CLI) {
571
			self::initSession();
572
		}
573
		\OC::$server->getEventLogger()->end('init_session');
574
		self::checkConfig();
575
		self::checkInstalled();
576
577
		OC_Response::addSecurityHeaders();
578
		if(self::$server->getRequest()->getServerProtocol() === 'https') {
579
			ini_set('session.cookie_secure', true);
580
		}
581
582
		if (!defined('OC_CONSOLE')) {
583
			$errors = OC_Util::checkServer(\OC::$server->getConfig());
584
			if (count($errors) > 0) {
585
				if (self::$CLI) {
586
					// Convert l10n string into regular string for usage in database
587
					$staticErrors = [];
588
					foreach ($errors as $error) {
589
						echo $error['error'] . "\n";
590
						echo $error['hint'] . "\n\n";
591
						$staticErrors[] = [
592
							'error' => (string)$error['error'],
593
							'hint' => (string)$error['hint'],
594
						];
595
					}
596
597
					try {
598
						\OC::$server->getConfig()->setAppValue('core', 'cronErrors', json_encode($staticErrors));
599
					} catch (\Exception $e) {
600
						echo('Writing to database failed');
601
					}
602
					exit(1);
603
				} else {
604
					OC_Response::setStatus(OC_Response::STATUS_SERVICE_UNAVAILABLE);
605
					OC_Template::printGuestPage('', 'error', array('errors' => $errors));
606
					exit;
607
				}
608 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...
609
				\OC::$server->getConfig()->deleteAppValue('core', 'cronErrors');
610
			}
611
		}
612
		//try to set the session lifetime
613
		$sessionLifeTime = self::getSessionLifeTime();
614
		@ini_set('gc_maxlifetime', (string)$sessionLifeTime);
615
616
		$systemConfig = \OC::$server->getSystemConfig();
617
618
		// User and Groups
619
		if (!$systemConfig->getValue("installed", false)) {
620
			self::$server->getSession()->set('user_id', '');
621
		}
622
623
		OC_User::useBackend(new OC_User_Database());
624
		OC_Group::useBackend(new OC_Group_Database());
625
626
		// Subscribe to the hook
627
		\OCP\Util::connectHook(
628
			'\OCA\Files_Sharing\API\Server2Server',
629
			'preLoginNameUsedAsUserName',
630
			'\OC_User_Database',
631
			'preLoginNameUsedAsUserName'
632
		);
633
634
		//setup extra user backends
635
		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...
636
			OC_User::setupBackends();
637
		}
638
639
		self::registerCacheHooks();
640
		self::registerFilesystemHooks();
641
		if ($systemConfig->getValue('enable_previews', true)) {
642
			self::registerPreviewHooks();
643
		}
644
		self::registerShareHooks();
645
		self::registerLogRotate();
646
		self::registerLocalAddressBook();
647
		self::registerEncryptionWrapper();
648
		self::registerEncryptionHooks();
649
650
		//make sure temporary files are cleaned up
651
		$tmpManager = \OC::$server->getTempManager();
652
		register_shutdown_function(array($tmpManager, 'clean'));
653
		$lockProvider = \OC::$server->getLockingProvider();
654
		register_shutdown_function(array($lockProvider, 'releaseAll'));
655
656
		// Check whether the sample configuration has been copied
657
		if($systemConfig->getValue('copied_sample_config', false)) {
658
			$l = \OC::$server->getL10N('lib');
659
			header('HTTP/1.1 503 Service Temporarily Unavailable');
660
			header('Status: 503 Service Temporarily Unavailable');
661
			OC_Template::printErrorPage(
662
				$l->t('Sample configuration detected'),
663
				$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')
664
			);
665
			return;
666
		}
667
668
		$request = \OC::$server->getRequest();
669
		$host = $request->getInsecureServerHost();
670
		/**
671
		 * if the host passed in headers isn't trusted
672
		 * FIXME: Should not be in here at all :see_no_evil:
673
		 */
674
		if (!OC::$CLI
675
			// overwritehost is always trusted, workaround to not have to make
676
			// \OC\AppFramework\Http\Request::getOverwriteHost public
677
			&& self::$server->getConfig()->getSystemValue('overwritehost') === ''
678
			&& !\OC::$server->getTrustedDomainHelper()->isTrustedDomain($host)
679
			&& self::$server->getConfig()->getSystemValue('installed', false)
680
		) {
681
			header('HTTP/1.1 400 Bad Request');
682
			header('Status: 400 Bad Request');
683
684
			\OC::$server->getLogger()->warning(
685
					'Trusted domain error. "{remoteAddress}" tried to access using "{host}" as host.',
686
					[
687
						'app' => 'core',
688
						'remoteAddress' => $request->getRemoteAddress(),
689
						'host' => $host,
690
					]
691
			);
692
693
			$tmpl = new OCP\Template('core', 'untrustedDomain', 'guest');
694
			$tmpl->assign('domain', $request->server['SERVER_NAME']);
0 ignored issues
show
Bug introduced by
Accessing server on the interface OCP\IRequest suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
695
			$tmpl->printPage();
696
697
			exit();
698
		}
699
		\OC::$server->getEventLogger()->end('boot');
700
	}
701
702
	private static function registerLocalAddressBook() {
703
		self::$server->getContactsManager()->register(function() {
704
			$userManager = \OC::$server->getUserManager();
705
			\OC::$server->getContactsManager()->registerAddressBook(
706
				new \OC\Contacts\LocalAddressBook($userManager));
707
		});
708
	}
709
710
	/**
711
	 * register hooks for the cache
712
	 */
713 570
	public static function registerCacheHooks() {
714
		//don't try to do this before we are properly setup
715
		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...
716
717
			// NOTE: This will be replaced to use OCP
718
			$userSession = self::$server->getUserSession();
719 570
			$userSession->listen('\OC\User', 'postLogin', function () {
720
				try {
721 570
					$cache = new \OC\Cache\File();
722 570
					$cache->gc();
723 570
				} catch (\Exception $e) {
724
					// a GC exception should not prevent users from using OC,
725
					// so log the exception
726
					\OC::$server->getLogger()->warning('Exception when running cache gc: ' . $e->getMessage(), array('app' => 'core'));
727
				}
728 570
			});
729
		}
730
	}
731
732
	private static function registerEncryptionWrapper() {
733
		\OCP\Util::connectHook('OC_Filesystem', 'preSetup', 'OC\Encryption\Manager', 'setupStorage');
734
	}
735
736
	private static function registerEncryptionHooks() {
737
		$enabled = self::$server->getEncryptionManager()->isEnabled();
738
		if ($enabled) {
739
			\OCP\Util::connectHook('OCP\Share', 'post_shared', 'OC\Encryption\HookManager', 'postShared');
740
			\OCP\Util::connectHook('OCP\Share', 'post_unshare', 'OC\Encryption\HookManager', 'postUnshared');
741
			\OCP\Util::connectHook('OC_Filesystem', 'post_rename', 'OC\Encryption\HookManager', 'postRename');
742
			\OCP\Util::connectHook('\OCA\Files_Trashbin\Trashbin', 'post_restore', 'OC\Encryption\HookManager', 'postRestore');
743
		}
744
	}
745
746
	/**
747
	 * register hooks for the cache
748
	 */
749
	public static function registerLogRotate() {
750
		$systemConfig = \OC::$server->getSystemConfig();
751
		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...
752
			//don't try to do this before we are properly setup
753
			//use custom logfile path if defined, otherwise use default of owncloud.log in data directory
754
			\OCP\BackgroundJob::registerJob('OC\Log\Rotate', $systemConfig->getValue('logfile', $systemConfig->getValue('datadirectory', OC::$SERVERROOT . '/data') . '/owncloud.log'));
755
		}
756
	}
757
758
	/**
759
	 * register hooks for the filesystem
760
	 */
761
	public static function registerFilesystemHooks() {
762
		// Check for blacklisted files
763
		OC_Hook::connect('OC_Filesystem', 'write', 'OC\Files\Filesystem', 'isBlacklisted');
764
		OC_Hook::connect('OC_Filesystem', 'rename', 'OC\Files\Filesystem', 'isBlacklisted');
765
	}
766
767
	/**
768
	 * register hooks for previews
769
	 */
770
	public static function registerPreviewHooks() {
771
		OC_Hook::connect('OC_Filesystem', 'post_write', 'OC\Preview', 'post_write');
772
		OC_Hook::connect('OC_Filesystem', 'delete', 'OC\Preview', 'prepare_delete_files');
773
		OC_Hook::connect('\OCP\Versions', 'preDelete', 'OC\Preview', 'prepare_delete');
774
		OC_Hook::connect('\OCP\Trashbin', 'preDelete', 'OC\Preview', 'prepare_delete');
775
		OC_Hook::connect('OC_Filesystem', 'post_delete', 'OC\Preview', 'post_delete_files');
776
		OC_Hook::connect('\OCP\Versions', 'delete', 'OC\Preview', 'post_delete_versions');
777
		OC_Hook::connect('\OCP\Trashbin', 'delete', 'OC\Preview', 'post_delete');
778
		OC_Hook::connect('\OCP\Versions', 'rollback', 'OC\Preview', 'post_delete_versions');
779
	}
780
781
	/**
782
	 * register hooks for sharing
783
	 */
784 90
	public static function registerShareHooks() {
785 90
		if (\OC::$server->getSystemConfig()->getValue('installed')) {
786 90
			OC_Hook::connect('OC_User', 'post_deleteUser', 'OC\Share\Hooks', 'post_deleteUser');
787 90
			OC_Hook::connect('OC_User', 'post_addToGroup', 'OC\Share\Hooks', 'post_addToGroup');
788 90
			OC_Hook::connect('OC_Group', 'pre_addToGroup', 'OC\Share\Hooks', 'pre_addToGroup');
789 90
			OC_Hook::connect('OC_User', 'post_removeFromGroup', 'OC\Share\Hooks', 'post_removeFromGroup');
790 90
			OC_Hook::connect('OC_User', 'post_deleteGroup', 'OC\Share\Hooks', 'post_deleteGroup');
791 90
		}
792 90
	}
793
794
	protected static function registerAutoloaderCache() {
795
		// The class loader takes an optional low-latency cache, which MUST be
796
		// namespaced. The instanceid is used for namespacing, but might be
797
		// unavailable at this point. Futhermore, it might not be possible to
798
		// generate an instanceid via \OC_Util::getInstanceId() because the
799
		// config file may not be writable. As such, we only register a class
800
		// loader cache if instanceid is available without trying to create one.
801
		$instanceId = \OC::$server->getSystemConfig()->getValue('instanceid', null);
802
		if ($instanceId) {
803
			try {
804
				$memcacheFactory = \OC::$server->getMemCacheFactory();
805
				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...
806
			} catch (\Exception $ex) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
807
			}
808
		}
809
	}
810
811
	/**
812
	 * Handle the request
813
	 */
814
	public static function handleRequest() {
815
816
		\OC::$server->getEventLogger()->start('handle_request', 'Handle request');
817
		$systemConfig = \OC::$server->getSystemConfig();
818
		// load all the classpaths from the enabled apps so they are available
819
		// in the routing files of each app
820
		OC::loadAppClassPaths();
821
822
		// Check if ownCloud is installed or in maintenance (update) mode
823
		if (!$systemConfig->getValue('installed', false)) {
824
			\OC::$server->getSession()->clear();
825
			$setupHelper = new OC\Setup(\OC::$server->getConfig(), \OC::$server->getIniWrapper(),
826
				\OC::$server->getL10N('lib'), new \OC_Defaults(), \OC::$server->getLogger(),
827
				\OC::$server->getSecureRandom());
828
			$controller = new OC\Core\Setup\Controller($setupHelper);
829
			$controller->run($_POST);
830
			exit();
831
		}
832
833
		$request = \OC::$server->getRequest()->getPathInfo();
834
		if (substr($request, -3) !== '.js') { // we need these files during the upgrade
835
			self::checkMaintenanceMode();
836
			self::checkUpgrade();
837
		}
838
839
		// Always load authentication apps
840
		OC_App::loadApps(['authentication']);
841
842
		// Load minimum set of apps
843
		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...
844
			&& !$systemConfig->getValue('maintenance', false)) {
845
			// For logged-in users: Load everything
846
			if(OC_User::isLoggedIn()) {
847
				OC_App::loadApps();
848
			} else {
849
				// For guests: Load only filesystem and logging
850
				OC_App::loadApps(array('filesystem', 'logging'));
851
				\OC_User::tryBasicAuthLogin();
852
			}
853
		}
854
855
		if (!self::$CLI and (!isset($_GET["logout"]) or ($_GET["logout"] !== 'true'))) {
856
			try {
857
				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...
858
					OC_App::loadApps(array('filesystem', 'logging'));
859
					OC_App::loadApps();
860
				}
861
				self::checkSingleUserMode();
862
				OC_Util::setupFS();
863
				OC::$server->getRouter()->match(\OC::$server->getRequest()->getRawPathInfo());
864
				return;
865
			} 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...
866
				//header('HTTP/1.0 404 Not Found');
867
			} 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...
868
				OC_Response::setStatus(405);
869
				return;
870
			}
871
		}
872
873
		// Handle redirect URL for logged in users
874
		if (isset($_REQUEST['redirect_url']) && OC_User::isLoggedIn()) {
875
			$location = \OC::$server->getURLGenerator()->getAbsoluteURL(urldecode($_REQUEST['redirect_url']));
876
877
			// Deny the redirect if the URL contains a @
878
			// This prevents unvalidated redirects like ?redirect_url=:[email protected]
879
			if (strpos($location, '@') === false) {
880
				header('Location: ' . $location);
881
				return;
882
			}
883
		}
884
		// Handle WebDAV
885
		if ($_SERVER['REQUEST_METHOD'] == 'PROPFIND') {
886
			// not allowed any more to prevent people
887
			// mounting this root directly.
888
			// Users need to mount remote.php/webdav instead.
889
			header('HTTP/1.1 405 Method Not Allowed');
890
			header('Status: 405 Method Not Allowed');
891
			return;
892
		}
893
894
		// Redirect to index if the logout link is accessed without valid session
895
		// this is needed to prevent "Token expired" messages while login if a session is expired
896
		// @see https://github.com/owncloud/core/pull/8443#issuecomment-42425583
897
		if(isset($_GET['logout']) && !OC_User::isLoggedIn()) {
898
			header("Location: " . \OC::$server->getURLGenerator()->getAbsoluteURL('/'));
899
			return;
900
		}
901
902
		// Someone is logged in
903
		if (OC_User::isLoggedIn()) {
904
			OC_App::loadApps();
905
			OC_User::setupBackends();
906
			OC_Util::setupFS();
907
			if (isset($_GET["logout"]) and ($_GET["logout"])) {
908
				OC_JSON::callCheck();
909
				if (isset($_COOKIE['oc_token'])) {
910
					\OC::$server->getConfig()->deleteUserValue(OC_User::getUser(), 'login_token', $_COOKIE['oc_token']);
911
				}
912
				OC_User::logout();
913
				// redirect to webroot and add slash if webroot is empty
914
				header("Location: " . \OC::$server->getURLGenerator()->getAbsoluteURL('/'));
915
			} else {
916
				// Redirect to default application
917
				OC_Util::redirectToDefaultPage();
918
			}
919
		} else {
920
			// Not handled and not logged in
921
			self::handleLogin();
922
		}
923
	}
924
925
	protected static function handleAuthHeaders() {
926
		//copy http auth headers for apache+php-fcgid work around
927
		if (isset($_SERVER['HTTP_XAUTHORIZATION']) && !isset($_SERVER['HTTP_AUTHORIZATION'])) {
928
			$_SERVER['HTTP_AUTHORIZATION'] = $_SERVER['HTTP_XAUTHORIZATION'];
929
		}
930
931
		// Extract PHP_AUTH_USER/PHP_AUTH_PW from other headers if necessary.
932
		$vars = array(
933
			'HTTP_AUTHORIZATION', // apache+php-cgi work around
934
			'REDIRECT_HTTP_AUTHORIZATION', // apache+php-cgi alternative
935
		);
936
		foreach ($vars as $var) {
937
			if (isset($_SERVER[$var]) && preg_match('/Basic\s+(.*)$/i', $_SERVER[$var], $matches)) {
938
				list($name, $password) = explode(':', base64_decode($matches[1]), 2);
939
				$_SERVER['PHP_AUTH_USER'] = $name;
940
				$_SERVER['PHP_AUTH_PW'] = $password;
941
				break;
942
			}
943
		}
944
	}
945
946
	protected static function handleLogin() {
947
		OC_App::loadApps(array('prelogin'));
948
		$error = array();
949
		$messages = [];
950
951
		try {
952
			// auth possible via apache module?
953
			if (OC::tryApacheAuth()) {
954
				$error[] = 'apacheauthfailed';
955
			} // remember was checked after last login
956
			elseif (OC::tryRememberLogin()) {
957
				$error[] = 'invalidcookie';
958
			} // logon via web form
959
			elseif (OC::tryFormLogin()) {
960
				$error[] = 'invalidpassword';
961
			}
962
		} catch (\OC\User\LoginException $e) {
963
			$messages[] = $e->getMessage();
964
		} catch (\Exception $ex) {
965
			\OCP\Util::logException('handleLogin', $ex);
966
			// do not disclose information. show generic error
967
			$error[] = 'internalexception';
968
		}
969
970
		OC_Util::displayLoginPage(array_unique($error), $messages);
971
	}
972
973
	/**
974
	 * Remove outdated and therefore invalid tokens for a user
975
	 * @param string $user
976
	 */
977
	protected static function cleanupLoginTokens($user) {
978
		$config = \OC::$server->getConfig();
979
		$cutoff = time() - $config->getSystemValue('remember_login_cookie_lifetime', 60 * 60 * 24 * 15);
980
		$tokens = $config->getUserKeys($user, 'login_token');
981
		foreach ($tokens as $token) {
982
			$time = $config->getUserValue($user, 'login_token', $token);
983
			if ($time < $cutoff) {
984
				$config->deleteUserValue($user, 'login_token', $token);
985
			}
986
		}
987
	}
988
989
	/**
990
	 * Try to login a user via HTTP authentication
991
	 * @return bool|void
992
	 */
993
	protected static function tryApacheAuth() {
994
		$return = OC_User::handleApacheAuth();
995
996
		// if return is true we are logged in -> redirect to the default page
997
		if ($return === true) {
998
			$_REQUEST['redirect_url'] = \OC::$server->getRequest()->getRequestUri();
999
			OC_Util::redirectToDefaultPage();
1000
			exit;
1001
		}
1002
1003
		// in case $return is null apache based auth is not enabled
1004
		return is_null($return) ? false : true;
1005
	}
1006
1007
	/**
1008
	 * Try to login a user using the remember me cookie.
1009
	 * @return bool Whether the provided cookie was valid
1010
	 */
1011
	protected static function tryRememberLogin() {
1012
		if (!isset($_COOKIE["oc_remember_login"])
1013
			|| !isset($_COOKIE["oc_token"])
1014
			|| !isset($_COOKIE["oc_username"])
1015
			|| !$_COOKIE["oc_remember_login"]
1016
			|| !OC_Util::rememberLoginAllowed()
1017
		) {
1018
			return false;
1019
		}
1020
1021
		if (\OC::$server->getConfig()->getSystemValue('debug', false)) {
1022
			\OCP\Util::writeLog('core', 'Trying to login from cookie', \OCP\Util::DEBUG);
1023
		}
1024
1025
		if(OC_User::userExists($_COOKIE['oc_username'])) {
1026
			self::cleanupLoginTokens($_COOKIE['oc_username']);
1027
			// verify whether the supplied "remember me" token was valid
1028
			$granted = OC_User::loginWithCookie(
1029
				$_COOKIE['oc_username'], $_COOKIE['oc_token']);
1030
			if($granted === true) {
1031
				OC_Util::redirectToDefaultPage();
1032
				// doesn't return
1033
			}
1034
			\OCP\Util::writeLog('core', 'Authentication cookie rejected for user ' .
1035
				$_COOKIE['oc_username'], \OCP\Util::WARN);
1036
			// if you reach this point you have changed your password
1037
			// or you are an attacker
1038
			// we can not delete tokens here because users may reach
1039
			// this point multiple times after a password change
1040
		}
1041
1042
		OC_User::unsetMagicInCookie();
1043
		return true;
1044
	}
1045
1046
	/**
1047
	 * Tries to login a user using the form based authentication
1048
	 * @return bool|void
1049
	 */
1050
	protected static function tryFormLogin() {
1051
		if (!isset($_POST["user"]) || !isset($_POST['password'])) {
1052
			return false;
1053
		}
1054
1055
		if(!(\OC::$server->getRequest()->passesCSRFCheck())) {
1056
			return false;
1057
		}
1058
		OC_App::loadApps();
1059
1060
		//setup extra user backends
1061
		OC_User::setupBackends();
1062
1063
		if (OC_User::login((string)$_POST["user"], (string)$_POST["password"])) {
1064
			$userId = OC_User::getUser();
1065
1066
			// setting up the time zone
1067
			if (isset($_POST['timezone-offset'])) {
1068
				self::$server->getSession()->set('timezone', (string)$_POST['timezone-offset']);
1069
				self::$server->getConfig()->setUserValue($userId, 'core', 'timezone', (string)$_POST['timezone']);
1070
			}
1071
1072
			self::cleanupLoginTokens($userId);
1073
			if (!empty($_POST["remember_login"])) {
1074
				$config = self::$server->getConfig();
1075
				if ($config->getSystemValue('debug', false)) {
1076
					self::$server->getLogger()->debug('Setting remember login to cookie', array('app' => 'core'));
1077
				}
1078
				$token = \OC::$server->getSecureRandom()->getMediumStrengthGenerator()->generate(32);
1079
				$config->setUserValue($userId, 'login_token', $token, time());
1080
				OC_User::setMagicInCookie($userId, $token);
1081
			} else {
1082
				OC_User::unsetMagicInCookie();
1083
			}
1084
			OC_Util::redirectToDefaultPage();
1085
			exit();
1086
		}
1087
		return true;
1088
	}
1089
1090
}
1091
1092
1093
OC::init();
1094