Completed
Push — master ( fb17f1...ff55bc )
by Blizzz
17:03
created
lib/private/Setup.php 2 patches
Indentation   +513 added lines, -513 removed lines patch added patch discarded remove patch
@@ -55,517 +55,517 @@
 block discarded – undo
55 55
 use OCP\Security\ISecureRandom;
56 56
 
57 57
 class Setup {
58
-	/** @var SystemConfig */
59
-	protected $config;
60
-	/** @var IniGetWrapper */
61
-	protected $iniWrapper;
62
-	/** @var IL10N */
63
-	protected $l10n;
64
-	/** @var Defaults */
65
-	protected $defaults;
66
-	/** @var ILogger */
67
-	protected $logger;
68
-	/** @var ISecureRandom */
69
-	protected $random;
70
-	/** @var Installer */
71
-	protected $installer;
72
-
73
-	/**
74
-	 * @param SystemConfig $config
75
-	 * @param IniGetWrapper $iniWrapper
76
-	 * @param IL10N $l10n
77
-	 * @param Defaults $defaults
78
-	 * @param ILogger $logger
79
-	 * @param ISecureRandom $random
80
-	 * @param Installer $installer
81
-	 */
82
-	public function __construct(SystemConfig $config,
83
-						 IniGetWrapper $iniWrapper,
84
-						 IL10N $l10n,
85
-						 Defaults $defaults,
86
-						 ILogger $logger,
87
-						 ISecureRandom $random,
88
-						 Installer $installer
89
-		) {
90
-		$this->config = $config;
91
-		$this->iniWrapper = $iniWrapper;
92
-		$this->l10n = $l10n;
93
-		$this->defaults = $defaults;
94
-		$this->logger = $logger;
95
-		$this->random = $random;
96
-		$this->installer = $installer;
97
-	}
98
-
99
-	static protected $dbSetupClasses = [
100
-		'mysql' => \OC\Setup\MySQL::class,
101
-		'pgsql' => \OC\Setup\PostgreSQL::class,
102
-		'oci'   => \OC\Setup\OCI::class,
103
-		'sqlite' => \OC\Setup\Sqlite::class,
104
-		'sqlite3' => \OC\Setup\Sqlite::class,
105
-	];
106
-
107
-	/**
108
-	 * Wrapper around the "class_exists" PHP function to be able to mock it
109
-	 * @param string $name
110
-	 * @return bool
111
-	 */
112
-	protected function class_exists($name) {
113
-		return class_exists($name);
114
-	}
115
-
116
-	/**
117
-	 * Wrapper around the "is_callable" PHP function to be able to mock it
118
-	 * @param string $name
119
-	 * @return bool
120
-	 */
121
-	protected function is_callable($name) {
122
-		return is_callable($name);
123
-	}
124
-
125
-	/**
126
-	 * Wrapper around \PDO::getAvailableDrivers
127
-	 *
128
-	 * @return array
129
-	 */
130
-	protected function getAvailableDbDriversForPdo() {
131
-		return \PDO::getAvailableDrivers();
132
-	}
133
-
134
-	/**
135
-	 * Get the available and supported databases of this instance
136
-	 *
137
-	 * @param bool $allowAllDatabases
138
-	 * @return array
139
-	 * @throws Exception
140
-	 */
141
-	public function getSupportedDatabases($allowAllDatabases = false) {
142
-		$availableDatabases = [
143
-			'sqlite' =>  [
144
-				'type' => 'pdo',
145
-				'call' => 'sqlite',
146
-				'name' => 'SQLite',
147
-			],
148
-			'mysql' => [
149
-				'type' => 'pdo',
150
-				'call' => 'mysql',
151
-				'name' => 'MySQL/MariaDB',
152
-			],
153
-			'pgsql' => [
154
-				'type' => 'pdo',
155
-				'call' => 'pgsql',
156
-				'name' => 'PostgreSQL',
157
-			],
158
-			'oci' => [
159
-				'type' => 'function',
160
-				'call' => 'oci_connect',
161
-				'name' => 'Oracle',
162
-			],
163
-		];
164
-		if ($allowAllDatabases) {
165
-			$configuredDatabases = array_keys($availableDatabases);
166
-		} else {
167
-			$configuredDatabases = $this->config->getValue('supportedDatabases',
168
-				['sqlite', 'mysql', 'pgsql']);
169
-		}
170
-		if(!is_array($configuredDatabases)) {
171
-			throw new Exception('Supported databases are not properly configured.');
172
-		}
173
-
174
-		$supportedDatabases = array();
175
-
176
-		foreach($configuredDatabases as $database) {
177
-			if(array_key_exists($database, $availableDatabases)) {
178
-				$working = false;
179
-				$type = $availableDatabases[$database]['type'];
180
-				$call = $availableDatabases[$database]['call'];
181
-
182
-				if ($type === 'function') {
183
-					$working = $this->is_callable($call);
184
-				} elseif($type === 'pdo') {
185
-					$working = in_array($call, $this->getAvailableDbDriversForPdo(), true);
186
-				}
187
-				if($working) {
188
-					$supportedDatabases[$database] = $availableDatabases[$database]['name'];
189
-				}
190
-			}
191
-		}
192
-
193
-		return $supportedDatabases;
194
-	}
195
-
196
-	/**
197
-	 * Gathers system information like database type and does
198
-	 * a few system checks.
199
-	 *
200
-	 * @return array of system info, including an "errors" value
201
-	 * in case of errors/warnings
202
-	 */
203
-	public function getSystemInfo($allowAllDatabases = false) {
204
-		$databases = $this->getSupportedDatabases($allowAllDatabases);
205
-
206
-		$dataDir = $this->config->getValue('datadirectory', \OC::$SERVERROOT.'/data');
207
-
208
-		$errors = [];
209
-
210
-		// Create data directory to test whether the .htaccess works
211
-		// Notice that this is not necessarily the same data directory as the one
212
-		// that will effectively be used.
213
-		if(!file_exists($dataDir)) {
214
-			@mkdir($dataDir);
215
-		}
216
-		$htAccessWorking = true;
217
-		if (is_dir($dataDir) && is_writable($dataDir)) {
218
-			// Protect data directory here, so we can test if the protection is working
219
-			self::protectDataDirectory();
220
-
221
-			try {
222
-				$util = new \OC_Util();
223
-				$htAccessWorking = $util->isHtaccessWorking(\OC::$server->getConfig());
224
-			} catch (\OC\HintException $e) {
225
-				$errors[] = [
226
-					'error' => $e->getMessage(),
227
-					'hint' => $e->getHint(),
228
-				];
229
-				$htAccessWorking = false;
230
-			}
231
-		}
232
-
233
-		if (\OC_Util::runningOnMac()) {
234
-			$errors[] = [
235
-				'error' => $this->l10n->t(
236
-					'Mac OS X is not supported and %s will not work properly on this platform. ' .
237
-					'Use it at your own risk! ',
238
-					[$this->defaults->getName()]
239
-				),
240
-				'hint' => $this->l10n->t('For the best results, please consider using a GNU/Linux server instead.'),
241
-			];
242
-		}
243
-
244
-		if($this->iniWrapper->getString('open_basedir') !== '' && PHP_INT_SIZE === 4) {
245
-			$errors[] = [
246
-				'error' => $this->l10n->t(
247
-					'It seems that this %s instance is running on a 32-bit PHP environment and the open_basedir has been configured in php.ini. ' .
248
-					'This will lead to problems with files over 4 GB and is highly discouraged.',
249
-					[$this->defaults->getName()]
250
-				),
251
-				'hint' => $this->l10n->t('Please remove the open_basedir setting within your php.ini or switch to 64-bit PHP.'),
252
-			];
253
-		}
254
-
255
-		return array(
256
-			'hasSQLite' => isset($databases['sqlite']),
257
-			'hasMySQL' => isset($databases['mysql']),
258
-			'hasPostgreSQL' => isset($databases['pgsql']),
259
-			'hasOracle' => isset($databases['oci']),
260
-			'databases' => $databases,
261
-			'directory' => $dataDir,
262
-			'htaccessWorking' => $htAccessWorking,
263
-			'errors' => $errors,
264
-		);
265
-	}
266
-
267
-	/**
268
-	 * @param $options
269
-	 * @return array
270
-	 */
271
-	public function install($options) {
272
-		$l = $this->l10n;
273
-
274
-		$error = array();
275
-		$dbType = $options['dbtype'];
276
-
277
-		if(empty($options['adminlogin'])) {
278
-			$error[] = $l->t('Set an admin username.');
279
-		}
280
-		if(empty($options['adminpass'])) {
281
-			$error[] = $l->t('Set an admin password.');
282
-		}
283
-		if(empty($options['directory'])) {
284
-			$options['directory'] = \OC::$SERVERROOT."/data";
285
-		}
286
-
287
-		if (!isset(self::$dbSetupClasses[$dbType])) {
288
-			$dbType = 'sqlite';
289
-		}
290
-
291
-		$username = htmlspecialchars_decode($options['adminlogin']);
292
-		$password = htmlspecialchars_decode($options['adminpass']);
293
-		$dataDir = htmlspecialchars_decode($options['directory']);
294
-
295
-		$class = self::$dbSetupClasses[$dbType];
296
-		/** @var \OC\Setup\AbstractDatabase $dbSetup */
297
-		$dbSetup = new $class($l, $this->config, $this->logger, $this->random);
298
-		$error = array_merge($error, $dbSetup->validate($options));
299
-
300
-		// validate the data directory
301
-		if ((!is_dir($dataDir) && !mkdir($dataDir)) || !is_writable($dataDir)) {
302
-			$error[] = $l->t("Can't create or write into the data directory %s", array($dataDir));
303
-		}
304
-
305
-		if (!empty($error)) {
306
-			return $error;
307
-		}
308
-
309
-		$request = \OC::$server->getRequest();
310
-
311
-		//no errors, good
312
-		if(isset($options['trusted_domains'])
313
-		    && is_array($options['trusted_domains'])) {
314
-			$trustedDomains = $options['trusted_domains'];
315
-		} else {
316
-			$trustedDomains = [$request->getInsecureServerHost()];
317
-		}
318
-
319
-		//use sqlite3 when available, otherwise sqlite2 will be used.
320
-		if ($dbType === 'sqlite' && class_exists('SQLite3')) {
321
-			$dbType = 'sqlite3';
322
-		}
323
-
324
-		//generate a random salt that is used to salt the local user passwords
325
-		$salt = $this->random->generate(30);
326
-		// generate a secret
327
-		$secret = $this->random->generate(48);
328
-
329
-		//write the config file
330
-		$newConfigValues = [
331
-			'passwordsalt'		=> $salt,
332
-			'secret'			=> $secret,
333
-			'trusted_domains'	=> $trustedDomains,
334
-			'datadirectory'		=> $dataDir,
335
-			'dbtype'			=> $dbType,
336
-			'version'			=> implode('.', \OCP\Util::getVersion()),
337
-		];
338
-
339
-		if ($this->config->getValue('overwrite.cli.url', null) === null) {
340
-			$newConfigValues['overwrite.cli.url'] = $request->getServerProtocol() . '://' . $request->getInsecureServerHost() . \OC::$WEBROOT;
341
-		}
342
-
343
-		$this->config->setValues($newConfigValues);
344
-
345
-		try {
346
-			$dbSetup->initialize($options);
347
-			$dbSetup->setupDatabase($username);
348
-			// apply necessary migrations
349
-			$dbSetup->runMigrations();
350
-		} catch (\OC\DatabaseSetupException $e) {
351
-			$error[] = [
352
-				'error' => $e->getMessage(),
353
-				'hint' => $e->getHint(),
354
-			];
355
-			return $error;
356
-		} catch (Exception $e) {
357
-			$error[] = [
358
-				'error' => 'Error while trying to create admin user: ' . $e->getMessage(),
359
-				'hint' => '',
360
-			];
361
-			return $error;
362
-		}
363
-
364
-		//create the user and group
365
-		$user =  null;
366
-		try {
367
-			$user = \OC::$server->getUserManager()->createUser($username, $password);
368
-			if (!$user) {
369
-				$error[] = "User <$username> could not be created.";
370
-			}
371
-		} catch(Exception $exception) {
372
-			$error[] = $exception->getMessage();
373
-		}
374
-
375
-		if (empty($error)) {
376
-			$config = \OC::$server->getConfig();
377
-			$config->setAppValue('core', 'installedat', microtime(true));
378
-			$config->setAppValue('core', 'lastupdatedat', microtime(true));
379
-			$config->setAppValue('core', 'vendor', $this->getVendor());
380
-
381
-			$group =\OC::$server->getGroupManager()->createGroup('admin');
382
-			$group->addUser($user);
383
-
384
-			// Install shipped apps and specified app bundles
385
-			Installer::installShippedApps();
386
-			$bundleFetcher = new BundleFetcher(\OC::$server->getL10N('lib'));
387
-			$defaultInstallationBundles = $bundleFetcher->getDefaultInstallationBundle();
388
-			foreach($defaultInstallationBundles as $bundle) {
389
-				try {
390
-					$this->installer->installAppBundle($bundle);
391
-				} catch (Exception $e) {}
392
-			}
393
-
394
-			// create empty file in data dir, so we can later find
395
-			// out that this is indeed an ownCloud data directory
396
-			file_put_contents($config->getSystemValue('datadirectory', \OC::$SERVERROOT.'/data').'/.ocdata', '');
397
-
398
-			// Update .htaccess files
399
-			self::updateHtaccess();
400
-			self::protectDataDirectory();
401
-
402
-			self::installBackgroundJobs();
403
-
404
-			//and we are done
405
-			$config->setSystemValue('installed', true);
406
-
407
-			// Create a session token for the newly created user
408
-			// The token provider requires a working db, so it's not injected on setup
409
-			/* @var $userSession User\Session */
410
-			$userSession = \OC::$server->getUserSession();
411
-			$defaultTokenProvider = \OC::$server->query(DefaultTokenProvider::class);
412
-			$userSession->setTokenProvider($defaultTokenProvider);
413
-			$userSession->login($username, $password);
414
-			$userSession->createSessionToken($request, $userSession->getUser()->getUID(), $username, $password);
415
-		}
416
-
417
-		return $error;
418
-	}
419
-
420
-	public static function installBackgroundJobs() {
421
-		$jobList = \OC::$server->getJobList();
422
-		$jobList->add(DefaultTokenCleanupJob::class);
423
-		$jobList->add(Rotate::class);
424
-		$jobList->add(BackgroundCleanupJob::class);
425
-	}
426
-
427
-	/**
428
-	 * @return string Absolute path to htaccess
429
-	 */
430
-	private function pathToHtaccess() {
431
-		return \OC::$SERVERROOT.'/.htaccess';
432
-	}
433
-
434
-	/**
435
-	 * Find webroot from config
436
-	 *
437
-	 * @param SystemConfig $config
438
-	 * @return string
439
-	 * @throws InvalidArgumentException when invalid value for overwrite.cli.url
440
-	 */
441
-	private static function findWebRoot(SystemConfig $config): string {
442
-		// For CLI read the value from overwrite.cli.url
443
-		if (\OC::$CLI) {
444
-			$webRoot = $config->getValue('overwrite.cli.url', '');
445
-			if ($webRoot === '') {
446
-				throw new InvalidArgumentException('overwrite.cli.url is empty');
447
-			}
448
-			$webRoot = parse_url($webRoot, PHP_URL_PATH);
449
-			if ($webRoot === null) {
450
-				throw new InvalidArgumentException('invalid value for overwrite.cli.url');
451
-			}
452
-			$webRoot = rtrim($webRoot, '/');
453
-		} else {
454
-			$webRoot = !empty(\OC::$WEBROOT) ? \OC::$WEBROOT : '/';
455
-		}
456
-
457
-		return $webRoot;
458
-	}
459
-
460
-	/**
461
-	 * Append the correct ErrorDocument path for Apache hosts
462
-	 *
463
-	 * @return bool True when success, False otherwise
464
-	 * @throws \OCP\AppFramework\QueryException
465
-	 */
466
-	public static function updateHtaccess() {
467
-		$config = \OC::$server->getSystemConfig();
468
-
469
-		try {
470
-			$webRoot = self::findWebRoot($config);
471
-		} catch (InvalidArgumentException $e) {
472
-			return false;
473
-		}
474
-
475
-		$setupHelper = new \OC\Setup(
476
-			$config,
477
-			\OC::$server->getIniWrapper(),
478
-			\OC::$server->getL10N('lib'),
479
-			\OC::$server->query(Defaults::class),
480
-			\OC::$server->getLogger(),
481
-			\OC::$server->getSecureRandom(),
482
-			\OC::$server->query(Installer::class)
483
-		);
484
-
485
-		$htaccessContent = file_get_contents($setupHelper->pathToHtaccess());
486
-		$content = "#### DO NOT CHANGE ANYTHING ABOVE THIS LINE ####\n";
487
-		$htaccessContent = explode($content, $htaccessContent, 2)[0];
488
-
489
-		//custom 403 error page
490
-		$content .= "\nErrorDocument 403 " . $webRoot . '/';
491
-
492
-		//custom 404 error page
493
-		$content .= "\nErrorDocument 404 " . $webRoot . '/';
494
-
495
-		// Add rewrite rules if the RewriteBase is configured
496
-		$rewriteBase = $config->getValue('htaccess.RewriteBase', '');
497
-		if($rewriteBase !== '') {
498
-			$content .= "\n<IfModule mod_rewrite.c>";
499
-			$content .= "\n  Options -MultiViews";
500
-			$content .= "\n  RewriteRule ^core/js/oc.js$ index.php [PT,E=PATH_INFO:$1]";
501
-			$content .= "\n  RewriteRule ^core/preview.png$ index.php [PT,E=PATH_INFO:$1]";
502
-			$content .= "\n  RewriteCond %{REQUEST_FILENAME} !\\.(css|js|svg|gif|png|html|ttf|woff|ico|jpg|jpeg)$";
503
-			$content .= "\n  RewriteCond %{REQUEST_FILENAME} !core/img/favicon.ico$";
504
-			$content .= "\n  RewriteCond %{REQUEST_FILENAME} !core/img/manifest.json$";
505
-			$content .= "\n  RewriteCond %{REQUEST_FILENAME} !/remote.php";
506
-			$content .= "\n  RewriteCond %{REQUEST_FILENAME} !/public.php";
507
-			$content .= "\n  RewriteCond %{REQUEST_FILENAME} !/cron.php";
508
-			$content .= "\n  RewriteCond %{REQUEST_FILENAME} !/core/ajax/update.php";
509
-			$content .= "\n  RewriteCond %{REQUEST_FILENAME} !/status.php";
510
-			$content .= "\n  RewriteCond %{REQUEST_FILENAME} !/ocs/v1.php";
511
-			$content .= "\n  RewriteCond %{REQUEST_FILENAME} !/ocs/v2.php";
512
-			$content .= "\n  RewriteCond %{REQUEST_FILENAME} !/robots.txt";
513
-			$content .= "\n  RewriteCond %{REQUEST_FILENAME} !/updater/";
514
-			$content .= "\n  RewriteCond %{REQUEST_FILENAME} !/ocs-provider/";
515
-			$content .= "\n  RewriteCond %{REQUEST_URI} !^/\\.well-known/(acme-challenge|pki-validation)/.*";
516
-			$content .= "\n  RewriteRule . index.php [PT,E=PATH_INFO:$1]";
517
-			$content .= "\n  RewriteBase " . $rewriteBase;
518
-			$content .= "\n  <IfModule mod_env.c>";
519
-			$content .= "\n    SetEnv front_controller_active true";
520
-			$content .= "\n    <IfModule mod_dir.c>";
521
-			$content .= "\n      DirectorySlash off";
522
-			$content .= "\n    </IfModule>";
523
-			$content .= "\n  </IfModule>";
524
-			$content .= "\n</IfModule>";
525
-		}
526
-
527
-		if ($content !== '') {
528
-			//suppress errors in case we don't have permissions for it
529
-			return (bool) @file_put_contents($setupHelper->pathToHtaccess(), $htaccessContent.$content . "\n");
530
-		}
531
-
532
-		return false;
533
-	}
534
-
535
-	public static function protectDataDirectory() {
536
-		//Require all denied
537
-		$now =  date('Y-m-d H:i:s');
538
-		$content = "# Generated by Nextcloud on $now\n";
539
-		$content.= "# line below if for Apache 2.4\n";
540
-		$content.= "<ifModule mod_authz_core.c>\n";
541
-		$content.= "Require all denied\n";
542
-		$content.= "</ifModule>\n\n";
543
-		$content.= "# line below if for Apache 2.2\n";
544
-		$content.= "<ifModule !mod_authz_core.c>\n";
545
-		$content.= "deny from all\n";
546
-		$content.= "Satisfy All\n";
547
-		$content.= "</ifModule>\n\n";
548
-		$content.= "# section for Apache 2.2 and 2.4\n";
549
-		$content.= "<ifModule mod_autoindex.c>\n";
550
-		$content.= "IndexIgnore *\n";
551
-		$content.= "</ifModule>\n";
552
-
553
-		$baseDir = \OC::$server->getConfig()->getSystemValue('datadirectory', \OC::$SERVERROOT . '/data');
554
-		file_put_contents($baseDir . '/.htaccess', $content);
555
-		file_put_contents($baseDir . '/index.html', '');
556
-	}
557
-
558
-	/**
559
-	 * Return vendor from which this version was published
560
-	 *
561
-	 * @return string Get the vendor
562
-	 *
563
-	 * Copy of \OC\Updater::getVendor()
564
-	 */
565
-	private function getVendor() {
566
-		// this should really be a JSON file
567
-		require \OC::$SERVERROOT . '/version.php';
568
-		/** @var string $vendor */
569
-		return (string) $vendor;
570
-	}
58
+    /** @var SystemConfig */
59
+    protected $config;
60
+    /** @var IniGetWrapper */
61
+    protected $iniWrapper;
62
+    /** @var IL10N */
63
+    protected $l10n;
64
+    /** @var Defaults */
65
+    protected $defaults;
66
+    /** @var ILogger */
67
+    protected $logger;
68
+    /** @var ISecureRandom */
69
+    protected $random;
70
+    /** @var Installer */
71
+    protected $installer;
72
+
73
+    /**
74
+     * @param SystemConfig $config
75
+     * @param IniGetWrapper $iniWrapper
76
+     * @param IL10N $l10n
77
+     * @param Defaults $defaults
78
+     * @param ILogger $logger
79
+     * @param ISecureRandom $random
80
+     * @param Installer $installer
81
+     */
82
+    public function __construct(SystemConfig $config,
83
+                            IniGetWrapper $iniWrapper,
84
+                            IL10N $l10n,
85
+                            Defaults $defaults,
86
+                            ILogger $logger,
87
+                            ISecureRandom $random,
88
+                            Installer $installer
89
+        ) {
90
+        $this->config = $config;
91
+        $this->iniWrapper = $iniWrapper;
92
+        $this->l10n = $l10n;
93
+        $this->defaults = $defaults;
94
+        $this->logger = $logger;
95
+        $this->random = $random;
96
+        $this->installer = $installer;
97
+    }
98
+
99
+    static protected $dbSetupClasses = [
100
+        'mysql' => \OC\Setup\MySQL::class,
101
+        'pgsql' => \OC\Setup\PostgreSQL::class,
102
+        'oci'   => \OC\Setup\OCI::class,
103
+        'sqlite' => \OC\Setup\Sqlite::class,
104
+        'sqlite3' => \OC\Setup\Sqlite::class,
105
+    ];
106
+
107
+    /**
108
+     * Wrapper around the "class_exists" PHP function to be able to mock it
109
+     * @param string $name
110
+     * @return bool
111
+     */
112
+    protected function class_exists($name) {
113
+        return class_exists($name);
114
+    }
115
+
116
+    /**
117
+     * Wrapper around the "is_callable" PHP function to be able to mock it
118
+     * @param string $name
119
+     * @return bool
120
+     */
121
+    protected function is_callable($name) {
122
+        return is_callable($name);
123
+    }
124
+
125
+    /**
126
+     * Wrapper around \PDO::getAvailableDrivers
127
+     *
128
+     * @return array
129
+     */
130
+    protected function getAvailableDbDriversForPdo() {
131
+        return \PDO::getAvailableDrivers();
132
+    }
133
+
134
+    /**
135
+     * Get the available and supported databases of this instance
136
+     *
137
+     * @param bool $allowAllDatabases
138
+     * @return array
139
+     * @throws Exception
140
+     */
141
+    public function getSupportedDatabases($allowAllDatabases = false) {
142
+        $availableDatabases = [
143
+            'sqlite' =>  [
144
+                'type' => 'pdo',
145
+                'call' => 'sqlite',
146
+                'name' => 'SQLite',
147
+            ],
148
+            'mysql' => [
149
+                'type' => 'pdo',
150
+                'call' => 'mysql',
151
+                'name' => 'MySQL/MariaDB',
152
+            ],
153
+            'pgsql' => [
154
+                'type' => 'pdo',
155
+                'call' => 'pgsql',
156
+                'name' => 'PostgreSQL',
157
+            ],
158
+            'oci' => [
159
+                'type' => 'function',
160
+                'call' => 'oci_connect',
161
+                'name' => 'Oracle',
162
+            ],
163
+        ];
164
+        if ($allowAllDatabases) {
165
+            $configuredDatabases = array_keys($availableDatabases);
166
+        } else {
167
+            $configuredDatabases = $this->config->getValue('supportedDatabases',
168
+                ['sqlite', 'mysql', 'pgsql']);
169
+        }
170
+        if(!is_array($configuredDatabases)) {
171
+            throw new Exception('Supported databases are not properly configured.');
172
+        }
173
+
174
+        $supportedDatabases = array();
175
+
176
+        foreach($configuredDatabases as $database) {
177
+            if(array_key_exists($database, $availableDatabases)) {
178
+                $working = false;
179
+                $type = $availableDatabases[$database]['type'];
180
+                $call = $availableDatabases[$database]['call'];
181
+
182
+                if ($type === 'function') {
183
+                    $working = $this->is_callable($call);
184
+                } elseif($type === 'pdo') {
185
+                    $working = in_array($call, $this->getAvailableDbDriversForPdo(), true);
186
+                }
187
+                if($working) {
188
+                    $supportedDatabases[$database] = $availableDatabases[$database]['name'];
189
+                }
190
+            }
191
+        }
192
+
193
+        return $supportedDatabases;
194
+    }
195
+
196
+    /**
197
+     * Gathers system information like database type and does
198
+     * a few system checks.
199
+     *
200
+     * @return array of system info, including an "errors" value
201
+     * in case of errors/warnings
202
+     */
203
+    public function getSystemInfo($allowAllDatabases = false) {
204
+        $databases = $this->getSupportedDatabases($allowAllDatabases);
205
+
206
+        $dataDir = $this->config->getValue('datadirectory', \OC::$SERVERROOT.'/data');
207
+
208
+        $errors = [];
209
+
210
+        // Create data directory to test whether the .htaccess works
211
+        // Notice that this is not necessarily the same data directory as the one
212
+        // that will effectively be used.
213
+        if(!file_exists($dataDir)) {
214
+            @mkdir($dataDir);
215
+        }
216
+        $htAccessWorking = true;
217
+        if (is_dir($dataDir) && is_writable($dataDir)) {
218
+            // Protect data directory here, so we can test if the protection is working
219
+            self::protectDataDirectory();
220
+
221
+            try {
222
+                $util = new \OC_Util();
223
+                $htAccessWorking = $util->isHtaccessWorking(\OC::$server->getConfig());
224
+            } catch (\OC\HintException $e) {
225
+                $errors[] = [
226
+                    'error' => $e->getMessage(),
227
+                    'hint' => $e->getHint(),
228
+                ];
229
+                $htAccessWorking = false;
230
+            }
231
+        }
232
+
233
+        if (\OC_Util::runningOnMac()) {
234
+            $errors[] = [
235
+                'error' => $this->l10n->t(
236
+                    'Mac OS X is not supported and %s will not work properly on this platform. ' .
237
+                    'Use it at your own risk! ',
238
+                    [$this->defaults->getName()]
239
+                ),
240
+                'hint' => $this->l10n->t('For the best results, please consider using a GNU/Linux server instead.'),
241
+            ];
242
+        }
243
+
244
+        if($this->iniWrapper->getString('open_basedir') !== '' && PHP_INT_SIZE === 4) {
245
+            $errors[] = [
246
+                'error' => $this->l10n->t(
247
+                    'It seems that this %s instance is running on a 32-bit PHP environment and the open_basedir has been configured in php.ini. ' .
248
+                    'This will lead to problems with files over 4 GB and is highly discouraged.',
249
+                    [$this->defaults->getName()]
250
+                ),
251
+                'hint' => $this->l10n->t('Please remove the open_basedir setting within your php.ini or switch to 64-bit PHP.'),
252
+            ];
253
+        }
254
+
255
+        return array(
256
+            'hasSQLite' => isset($databases['sqlite']),
257
+            'hasMySQL' => isset($databases['mysql']),
258
+            'hasPostgreSQL' => isset($databases['pgsql']),
259
+            'hasOracle' => isset($databases['oci']),
260
+            'databases' => $databases,
261
+            'directory' => $dataDir,
262
+            'htaccessWorking' => $htAccessWorking,
263
+            'errors' => $errors,
264
+        );
265
+    }
266
+
267
+    /**
268
+     * @param $options
269
+     * @return array
270
+     */
271
+    public function install($options) {
272
+        $l = $this->l10n;
273
+
274
+        $error = array();
275
+        $dbType = $options['dbtype'];
276
+
277
+        if(empty($options['adminlogin'])) {
278
+            $error[] = $l->t('Set an admin username.');
279
+        }
280
+        if(empty($options['adminpass'])) {
281
+            $error[] = $l->t('Set an admin password.');
282
+        }
283
+        if(empty($options['directory'])) {
284
+            $options['directory'] = \OC::$SERVERROOT."/data";
285
+        }
286
+
287
+        if (!isset(self::$dbSetupClasses[$dbType])) {
288
+            $dbType = 'sqlite';
289
+        }
290
+
291
+        $username = htmlspecialchars_decode($options['adminlogin']);
292
+        $password = htmlspecialchars_decode($options['adminpass']);
293
+        $dataDir = htmlspecialchars_decode($options['directory']);
294
+
295
+        $class = self::$dbSetupClasses[$dbType];
296
+        /** @var \OC\Setup\AbstractDatabase $dbSetup */
297
+        $dbSetup = new $class($l, $this->config, $this->logger, $this->random);
298
+        $error = array_merge($error, $dbSetup->validate($options));
299
+
300
+        // validate the data directory
301
+        if ((!is_dir($dataDir) && !mkdir($dataDir)) || !is_writable($dataDir)) {
302
+            $error[] = $l->t("Can't create or write into the data directory %s", array($dataDir));
303
+        }
304
+
305
+        if (!empty($error)) {
306
+            return $error;
307
+        }
308
+
309
+        $request = \OC::$server->getRequest();
310
+
311
+        //no errors, good
312
+        if(isset($options['trusted_domains'])
313
+            && is_array($options['trusted_domains'])) {
314
+            $trustedDomains = $options['trusted_domains'];
315
+        } else {
316
+            $trustedDomains = [$request->getInsecureServerHost()];
317
+        }
318
+
319
+        //use sqlite3 when available, otherwise sqlite2 will be used.
320
+        if ($dbType === 'sqlite' && class_exists('SQLite3')) {
321
+            $dbType = 'sqlite3';
322
+        }
323
+
324
+        //generate a random salt that is used to salt the local user passwords
325
+        $salt = $this->random->generate(30);
326
+        // generate a secret
327
+        $secret = $this->random->generate(48);
328
+
329
+        //write the config file
330
+        $newConfigValues = [
331
+            'passwordsalt'		=> $salt,
332
+            'secret'			=> $secret,
333
+            'trusted_domains'	=> $trustedDomains,
334
+            'datadirectory'		=> $dataDir,
335
+            'dbtype'			=> $dbType,
336
+            'version'			=> implode('.', \OCP\Util::getVersion()),
337
+        ];
338
+
339
+        if ($this->config->getValue('overwrite.cli.url', null) === null) {
340
+            $newConfigValues['overwrite.cli.url'] = $request->getServerProtocol() . '://' . $request->getInsecureServerHost() . \OC::$WEBROOT;
341
+        }
342
+
343
+        $this->config->setValues($newConfigValues);
344
+
345
+        try {
346
+            $dbSetup->initialize($options);
347
+            $dbSetup->setupDatabase($username);
348
+            // apply necessary migrations
349
+            $dbSetup->runMigrations();
350
+        } catch (\OC\DatabaseSetupException $e) {
351
+            $error[] = [
352
+                'error' => $e->getMessage(),
353
+                'hint' => $e->getHint(),
354
+            ];
355
+            return $error;
356
+        } catch (Exception $e) {
357
+            $error[] = [
358
+                'error' => 'Error while trying to create admin user: ' . $e->getMessage(),
359
+                'hint' => '',
360
+            ];
361
+            return $error;
362
+        }
363
+
364
+        //create the user and group
365
+        $user =  null;
366
+        try {
367
+            $user = \OC::$server->getUserManager()->createUser($username, $password);
368
+            if (!$user) {
369
+                $error[] = "User <$username> could not be created.";
370
+            }
371
+        } catch(Exception $exception) {
372
+            $error[] = $exception->getMessage();
373
+        }
374
+
375
+        if (empty($error)) {
376
+            $config = \OC::$server->getConfig();
377
+            $config->setAppValue('core', 'installedat', microtime(true));
378
+            $config->setAppValue('core', 'lastupdatedat', microtime(true));
379
+            $config->setAppValue('core', 'vendor', $this->getVendor());
380
+
381
+            $group =\OC::$server->getGroupManager()->createGroup('admin');
382
+            $group->addUser($user);
383
+
384
+            // Install shipped apps and specified app bundles
385
+            Installer::installShippedApps();
386
+            $bundleFetcher = new BundleFetcher(\OC::$server->getL10N('lib'));
387
+            $defaultInstallationBundles = $bundleFetcher->getDefaultInstallationBundle();
388
+            foreach($defaultInstallationBundles as $bundle) {
389
+                try {
390
+                    $this->installer->installAppBundle($bundle);
391
+                } catch (Exception $e) {}
392
+            }
393
+
394
+            // create empty file in data dir, so we can later find
395
+            // out that this is indeed an ownCloud data directory
396
+            file_put_contents($config->getSystemValue('datadirectory', \OC::$SERVERROOT.'/data').'/.ocdata', '');
397
+
398
+            // Update .htaccess files
399
+            self::updateHtaccess();
400
+            self::protectDataDirectory();
401
+
402
+            self::installBackgroundJobs();
403
+
404
+            //and we are done
405
+            $config->setSystemValue('installed', true);
406
+
407
+            // Create a session token for the newly created user
408
+            // The token provider requires a working db, so it's not injected on setup
409
+            /* @var $userSession User\Session */
410
+            $userSession = \OC::$server->getUserSession();
411
+            $defaultTokenProvider = \OC::$server->query(DefaultTokenProvider::class);
412
+            $userSession->setTokenProvider($defaultTokenProvider);
413
+            $userSession->login($username, $password);
414
+            $userSession->createSessionToken($request, $userSession->getUser()->getUID(), $username, $password);
415
+        }
416
+
417
+        return $error;
418
+    }
419
+
420
+    public static function installBackgroundJobs() {
421
+        $jobList = \OC::$server->getJobList();
422
+        $jobList->add(DefaultTokenCleanupJob::class);
423
+        $jobList->add(Rotate::class);
424
+        $jobList->add(BackgroundCleanupJob::class);
425
+    }
426
+
427
+    /**
428
+     * @return string Absolute path to htaccess
429
+     */
430
+    private function pathToHtaccess() {
431
+        return \OC::$SERVERROOT.'/.htaccess';
432
+    }
433
+
434
+    /**
435
+     * Find webroot from config
436
+     *
437
+     * @param SystemConfig $config
438
+     * @return string
439
+     * @throws InvalidArgumentException when invalid value for overwrite.cli.url
440
+     */
441
+    private static function findWebRoot(SystemConfig $config): string {
442
+        // For CLI read the value from overwrite.cli.url
443
+        if (\OC::$CLI) {
444
+            $webRoot = $config->getValue('overwrite.cli.url', '');
445
+            if ($webRoot === '') {
446
+                throw new InvalidArgumentException('overwrite.cli.url is empty');
447
+            }
448
+            $webRoot = parse_url($webRoot, PHP_URL_PATH);
449
+            if ($webRoot === null) {
450
+                throw new InvalidArgumentException('invalid value for overwrite.cli.url');
451
+            }
452
+            $webRoot = rtrim($webRoot, '/');
453
+        } else {
454
+            $webRoot = !empty(\OC::$WEBROOT) ? \OC::$WEBROOT : '/';
455
+        }
456
+
457
+        return $webRoot;
458
+    }
459
+
460
+    /**
461
+     * Append the correct ErrorDocument path for Apache hosts
462
+     *
463
+     * @return bool True when success, False otherwise
464
+     * @throws \OCP\AppFramework\QueryException
465
+     */
466
+    public static function updateHtaccess() {
467
+        $config = \OC::$server->getSystemConfig();
468
+
469
+        try {
470
+            $webRoot = self::findWebRoot($config);
471
+        } catch (InvalidArgumentException $e) {
472
+            return false;
473
+        }
474
+
475
+        $setupHelper = new \OC\Setup(
476
+            $config,
477
+            \OC::$server->getIniWrapper(),
478
+            \OC::$server->getL10N('lib'),
479
+            \OC::$server->query(Defaults::class),
480
+            \OC::$server->getLogger(),
481
+            \OC::$server->getSecureRandom(),
482
+            \OC::$server->query(Installer::class)
483
+        );
484
+
485
+        $htaccessContent = file_get_contents($setupHelper->pathToHtaccess());
486
+        $content = "#### DO NOT CHANGE ANYTHING ABOVE THIS LINE ####\n";
487
+        $htaccessContent = explode($content, $htaccessContent, 2)[0];
488
+
489
+        //custom 403 error page
490
+        $content .= "\nErrorDocument 403 " . $webRoot . '/';
491
+
492
+        //custom 404 error page
493
+        $content .= "\nErrorDocument 404 " . $webRoot . '/';
494
+
495
+        // Add rewrite rules if the RewriteBase is configured
496
+        $rewriteBase = $config->getValue('htaccess.RewriteBase', '');
497
+        if($rewriteBase !== '') {
498
+            $content .= "\n<IfModule mod_rewrite.c>";
499
+            $content .= "\n  Options -MultiViews";
500
+            $content .= "\n  RewriteRule ^core/js/oc.js$ index.php [PT,E=PATH_INFO:$1]";
501
+            $content .= "\n  RewriteRule ^core/preview.png$ index.php [PT,E=PATH_INFO:$1]";
502
+            $content .= "\n  RewriteCond %{REQUEST_FILENAME} !\\.(css|js|svg|gif|png|html|ttf|woff|ico|jpg|jpeg)$";
503
+            $content .= "\n  RewriteCond %{REQUEST_FILENAME} !core/img/favicon.ico$";
504
+            $content .= "\n  RewriteCond %{REQUEST_FILENAME} !core/img/manifest.json$";
505
+            $content .= "\n  RewriteCond %{REQUEST_FILENAME} !/remote.php";
506
+            $content .= "\n  RewriteCond %{REQUEST_FILENAME} !/public.php";
507
+            $content .= "\n  RewriteCond %{REQUEST_FILENAME} !/cron.php";
508
+            $content .= "\n  RewriteCond %{REQUEST_FILENAME} !/core/ajax/update.php";
509
+            $content .= "\n  RewriteCond %{REQUEST_FILENAME} !/status.php";
510
+            $content .= "\n  RewriteCond %{REQUEST_FILENAME} !/ocs/v1.php";
511
+            $content .= "\n  RewriteCond %{REQUEST_FILENAME} !/ocs/v2.php";
512
+            $content .= "\n  RewriteCond %{REQUEST_FILENAME} !/robots.txt";
513
+            $content .= "\n  RewriteCond %{REQUEST_FILENAME} !/updater/";
514
+            $content .= "\n  RewriteCond %{REQUEST_FILENAME} !/ocs-provider/";
515
+            $content .= "\n  RewriteCond %{REQUEST_URI} !^/\\.well-known/(acme-challenge|pki-validation)/.*";
516
+            $content .= "\n  RewriteRule . index.php [PT,E=PATH_INFO:$1]";
517
+            $content .= "\n  RewriteBase " . $rewriteBase;
518
+            $content .= "\n  <IfModule mod_env.c>";
519
+            $content .= "\n    SetEnv front_controller_active true";
520
+            $content .= "\n    <IfModule mod_dir.c>";
521
+            $content .= "\n      DirectorySlash off";
522
+            $content .= "\n    </IfModule>";
523
+            $content .= "\n  </IfModule>";
524
+            $content .= "\n</IfModule>";
525
+        }
526
+
527
+        if ($content !== '') {
528
+            //suppress errors in case we don't have permissions for it
529
+            return (bool) @file_put_contents($setupHelper->pathToHtaccess(), $htaccessContent.$content . "\n");
530
+        }
531
+
532
+        return false;
533
+    }
534
+
535
+    public static function protectDataDirectory() {
536
+        //Require all denied
537
+        $now =  date('Y-m-d H:i:s');
538
+        $content = "# Generated by Nextcloud on $now\n";
539
+        $content.= "# line below if for Apache 2.4\n";
540
+        $content.= "<ifModule mod_authz_core.c>\n";
541
+        $content.= "Require all denied\n";
542
+        $content.= "</ifModule>\n\n";
543
+        $content.= "# line below if for Apache 2.2\n";
544
+        $content.= "<ifModule !mod_authz_core.c>\n";
545
+        $content.= "deny from all\n";
546
+        $content.= "Satisfy All\n";
547
+        $content.= "</ifModule>\n\n";
548
+        $content.= "# section for Apache 2.2 and 2.4\n";
549
+        $content.= "<ifModule mod_autoindex.c>\n";
550
+        $content.= "IndexIgnore *\n";
551
+        $content.= "</ifModule>\n";
552
+
553
+        $baseDir = \OC::$server->getConfig()->getSystemValue('datadirectory', \OC::$SERVERROOT . '/data');
554
+        file_put_contents($baseDir . '/.htaccess', $content);
555
+        file_put_contents($baseDir . '/index.html', '');
556
+    }
557
+
558
+    /**
559
+     * Return vendor from which this version was published
560
+     *
561
+     * @return string Get the vendor
562
+     *
563
+     * Copy of \OC\Updater::getVendor()
564
+     */
565
+    private function getVendor() {
566
+        // this should really be a JSON file
567
+        require \OC::$SERVERROOT . '/version.php';
568
+        /** @var string $vendor */
569
+        return (string) $vendor;
570
+    }
571 571
 }
Please login to merge, or discard this patch.
Spacing   +43 added lines, -43 removed lines patch added patch discarded remove patch
@@ -167,24 +167,24 @@  discard block
 block discarded – undo
167 167
 			$configuredDatabases = $this->config->getValue('supportedDatabases',
168 168
 				['sqlite', 'mysql', 'pgsql']);
169 169
 		}
170
-		if(!is_array($configuredDatabases)) {
170
+		if (!is_array($configuredDatabases)) {
171 171
 			throw new Exception('Supported databases are not properly configured.');
172 172
 		}
173 173
 
174 174
 		$supportedDatabases = array();
175 175
 
176
-		foreach($configuredDatabases as $database) {
177
-			if(array_key_exists($database, $availableDatabases)) {
176
+		foreach ($configuredDatabases as $database) {
177
+			if (array_key_exists($database, $availableDatabases)) {
178 178
 				$working = false;
179 179
 				$type = $availableDatabases[$database]['type'];
180 180
 				$call = $availableDatabases[$database]['call'];
181 181
 
182 182
 				if ($type === 'function') {
183 183
 					$working = $this->is_callable($call);
184
-				} elseif($type === 'pdo') {
184
+				} elseif ($type === 'pdo') {
185 185
 					$working = in_array($call, $this->getAvailableDbDriversForPdo(), true);
186 186
 				}
187
-				if($working) {
187
+				if ($working) {
188 188
 					$supportedDatabases[$database] = $availableDatabases[$database]['name'];
189 189
 				}
190 190
 			}
@@ -210,7 +210,7 @@  discard block
 block discarded – undo
210 210
 		// Create data directory to test whether the .htaccess works
211 211
 		// Notice that this is not necessarily the same data directory as the one
212 212
 		// that will effectively be used.
213
-		if(!file_exists($dataDir)) {
213
+		if (!file_exists($dataDir)) {
214 214
 			@mkdir($dataDir);
215 215
 		}
216 216
 		$htAccessWorking = true;
@@ -233,7 +233,7 @@  discard block
 block discarded – undo
233 233
 		if (\OC_Util::runningOnMac()) {
234 234
 			$errors[] = [
235 235
 				'error' => $this->l10n->t(
236
-					'Mac OS X is not supported and %s will not work properly on this platform. ' .
236
+					'Mac OS X is not supported and %s will not work properly on this platform. '.
237 237
 					'Use it at your own risk! ',
238 238
 					[$this->defaults->getName()]
239 239
 				),
@@ -241,10 +241,10 @@  discard block
 block discarded – undo
241 241
 			];
242 242
 		}
243 243
 
244
-		if($this->iniWrapper->getString('open_basedir') !== '' && PHP_INT_SIZE === 4) {
244
+		if ($this->iniWrapper->getString('open_basedir') !== '' && PHP_INT_SIZE === 4) {
245 245
 			$errors[] = [
246 246
 				'error' => $this->l10n->t(
247
-					'It seems that this %s instance is running on a 32-bit PHP environment and the open_basedir has been configured in php.ini. ' .
247
+					'It seems that this %s instance is running on a 32-bit PHP environment and the open_basedir has been configured in php.ini. '.
248 248
 					'This will lead to problems with files over 4 GB and is highly discouraged.',
249 249
 					[$this->defaults->getName()]
250 250
 				),
@@ -274,13 +274,13 @@  discard block
 block discarded – undo
274 274
 		$error = array();
275 275
 		$dbType = $options['dbtype'];
276 276
 
277
-		if(empty($options['adminlogin'])) {
277
+		if (empty($options['adminlogin'])) {
278 278
 			$error[] = $l->t('Set an admin username.');
279 279
 		}
280
-		if(empty($options['adminpass'])) {
280
+		if (empty($options['adminpass'])) {
281 281
 			$error[] = $l->t('Set an admin password.');
282 282
 		}
283
-		if(empty($options['directory'])) {
283
+		if (empty($options['directory'])) {
284 284
 			$options['directory'] = \OC::$SERVERROOT."/data";
285 285
 		}
286 286
 
@@ -309,7 +309,7 @@  discard block
 block discarded – undo
309 309
 		$request = \OC::$server->getRequest();
310 310
 
311 311
 		//no errors, good
312
-		if(isset($options['trusted_domains'])
312
+		if (isset($options['trusted_domains'])
313 313
 		    && is_array($options['trusted_domains'])) {
314 314
 			$trustedDomains = $options['trusted_domains'];
315 315
 		} else {
@@ -337,7 +337,7 @@  discard block
 block discarded – undo
337 337
 		];
338 338
 
339 339
 		if ($this->config->getValue('overwrite.cli.url', null) === null) {
340
-			$newConfigValues['overwrite.cli.url'] = $request->getServerProtocol() . '://' . $request->getInsecureServerHost() . \OC::$WEBROOT;
340
+			$newConfigValues['overwrite.cli.url'] = $request->getServerProtocol().'://'.$request->getInsecureServerHost().\OC::$WEBROOT;
341 341
 		}
342 342
 
343 343
 		$this->config->setValues($newConfigValues);
@@ -355,20 +355,20 @@  discard block
 block discarded – undo
355 355
 			return $error;
356 356
 		} catch (Exception $e) {
357 357
 			$error[] = [
358
-				'error' => 'Error while trying to create admin user: ' . $e->getMessage(),
358
+				'error' => 'Error while trying to create admin user: '.$e->getMessage(),
359 359
 				'hint' => '',
360 360
 			];
361 361
 			return $error;
362 362
 		}
363 363
 
364 364
 		//create the user and group
365
-		$user =  null;
365
+		$user = null;
366 366
 		try {
367 367
 			$user = \OC::$server->getUserManager()->createUser($username, $password);
368 368
 			if (!$user) {
369 369
 				$error[] = "User <$username> could not be created.";
370 370
 			}
371
-		} catch(Exception $exception) {
371
+		} catch (Exception $exception) {
372 372
 			$error[] = $exception->getMessage();
373 373
 		}
374 374
 
@@ -378,14 +378,14 @@  discard block
 block discarded – undo
378 378
 			$config->setAppValue('core', 'lastupdatedat', microtime(true));
379 379
 			$config->setAppValue('core', 'vendor', $this->getVendor());
380 380
 
381
-			$group =\OC::$server->getGroupManager()->createGroup('admin');
381
+			$group = \OC::$server->getGroupManager()->createGroup('admin');
382 382
 			$group->addUser($user);
383 383
 
384 384
 			// Install shipped apps and specified app bundles
385 385
 			Installer::installShippedApps();
386 386
 			$bundleFetcher = new BundleFetcher(\OC::$server->getL10N('lib'));
387 387
 			$defaultInstallationBundles = $bundleFetcher->getDefaultInstallationBundle();
388
-			foreach($defaultInstallationBundles as $bundle) {
388
+			foreach ($defaultInstallationBundles as $bundle) {
389 389
 				try {
390 390
 					$this->installer->installAppBundle($bundle);
391 391
 				} catch (Exception $e) {}
@@ -487,14 +487,14 @@  discard block
 block discarded – undo
487 487
 		$htaccessContent = explode($content, $htaccessContent, 2)[0];
488 488
 
489 489
 		//custom 403 error page
490
-		$content .= "\nErrorDocument 403 " . $webRoot . '/';
490
+		$content .= "\nErrorDocument 403 ".$webRoot.'/';
491 491
 
492 492
 		//custom 404 error page
493
-		$content .= "\nErrorDocument 404 " . $webRoot . '/';
493
+		$content .= "\nErrorDocument 404 ".$webRoot.'/';
494 494
 
495 495
 		// Add rewrite rules if the RewriteBase is configured
496 496
 		$rewriteBase = $config->getValue('htaccess.RewriteBase', '');
497
-		if($rewriteBase !== '') {
497
+		if ($rewriteBase !== '') {
498 498
 			$content .= "\n<IfModule mod_rewrite.c>";
499 499
 			$content .= "\n  Options -MultiViews";
500 500
 			$content .= "\n  RewriteRule ^core/js/oc.js$ index.php [PT,E=PATH_INFO:$1]";
@@ -514,7 +514,7 @@  discard block
 block discarded – undo
514 514
 			$content .= "\n  RewriteCond %{REQUEST_FILENAME} !/ocs-provider/";
515 515
 			$content .= "\n  RewriteCond %{REQUEST_URI} !^/\\.well-known/(acme-challenge|pki-validation)/.*";
516 516
 			$content .= "\n  RewriteRule . index.php [PT,E=PATH_INFO:$1]";
517
-			$content .= "\n  RewriteBase " . $rewriteBase;
517
+			$content .= "\n  RewriteBase ".$rewriteBase;
518 518
 			$content .= "\n  <IfModule mod_env.c>";
519 519
 			$content .= "\n    SetEnv front_controller_active true";
520 520
 			$content .= "\n    <IfModule mod_dir.c>";
@@ -526,7 +526,7 @@  discard block
 block discarded – undo
526 526
 
527 527
 		if ($content !== '') {
528 528
 			//suppress errors in case we don't have permissions for it
529
-			return (bool) @file_put_contents($setupHelper->pathToHtaccess(), $htaccessContent.$content . "\n");
529
+			return (bool) @file_put_contents($setupHelper->pathToHtaccess(), $htaccessContent.$content."\n");
530 530
 		}
531 531
 
532 532
 		return false;
@@ -534,25 +534,25 @@  discard block
 block discarded – undo
534 534
 
535 535
 	public static function protectDataDirectory() {
536 536
 		//Require all denied
537
-		$now =  date('Y-m-d H:i:s');
537
+		$now = date('Y-m-d H:i:s');
538 538
 		$content = "# Generated by Nextcloud on $now\n";
539
-		$content.= "# line below if for Apache 2.4\n";
540
-		$content.= "<ifModule mod_authz_core.c>\n";
541
-		$content.= "Require all denied\n";
542
-		$content.= "</ifModule>\n\n";
543
-		$content.= "# line below if for Apache 2.2\n";
544
-		$content.= "<ifModule !mod_authz_core.c>\n";
545
-		$content.= "deny from all\n";
546
-		$content.= "Satisfy All\n";
547
-		$content.= "</ifModule>\n\n";
548
-		$content.= "# section for Apache 2.2 and 2.4\n";
549
-		$content.= "<ifModule mod_autoindex.c>\n";
550
-		$content.= "IndexIgnore *\n";
551
-		$content.= "</ifModule>\n";
552
-
553
-		$baseDir = \OC::$server->getConfig()->getSystemValue('datadirectory', \OC::$SERVERROOT . '/data');
554
-		file_put_contents($baseDir . '/.htaccess', $content);
555
-		file_put_contents($baseDir . '/index.html', '');
539
+		$content .= "# line below if for Apache 2.4\n";
540
+		$content .= "<ifModule mod_authz_core.c>\n";
541
+		$content .= "Require all denied\n";
542
+		$content .= "</ifModule>\n\n";
543
+		$content .= "# line below if for Apache 2.2\n";
544
+		$content .= "<ifModule !mod_authz_core.c>\n";
545
+		$content .= "deny from all\n";
546
+		$content .= "Satisfy All\n";
547
+		$content .= "</ifModule>\n\n";
548
+		$content .= "# section for Apache 2.2 and 2.4\n";
549
+		$content .= "<ifModule mod_autoindex.c>\n";
550
+		$content .= "IndexIgnore *\n";
551
+		$content .= "</ifModule>\n";
552
+
553
+		$baseDir = \OC::$server->getConfig()->getSystemValue('datadirectory', \OC::$SERVERROOT.'/data');
554
+		file_put_contents($baseDir.'/.htaccess', $content);
555
+		file_put_contents($baseDir.'/index.html', '');
556 556
 	}
557 557
 
558 558
 	/**
@@ -564,7 +564,7 @@  discard block
 block discarded – undo
564 564
 	 */
565 565
 	private function getVendor() {
566 566
 		// this should really be a JSON file
567
-		require \OC::$SERVERROOT . '/version.php';
567
+		require \OC::$SERVERROOT.'/version.php';
568 568
 		/** @var string $vendor */
569 569
 		return (string) $vendor;
570 570
 	}
Please login to merge, or discard this patch.