aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVincent Petry <pvince81@owncloud.com>2014-03-14 13:03:18 +0100
committerVincent Petry <pvince81@owncloud.com>2014-03-14 15:36:35 +0100
commit3c46dcd7ddde403cdc89abdaabd3879fc71d39b9 (patch)
tree12d793c2951e1a0b53e03356eefdce0457c1256a
parentb92be2ef1cb59f251a6d48953f4cb8d5e0eb734f (diff)
downloadnextcloud-server-3c46dcd7ddde403cdc89abdaabd3879fc71d39b9.tar.gz
nextcloud-server-3c46dcd7ddde403cdc89abdaabd3879fc71d39b9.zip
Added .ocdata file to check for data folder validity
In environments where the data folder is mount from another partition, it is important to check that the data folder we see is actually the real one. If the mount failed for some reasons, this fix will make ownCloud temporarily unavailable instead of causing unpredictable behavior.
-rw-r--r--lib/private/setup.php4
-rw-r--r--lib/private/updater.php5
-rwxr-xr-xlib/private/util.php32
-rw-r--r--tests/lib/utilcheckserver.php108
-rw-r--r--tests/testcleanuplistener.php1
5 files changed, 146 insertions, 4 deletions
diff --git a/lib/private/setup.php b/lib/private/setup.php
index 0d5bf424b33..b1061b3a25b 100644
--- a/lib/private/setup.php
+++ b/lib/private/setup.php
@@ -106,6 +106,10 @@ class OC_Setup {
//guess what this does
OC_Installer::installShippedApps();
+ // create empty file in data dir, so we can later find
+ // out that this is indeed an ownCloud data directory
+ file_put_contents(OC_Config::getValue('datadirectory', OC::$SERVERROOT.'/data').'/.ocdata', '');
+
//create htaccess files for apache hosts
if (isset($_SERVER['SERVER_SOFTWARE']) && strstr($_SERVER['SERVER_SOFTWARE'], 'Apache')) {
self::createHtaccess();
diff --git a/lib/private/updater.php b/lib/private/updater.php
index fd2d46a1fac..2ca705193cc 100644
--- a/lib/private/updater.php
+++ b/lib/private/updater.php
@@ -105,6 +105,11 @@ class Updater extends BasicEmitter {
}
$this->emit('\OC\Updater', 'maintenanceStart');
+ // create empty file in data dir, so we can later find
+ // out that this is indeed an ownCloud data directory
+ // (in case it didn't exist before)
+ file_put_contents(\OC_Config::getValue('datadirectory', \OC::$SERVERROOT.'/data').'/.ocdata', '');
+
/*
* START CONFIG CHANGES FOR OLDER VERSIONS
*/
diff --git a/lib/private/util.php b/lib/private/util.php
index 920161949ae..75e1711b0de 100755
--- a/lib/private/util.php
+++ b/lib/private/util.php
@@ -290,13 +290,19 @@ class OC_Util {
* @return array arrays with error messages and hints
*/
public static function checkServer() {
+ $errors = array();
+ $CONFIG_DATADIRECTORY = OC_Config::getValue('datadirectory', OC::$SERVERROOT . '/data');
+
+ if (!\OC::needUpgrade() && OC_Config::getValue('installed', false)) {
+ // this check needs to be done every time
+ $errors = self::checkDataDirectoryValidity($CONFIG_DATADIRECTORY);
+ }
+
// Assume that if checkServer() succeeded before in this session, then all is fine.
if(\OC::$session->exists('checkServer_suceeded') && \OC::$session->get('checkServer_suceeded')) {
- return array();
+ return $errors;
}
- $errors = array();
-
$defaults = new \OC_Defaults();
$webServerRestart = false;
@@ -341,7 +347,6 @@ class OC_Util {
);
}
}
- $CONFIG_DATADIRECTORY = OC_Config::getValue( "datadirectory", OC::$SERVERROOT."/data" );
// Create root dir.
if(!is_dir($CONFIG_DATADIRECTORY)) {
$success=@mkdir($CONFIG_DATADIRECTORY);
@@ -541,6 +546,25 @@ class OC_Util {
}
/**
+ * Check that the data directory exists and is valid by
+ * checking the existence of the ".ocdata" file.
+ *
+ * @param string $dataDirectory data directory path
+ * @return bool true if the data directory is valid, false otherwise
+ */
+ public static function checkDataDirectoryValidity($dataDirectory) {
+ $errors = array();
+ if (!file_exists($dataDirectory.'/.ocdata')) {
+ $errors[] = array(
+ 'error' => 'Data directory (' . $dataDirectory . ') is invalid',
+ 'hint' => 'Please check that the data directory contains a file' .
+ ' ".ocdata" in its root.'
+ );
+ }
+ return $errors;
+ }
+
+ /**
* @return void
*/
public static function displayLoginPage($errors = array()) {
diff --git a/tests/lib/utilcheckserver.php b/tests/lib/utilcheckserver.php
new file mode 100644
index 00000000000..155d617c4ad
--- /dev/null
+++ b/tests/lib/utilcheckserver.php
@@ -0,0 +1,108 @@
+<?php
+/**
+ * Copyright (c) 2014 Vincent Petry <pvince81@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+/**
+ * Tests for server check functions
+ */
+class Test_Util_CheckServer extends PHPUnit_Framework_TestCase {
+
+ private $datadir;
+
+ public function setUp() {
+ $this->datadir = \OC_Config::getValue('datadirectory', \OC::$SERVERROOT . '/data');
+
+ file_put_contents($this->datadir . '/.ocdata', '');
+ }
+
+ public function tearDown() {
+ // clean up
+ @unlink($this->datadir . '/.ocdata');
+ }
+
+ /**
+ * Test that checkServer() returns no errors in the regular case.
+ */
+ public function testCheckServer() {
+ $result = \OC_Util::checkServer();
+ $this->assertEmpty($result);
+ }
+
+ /**
+ * Test that checkServer() does not check the data dir validity
+ * when the server is not installed yet (else the setup cannot
+ * be run...)
+ */
+ public function testCheckServerSkipDataDirValidityOnSetup() {
+ // simulate old version that didn't have it
+ unlink($this->datadir . '/.ocdata');
+
+ $session = \OC::$server->getSession();
+ $oldInstalled = \OC_Config::getValue('installed', false);
+
+ // simulate that the server isn't setup yet
+ \OC_Config::setValue('installed', false);
+
+ // even though ".ocdata" is missing, the error isn't
+ // triggered to allow setup to run
+ $result = \OC_Util::checkServer();
+ $this->assertEmpty($result);
+
+ // restore config
+ \OC_Config::setValue('installed', $oldInstalled);
+ }
+
+ /**
+ * Test that checkServer() does not check the data dir validity
+ * when an upgrade is required (else the upgrade cannot be
+ * performed...)
+ */
+ public function testCheckServerSkipDataDirValidityOnUpgrade() {
+ // simulate old version that didn't have it
+ unlink($this->datadir . '/.ocdata');
+
+ $session = \OC::$server->getSession();
+ $oldCurrentVersion = $session->get('OC_Version');
+ $oldInstallVersion = \OC_Config::getValue('version', '0.0.0');
+
+ // upgrade condition to simulate needUpgrade() === true
+ $session->set('OC_Version', array(6, 0, 0, 2));
+ \OC_Config::setValue('version', '6.0.0.1');
+
+ // even though ".ocdata" is missing, the error isn't
+ // triggered to allow for upgrade
+ $result = \OC_Util::checkServer();
+ $this->assertEmpty($result);
+
+ // restore versions
+ $session->set('OC_Version', $oldCurrentVersion);
+ \OC_Config::setValue('version', $oldInstallVersion);
+ }
+
+ /**
+ * Test that checkDataDirectoryValidity returns no error
+ * when ".ocdata" is present.
+ */
+ public function testCheckDataDirValidity() {
+ $result = \OC_Util::checkDataDirectoryValidity($this->datadir);
+ $this->assertEmpty($result);
+ }
+
+ /**
+ * Test that checkDataDirectoryValidity and checkServer
+ * both return an error when ".ocdata" is missing.
+ */
+ public function testCheckDataDirValidityWhenFileMissing() {
+ unlink($this->datadir . '/.ocdata');
+ $result = \OC_Util::checkDataDirectoryValidity($this->datadir);
+ $this->assertEquals(1, count($result));
+
+ $result = \OC_Util::checkServer();
+ $this->assertEquals(1, count($result));
+ }
+
+}
diff --git a/tests/testcleanuplistener.php b/tests/testcleanuplistener.php
index 299a589ef4e..2083ffce67c 100644
--- a/tests/testcleanuplistener.php
+++ b/tests/testcleanuplistener.php
@@ -83,6 +83,7 @@ class TestCleanupListener implements PHPUnit_Framework_TestListener {
$knownEntries = array(
'owncloud.log' => true,
'owncloud.db' => true,
+ '.ocdata' => true,
'..' => true,
'.' => true
);