From e4c31b362ec724f83cd2fb0205ea4321496d8d0c Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Sat, 7 Dec 2013 14:44:23 +0100 Subject: [PATCH 001/317] Add command for converting sqlite database to server based one --- core/command/db/convertfromsqlite.php | 164 ++++++++++++++++++++++++++ core/register_command.php | 1 + 2 files changed, 165 insertions(+) create mode 100644 core/command/db/convertfromsqlite.php diff --git a/core/command/db/convertfromsqlite.php b/core/command/db/convertfromsqlite.php new file mode 100644 index 00000000000..85cf1e38c18 --- /dev/null +++ b/core/command/db/convertfromsqlite.php @@ -0,0 +1,164 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + * + */ + +namespace OC\Core\Command\Db; + +use Symfony\Component\Console\Command\Command; +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Output\OutputInterface; + +class ConvertFromSqlite extends Command { + protected function configure() { + $this + ->setName('db:convert-from-sqlite') + ->setDescription('Convert the owncloud sqlite database to the newly configured one') + ->addArgument( + 'type', + InputArgument::REQUIRED, + 'the type of the database to convert to' + ) + ->addArgument( + 'username', + InputArgument::REQUIRED, + 'the username of the database to convert to' + ) + ->addArgument( + 'hostname', + InputArgument::REQUIRED, + 'the hostname of the database to convert to' + ) + ->addArgument( + 'database', + InputArgument::REQUIRED, + 'the name of the database to convert to' + ) + ->addOption( + 'port', + null, + InputOption::VALUE_REQUIRED, + 'the port of the database to convert to' + ) + ->addOption( + 'password', + null, + InputOption::VALUE_REQUIRED, + 'the password of the database to convert to. Will be asked when not specified' + ) + ; + } + + private static $type2driver = array( + 'mysql' => 'pdo_mysql', + 'pgsql' => 'pdo_pgsql', + 'oci' => 'oci8', + 'mssql' => 'pdo_sqlsrv', + ); + protected function execute(InputInterface $input, OutputInterface $output) { + // connect 'from' database + $datadir = \OC_Config::getValue( "datadirectory", \OC::$SERVERROOT.'/data' ); + $name = \OC_Config::getValue( "dbname", "owncloud" ); + $dbfile = $datadir.'/'.$name.'.db'; + $connectionParams = array( + 'path' => $dbfile, + 'driver' => 'pdo_sqlite', + ); + $fromDB = \Doctrine\DBAL\DriverManager::getConnection($connectionParams); + + // connect 'to' database + $type = $input->getArgument('type'); + $username = $input->getArgument('username'); + $hostname = $input->getArgument('hostname'); + $dbname = $input->getArgument('database'); + + if ($input->getOption('password')) { + $password = $input->getOption('password'); + } else { + // TODO: should be moved to the interact function + $dialog = $this->getHelperSet()->get('dialog'); + $password = $dialog->askHiddenResponse( + $output, + 'What is the database password?', + false + ); + } + $connectionParams = array( + 'driver' => self::$type2driver[$type], + 'user' => $username, + 'password' => $password, + 'host' => $hostname, + 'dbname' => $dbname, + ); + if ($input->getOption('port')) { + $connectionParams['port'] = $input->getOption('port'); + } + $toDB = \Doctrine\DBAL\DriverManager::getConnection($connectionParams); + + // create tables in new database + $schemaManager = new \OC\DB\MDB2SchemaManager($toDB); + $schemaManager->createDbFromStructure(\OC::$SERVERROOT.'/db_structure.xml'); + $apps = \OC_App::getEnabledApps(); + foreach($apps as $app) { + if(file_exists(\OC_App::getAppPath($app).'/appinfo/database.xml')) { + $schemaManager->createDbFromStructure(\OC_App::getAppPath($app).'/appinfo/database.xml'); + } + } + + // get tables from 'to' database + $toTables = $this->getTables($toDB); + // get tables from 'from' database + $fromTables = $this->getTables($fromDB); + // warn/fail if there are more tables in 'from' database + $tables = array_diff($fromTables, $toTables); + if (!empty($tables)) { + $output->writeln('The following tables do NOT exist any more: '.join(', ', $tables).''); + $dialog = $this->getHelperSet()->get('dialog'); + if (!$dialog->askConfirmation( + $output, + 'Continue with the convertion?', + false + )) { + return; + } + } + // copy table rows + $tables = array_intersect($toTables, $fromTables); + foreach($tables as $table) { + $output->writeln($table); + $this->copyTable($fromDB, $toDB, $table, $output); + } + } + + private function getTables($db) { + $schemaManager = $db->getSchemaManager(); + return $schemaManager->listTableNames(); + } + + private function copyTable($fromDB, $toDB, $table, $output) { + $progress = $this->getHelperSet()->get('progress'); + $query = 'SELECT COUNT(*) from '.$table; + $count = $fromDB->fetchColumn($query); + $query = 'SELECT * from '.$table; + $statement = $fromDB->executeQuery($query); + $query = 'DELETE FROM '.$table; + $toDB->executeUpdate($query); + $progress->start($output, $count); + if ($count > 100) { + $progress->setRedrawFrequency(5); + } else { + $progress->setRedrawFrequency(1); + } + while($row = $statement->fetch()) { + $progress->advance(); + $toDB->insert($table, $row); + } + $progress->finish(); + } +} \ No newline at end of file diff --git a/core/register_command.php b/core/register_command.php index e4f3b124365..419747ebb44 100644 --- a/core/register_command.php +++ b/core/register_command.php @@ -9,6 +9,7 @@ /** @var $application Symfony\Component\Console\Application */ $application->add(new OC\Core\Command\Status); $application->add(new OC\Core\Command\Db\GenerateChangeScript()); +$application->add(new OC\Core\Command\Db\ConvertFromSqlite()); $application->add(new OC\Core\Command\Upgrade()); $application->add(new OC\Core\Command\Maintenance\SingleUser()); $application->add(new OC\Core\Command\App\Disable()); -- GitLab From 22edc42f548a148b323a375ecaf82141f18bc293 Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Sat, 7 Dec 2013 15:09:36 +0100 Subject: [PATCH 002/317] Add UTF8 charset to connection params --- core/command/db/convertfromsqlite.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/core/command/db/convertfromsqlite.php b/core/command/db/convertfromsqlite.php index 85cf1e38c18..d5003edd6e9 100644 --- a/core/command/db/convertfromsqlite.php +++ b/core/command/db/convertfromsqlite.php @@ -99,6 +99,16 @@ class ConvertFromSqlite extends Command { if ($input->getOption('port')) { $connectionParams['port'] = $input->getOption('port'); } + switch ($type) { + case 'mysql': + case 'mssql': + $connectionParams['charset'] = 'UTF8'; + break; + case 'oci': + $connectionParams['charset'] = 'AL32UTF8'; + break; + } + $toDB = \Doctrine\DBAL\DriverManager::getConnection($connectionParams); // create tables in new database -- GitLab From 731e83c35a11657248f1d73c0a68e74573a1c3e8 Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Sat, 7 Dec 2013 15:14:54 +0100 Subject: [PATCH 003/317] Save the new database config --- core/command/db/convertfromsqlite.php | 28 ++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/core/command/db/convertfromsqlite.php b/core/command/db/convertfromsqlite.php index d5003edd6e9..fb11409d2c3 100644 --- a/core/command/db/convertfromsqlite.php +++ b/core/command/db/convertfromsqlite.php @@ -138,12 +138,30 @@ class ConvertFromSqlite extends Command { return; } } - // copy table rows - $tables = array_intersect($toTables, $fromTables); - foreach($tables as $table) { - $output->writeln($table); - $this->copyTable($fromDB, $toDB, $table, $output); + // enable maintenance mode to prevent changes + \OC_Config::setValue('maintenance', true); + try { + // copy table rows + $tables = array_intersect($toTables, $fromTables); + foreach($tables as $table) { + $output->writeln($table); + $this->copyTable($fromDB, $toDB, $table, $output); + } + // save new database config + $dbhost = $hostname; + if ($input->getOption('port')) { + $dbhost = $hostname.':'.$input->getOption('port'); + } + \OC_Config::setValue('dbtype', $type); + \OC_Config::setValue('dbname', $dbname); + \OC_Config::setValue('dbhost', $dbhost); + \OC_Config::setValue('dbuser', $username); + \OC_Config::setValue('dbpassword', $password); + } catch(Exception $e) { + \OC_Config::setValue('maintenance', false); + throw $e; } + \OC_Config::setValue('maintenance', false); } private function getTables($db) { -- GitLab From 202e26647e534065271db153fde7207922fa2ecd Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Tue, 24 Dec 2013 13:36:32 +0100 Subject: [PATCH 004/317] Inject config object --- core/command/db/convertfromsqlite.php | 33 +++++++++++++++++++-------- core/register_command.php | 2 +- 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/core/command/db/convertfromsqlite.php b/core/command/db/convertfromsqlite.php index fb11409d2c3..de65fe9a883 100644 --- a/core/command/db/convertfromsqlite.php +++ b/core/command/db/convertfromsqlite.php @@ -16,6 +16,19 @@ use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; class ConvertFromSqlite extends Command { + /** + * @var \OC\Config $config + */ + protected $config; + + /** + * @param \OC\Config $config + */ + public function __construct($config) { + $this->config = $config; + parent::__construct(); + } + protected function configure() { $this ->setName('db:convert-from-sqlite') @@ -63,8 +76,8 @@ class ConvertFromSqlite extends Command { ); protected function execute(InputInterface $input, OutputInterface $output) { // connect 'from' database - $datadir = \OC_Config::getValue( "datadirectory", \OC::$SERVERROOT.'/data' ); - $name = \OC_Config::getValue( "dbname", "owncloud" ); + $datadir = $this->config->getValue( "datadirectory", \OC::$SERVERROOT.'/data' ); + $name = $this->config->getValue( "dbname", "owncloud" ); $dbfile = $datadir.'/'.$name.'.db'; $connectionParams = array( 'path' => $dbfile, @@ -139,7 +152,7 @@ class ConvertFromSqlite extends Command { } } // enable maintenance mode to prevent changes - \OC_Config::setValue('maintenance', true); + $this->config->setValue('maintenance', true); try { // copy table rows $tables = array_intersect($toTables, $fromTables); @@ -152,16 +165,16 @@ class ConvertFromSqlite extends Command { if ($input->getOption('port')) { $dbhost = $hostname.':'.$input->getOption('port'); } - \OC_Config::setValue('dbtype', $type); - \OC_Config::setValue('dbname', $dbname); - \OC_Config::setValue('dbhost', $dbhost); - \OC_Config::setValue('dbuser', $username); - \OC_Config::setValue('dbpassword', $password); + $this->config->setValue('dbtype', $type); + $this->config->setValue('dbname', $dbname); + $this->config->setValue('dbhost', $dbhost); + $this->config->setValue('dbuser', $username); + $this->config->setValue('dbpassword', $password); } catch(Exception $e) { - \OC_Config::setValue('maintenance', false); + $this->config->setValue('maintenance', false); throw $e; } - \OC_Config::setValue('maintenance', false); + $this->config->setValue('maintenance', false); } private function getTables($db) { diff --git a/core/register_command.php b/core/register_command.php index 419747ebb44..350a817c02a 100644 --- a/core/register_command.php +++ b/core/register_command.php @@ -9,7 +9,7 @@ /** @var $application Symfony\Component\Console\Application */ $application->add(new OC\Core\Command\Status); $application->add(new OC\Core\Command\Db\GenerateChangeScript()); -$application->add(new OC\Core\Command\Db\ConvertFromSqlite()); +$application->add(new OC\Core\Command\Db\ConvertFromSqlite(OC_Config::getObject())); $application->add(new OC\Core\Command\Upgrade()); $application->add(new OC\Core\Command\Maintenance\SingleUser()); $application->add(new OC\Core\Command\App\Disable()); -- GitLab From 4e1a3f212f0c3f3f9e412b67b8deeec0963f15c9 Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Tue, 24 Dec 2013 13:44:35 +0100 Subject: [PATCH 005/317] Review points --- core/command/db/convertfromsqlite.php | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/core/command/db/convertfromsqlite.php b/core/command/db/convertfromsqlite.php index de65fe9a883..ed0443e9806 100644 --- a/core/command/db/convertfromsqlite.php +++ b/core/command/db/convertfromsqlite.php @@ -184,22 +184,18 @@ class ConvertFromSqlite extends Command { private function copyTable($fromDB, $toDB, $table, $output) { $progress = $this->getHelperSet()->get('progress'); - $query = 'SELECT COUNT(*) from '.$table; + $query = 'SELECT COUNT(*) FROM '.$table; $count = $fromDB->fetchColumn($query); - $query = 'SELECT * from '.$table; + $query = 'SELECT * FROM '.$table; $statement = $fromDB->executeQuery($query); $query = 'DELETE FROM '.$table; $toDB->executeUpdate($query); $progress->start($output, $count); - if ($count > 100) { - $progress->setRedrawFrequency(5); - } else { - $progress->setRedrawFrequency(1); - } + $progress->setRedrawFrequency($count > 100 ? 5 : 1); while($row = $statement->fetch()) { $progress->advance(); $toDB->insert($table, $row); } $progress->finish(); } -} \ No newline at end of file +} -- GitLab From 1b7eb4dc6cfce382c7a3192bdc8bf6fd52791de1 Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Sat, 11 Jan 2014 12:22:23 +0100 Subject: [PATCH 006/317] Quote column names on insert --- core/command/db/convertfromsqlite.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/core/command/db/convertfromsqlite.php b/core/command/db/convertfromsqlite.php index ed0443e9806..5ae54b68936 100644 --- a/core/command/db/convertfromsqlite.php +++ b/core/command/db/convertfromsqlite.php @@ -194,7 +194,11 @@ class ConvertFromSqlite extends Command { $progress->setRedrawFrequency($count > 100 ? 5 : 1); while($row = $statement->fetch()) { $progress->advance(); - $toDB->insert($table, $row); + $data = array(); + foreach ($row as $columnName => $value) { + $data[$toDB->quoteIdentifier($columnName)] = $value; + } + $toDB->insert($table, $data); } $progress->finish(); } -- GitLab From af3bedf9858b117b676c915829229fb8745a5e36 Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Sat, 11 Jan 2014 12:23:28 +0100 Subject: [PATCH 007/317] Add option to remove all the tables from the destination database --- core/command/db/convertfromsqlite.php | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/core/command/db/convertfromsqlite.php b/core/command/db/convertfromsqlite.php index 5ae54b68936..4d5122ca2d7 100644 --- a/core/command/db/convertfromsqlite.php +++ b/core/command/db/convertfromsqlite.php @@ -65,6 +65,12 @@ class ConvertFromSqlite extends Command { InputOption::VALUE_REQUIRED, 'the password of the database to convert to. Will be asked when not specified' ) + ->addOption( + 'clear-schema', + null, + InputOption::VALUE_NONE, + 'remove all tables from the destination database' + ) ; } @@ -124,7 +130,20 @@ class ConvertFromSqlite extends Command { $toDB = \Doctrine\DBAL\DriverManager::getConnection($connectionParams); + // Clearing schema in new database + if ($input->getOption('clear-schema')) { + $schemaManager = $toDB->getSchemaManager(); + $toTables = $schemaManager->listTableNames(); + if (!empty($toTables)) { + $output->writeln('Clearing schema in new database'); + } + foreach($toTables as $table) { + $schemaManager->dropTable($table); + } + } + // create tables in new database + $output->writeln('Creating schema in new database'); $schemaManager = new \OC\DB\MDB2SchemaManager($toDB); $schemaManager->createDbFromStructure(\OC::$SERVERROOT.'/db_structure.xml'); $apps = \OC_App::getEnabledApps(); @@ -188,8 +207,6 @@ class ConvertFromSqlite extends Command { $count = $fromDB->fetchColumn($query); $query = 'SELECT * FROM '.$table; $statement = $fromDB->executeQuery($query); - $query = 'DELETE FROM '.$table; - $toDB->executeUpdate($query); $progress->start($output, $count); $progress->setRedrawFrequency($count > 100 ? 5 : 1); while($row = $statement->fetch()) { -- GitLab From 2638fd47674deaeb630b87f01a46ad94446a2097 Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Sat, 11 Jan 2014 12:25:35 +0100 Subject: [PATCH 008/317] Postgresql needs the sequences adjusted after the inserts --- core/command/db/convertfromsqlite.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/core/command/db/convertfromsqlite.php b/core/command/db/convertfromsqlite.php index 4d5122ca2d7..cd3e494d7f2 100644 --- a/core/command/db/convertfromsqlite.php +++ b/core/command/db/convertfromsqlite.php @@ -179,6 +179,18 @@ class ConvertFromSqlite extends Command { $output->writeln($table); $this->copyTable($fromDB, $toDB, $table, $output); } + if ($type == 'pgsql') { + $sequences = $toDB->getSchemaManager()->listSequences(); + foreach($sequences as $sequence) { + $info = $toDB->fetchAssoc('SELECT table_schema, table_name, column_name ' + .'FROM information_schema.columns ' + .'WHERE column_default = ? AND table_catalog = ?', + array("nextval('".$sequence->getName()."'::regclass)", $dbname)); + $table_name = $info['table_name']; + $column_name = $info['column_name']; + $toDB->executeQuery("SELECT setval('" . $sequence->getName() . "', (SELECT MAX(" . $column_name . ") FROM " . $table_name . ")+1)"); + } + } // save new database config $dbhost = $hostname; if ($input->getOption('port')) { -- GitLab From 21426b7ff6c8b84ea3898aa4a95a7fd3c4376ddb Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Fri, 17 Jan 2014 14:54:13 +0100 Subject: [PATCH 009/317] Fixed doctrine code --- 3rdparty | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/3rdparty b/3rdparty index 42efd966284..b4db0b302aa 160000 --- a/3rdparty +++ b/3rdparty @@ -1 +1 @@ -Subproject commit 42efd966284debadf83b761367e529bc45f806d6 +Subproject commit b4db0b302aa8266b067012d0f862fafe70a665e0 -- GitLab From f46e66073733adba33957cc840fdaba6d0d578b1 Mon Sep 17 00:00:00 2001 From: Jan-Christoph Borchardt Date: Tue, 21 Jan 2014 17:02:59 +0100 Subject: [PATCH 010/317] do not check 'remember' log in by default --- core/templates/login.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/templates/login.php b/core/templates/login.php index e697ebe5326..cdec375c8ec 100644 --- a/core/templates/login.php +++ b/core/templates/login.php @@ -45,7 +45,7 @@ - + -- GitLab From eede20c5acb4135f96f318a4ad0a146dd562861c Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Tue, 11 Feb 2014 17:59:50 +0100 Subject: [PATCH 011/317] Check target DB type --- core/command/db/convertfromsqlite.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/core/command/db/convertfromsqlite.php b/core/command/db/convertfromsqlite.php index cd3e494d7f2..71706580382 100644 --- a/core/command/db/convertfromsqlite.php +++ b/core/command/db/convertfromsqlite.php @@ -97,6 +97,9 @@ class ConvertFromSqlite extends Command { $hostname = $input->getArgument('hostname'); $dbname = $input->getArgument('database'); + if (!isset(self::$type2driver[$type])) { + throw new InvalidArgumentException('Unknown type: '.$type); + } if ($input->getOption('password')) { $password = $input->getOption('password'); } else { -- GitLab From 3abcd13979660309f9a6d672d3dc64a7c6d784ab Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Tue, 11 Feb 2014 18:01:41 +0100 Subject: [PATCH 012/317] Allow converting from any db type --- .../db/{convertfromsqlite.php => converttype.php} | 15 ++++----------- core/register_command.php | 2 +- 2 files changed, 5 insertions(+), 12 deletions(-) rename core/command/db/{convertfromsqlite.php => converttype.php} (92%) diff --git a/core/command/db/convertfromsqlite.php b/core/command/db/converttype.php similarity index 92% rename from core/command/db/convertfromsqlite.php rename to core/command/db/converttype.php index 71706580382..38527d3d55a 100644 --- a/core/command/db/convertfromsqlite.php +++ b/core/command/db/converttype.php @@ -15,7 +15,7 @@ use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; -class ConvertFromSqlite extends Command { +class ConvertType extends Command { /** * @var \OC\Config $config */ @@ -31,8 +31,8 @@ class ConvertFromSqlite extends Command { protected function configure() { $this - ->setName('db:convert-from-sqlite') - ->setDescription('Convert the owncloud sqlite database to the newly configured one') + ->setName('db:convert-type') + ->setDescription('Convert the owncloud database to the newly configured one') ->addArgument( 'type', InputArgument::REQUIRED, @@ -82,14 +82,7 @@ class ConvertFromSqlite extends Command { ); protected function execute(InputInterface $input, OutputInterface $output) { // connect 'from' database - $datadir = $this->config->getValue( "datadirectory", \OC::$SERVERROOT.'/data' ); - $name = $this->config->getValue( "dbname", "owncloud" ); - $dbfile = $datadir.'/'.$name.'.db'; - $connectionParams = array( - 'path' => $dbfile, - 'driver' => 'pdo_sqlite', - ); - $fromDB = \Doctrine\DBAL\DriverManager::getConnection($connectionParams); + $fromDB = \OC_DB::getConnection(); // connect 'to' database $type = $input->getArgument('type'); diff --git a/core/register_command.php b/core/register_command.php index 736953094b1..a3833214c21 100644 --- a/core/register_command.php +++ b/core/register_command.php @@ -9,7 +9,7 @@ /** @var $application Symfony\Component\Console\Application */ $application->add(new OC\Core\Command\Status); $application->add(new OC\Core\Command\Db\GenerateChangeScript()); -$application->add(new OC\Core\Command\Db\ConvertFromSqlite(OC_Config::getObject())); +$application->add(new OC\Core\Command\Db\ConvertType(OC_Config::getObject())); $application->add(new OC\Core\Command\Upgrade()); $application->add(new OC\Core\Command\Maintenance\SingleUser()); $application->add(new OC\Core\Command\App\Disable()); -- GitLab From ae525d1f125483dc14858938c5056f18d63f831e Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Wed, 12 Feb 2014 17:42:55 +0100 Subject: [PATCH 013/317] Fix namespace for Exception --- core/command/db/converttype.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/command/db/converttype.php b/core/command/db/converttype.php index 38527d3d55a..5f59a6be828 100644 --- a/core/command/db/converttype.php +++ b/core/command/db/converttype.php @@ -197,7 +197,7 @@ class ConvertType extends Command { $this->config->setValue('dbhost', $dbhost); $this->config->setValue('dbuser', $username); $this->config->setValue('dbpassword', $password); - } catch(Exception $e) { + } catch(\Exception $e) { $this->config->setValue('maintenance', false); throw $e; } -- GitLab From bcb78e48b283def05d21defaf554f5ce7c578c56 Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Mon, 17 Feb 2014 18:02:58 +0100 Subject: [PATCH 014/317] Split execute function into multiple functions --- core/command/db/converttype.php | 158 ++++++++++++++++++-------------- 1 file changed, 89 insertions(+), 69 deletions(-) diff --git a/core/command/db/converttype.php b/core/command/db/converttype.php index 5f59a6be828..370ace7fd0c 100644 --- a/core/command/db/converttype.php +++ b/core/command/db/converttype.php @@ -85,6 +85,54 @@ class ConvertType extends Command { $fromDB = \OC_DB::getConnection(); // connect 'to' database + $toDB = $this->getToDBConnection($input, $output); + + // Clearing schema in new database + if ($input->getOption('clear-schema')) { + $schemaManager = $toDB->getSchemaManager(); + $toTables = $schemaManager->listTableNames(); + if (!empty($toTables)) { + $output->writeln('Clearing schema in new database'); + } + foreach($toTables as $table) { + $schemaManager->dropTable($table); + } + } + + // create tables in new database + $output->writeln('Creating schema in new database'); + $schemaManager = new \OC\DB\MDB2SchemaManager($toDB); + $schemaManager->createDbFromStructure(\OC::$SERVERROOT.'/db_structure.xml'); + $apps = \OC_App::getEnabledApps(); + foreach($apps as $app) { + if(file_exists(\OC_App::getAppPath($app).'/appinfo/database.xml')) { + $schemaManager->createDbFromStructure(\OC_App::getAppPath($app).'/appinfo/database.xml'); + } + } + + // get tables from 'to' database + $toTables = $this->getTables($toDB); + // get tables from 'from' database + $fromTables = $this->getTables($fromDB); + // warn/fail if there are more tables in 'from' database + $tables = array_diff($fromTables, $toTables); + if (!empty($tables)) { + $output->writeln('The following tables do NOT exist any more: '.join(', ', $tables).''); + $dialog = $this->getHelperSet()->get('dialog'); + if (!$dialog->askConfirmation( + $output, + 'Continue with the convertion?', + false + )) { + return; + } + } + // enable maintenance mode to prevent changes + $tables = array_intersect($toTables, $fromTables); + $this->convertDB($fromDB, $toDB, $tables, $input, $output); + } + + private function getToDBConnection($input, $output) { $type = $input->getArgument('type'); $username = $input->getArgument('username'); $hostname = $input->getArgument('hostname'); @@ -103,6 +151,7 @@ class ConvertType extends Command { 'What is the database password?', false ); + $input->setOption('password', $password); } $connectionParams = array( 'driver' => self::$type2driver[$type], @@ -124,59 +173,45 @@ class ConvertType extends Command { break; } - $toDB = \Doctrine\DBAL\DriverManager::getConnection($connectionParams); + return \Doctrine\DBAL\DriverManager::getConnection($connectionParams); + } - // Clearing schema in new database - if ($input->getOption('clear-schema')) { - $schemaManager = $toDB->getSchemaManager(); - $toTables = $schemaManager->listTableNames(); - if (!empty($toTables)) { - $output->writeln('Clearing schema in new database'); - } - foreach($toTables as $table) { - $schemaManager->dropTable($table); - } - } + private function getTables($db) { + $schemaManager = $db->getSchemaManager(); + return $schemaManager->listTableNames(); + } - // create tables in new database - $output->writeln('Creating schema in new database'); - $schemaManager = new \OC\DB\MDB2SchemaManager($toDB); - $schemaManager->createDbFromStructure(\OC::$SERVERROOT.'/db_structure.xml'); - $apps = \OC_App::getEnabledApps(); - foreach($apps as $app) { - if(file_exists(\OC_App::getAppPath($app).'/appinfo/database.xml')) { - $schemaManager->createDbFromStructure(\OC_App::getAppPath($app).'/appinfo/database.xml'); + private function copyTable($fromDB, $toDB, $table, $output) { + $progress = $this->getHelperSet()->get('progress'); + $query = 'SELECT COUNT(*) FROM '.$table; + $count = $fromDB->fetchColumn($query); + $query = 'SELECT * FROM '.$table; + $statement = $fromDB->executeQuery($query); + $progress->start($output, $count); + $progress->setRedrawFrequency($count > 100 ? 5 : 1); + while($row = $statement->fetch()) { + $progress->advance(); + $data = array(); + foreach ($row as $columnName => $value) { + $data[$toDB->quoteIdentifier($columnName)] = $value; } + $toDB->insert($table, $data); } + $progress->finish(); + } - // get tables from 'to' database - $toTables = $this->getTables($toDB); - // get tables from 'from' database - $fromTables = $this->getTables($fromDB); - // warn/fail if there are more tables in 'from' database - $tables = array_diff($fromTables, $toTables); - if (!empty($tables)) { - $output->writeln('The following tables do NOT exist any more: '.join(', ', $tables).''); - $dialog = $this->getHelperSet()->get('dialog'); - if (!$dialog->askConfirmation( - $output, - 'Continue with the convertion?', - false - )) { - return; - } - } - // enable maintenance mode to prevent changes + private function convertDB($fromDB, $toDB, $tables, $input, $output) { $this->config->setValue('maintenance', true); + $type = $input->getArgument('type'); try { // copy table rows - $tables = array_intersect($toTables, $fromTables); foreach($tables as $table) { $output->writeln($table); $this->copyTable($fromDB, $toDB, $table, $output); } if ($type == 'pgsql') { $sequences = $toDB->getSchemaManager()->listSequences(); + $dbname = $input->getArgument('database'); foreach($sequences as $sequence) { $info = $toDB->fetchAssoc('SELECT table_schema, table_name, column_name ' .'FROM information_schema.columns ' @@ -188,15 +223,7 @@ class ConvertType extends Command { } } // save new database config - $dbhost = $hostname; - if ($input->getOption('port')) { - $dbhost = $hostname.':'.$input->getOption('port'); - } - $this->config->setValue('dbtype', $type); - $this->config->setValue('dbname', $dbname); - $this->config->setValue('dbhost', $dbhost); - $this->config->setValue('dbuser', $username); - $this->config->setValue('dbpassword', $password); + $this->saveDBInfo($input); } catch(\Exception $e) { $this->config->setValue('maintenance', false); throw $e; @@ -204,27 +231,20 @@ class ConvertType extends Command { $this->config->setValue('maintenance', false); } - private function getTables($db) { - $schemaManager = $db->getSchemaManager(); - return $schemaManager->listTableNames(); - } - - private function copyTable($fromDB, $toDB, $table, $output) { - $progress = $this->getHelperSet()->get('progress'); - $query = 'SELECT COUNT(*) FROM '.$table; - $count = $fromDB->fetchColumn($query); - $query = 'SELECT * FROM '.$table; - $statement = $fromDB->executeQuery($query); - $progress->start($output, $count); - $progress->setRedrawFrequency($count > 100 ? 5 : 1); - while($row = $statement->fetch()) { - $progress->advance(); - $data = array(); - foreach ($row as $columnName => $value) { - $data[$toDB->quoteIdentifier($columnName)] = $value; - } - $toDB->insert($table, $data); + private function saveDBInfo($input) { + $type = $input->getArgument('type'); + $username = $input->getArgument('username'); + $dbhost = $input->getArgument('hostname'); + $dbname = $input->getArgument('database'); + $password = $input->getOption('password'); + if ($input->getOption('port')) { + $dbhost .= ':'.$input->getOption('port'); } - $progress->finish(); + + $this->config->setValue('dbtype', $type); + $this->config->setValue('dbname', $dbname); + $this->config->setValue('dbhost', $dbhost); + $this->config->setValue('dbuser', $username); + $this->config->setValue('dbpassword', $password); } } -- GitLab From 8a6dcdf4a47fb45d417ca1fd2aec2901c247d16f Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Mon, 17 Feb 2014 18:09:42 +0100 Subject: [PATCH 015/317] Move password interaction to interact function --- core/command/db/converttype.php | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/core/command/db/converttype.php b/core/command/db/converttype.php index 370ace7fd0c..fb45ab33113 100644 --- a/core/command/db/converttype.php +++ b/core/command/db/converttype.php @@ -29,6 +29,19 @@ class ConvertType extends Command { parent::__construct(); } + protected function interact(InputInterface $input, OutputInterface $output) { + parent::interact($input, $output); + if (!$input->getOption('password')) { + $dialog = $this->getHelperSet()->get('dialog'); + $password = $dialog->askHiddenResponse( + $output, + 'What is the database password?', + false + ); + $input->setOption('password', $password); + } + } + protected function configure() { $this ->setName('db:convert-type') @@ -137,22 +150,11 @@ class ConvertType extends Command { $username = $input->getArgument('username'); $hostname = $input->getArgument('hostname'); $dbname = $input->getArgument('database'); + $password = $input->getOption('password'); if (!isset(self::$type2driver[$type])) { throw new InvalidArgumentException('Unknown type: '.$type); } - if ($input->getOption('password')) { - $password = $input->getOption('password'); - } else { - // TODO: should be moved to the interact function - $dialog = $this->getHelperSet()->get('dialog'); - $password = $dialog->askHiddenResponse( - $output, - 'What is the database password?', - false - ); - $input->setOption('password', $password); - } $connectionParams = array( 'driver' => self::$type2driver[$type], 'user' => $username, -- GitLab From a55c56c9e7c0c78c1592f2501b527b5c977cafb7 Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Tue, 18 Feb 2014 20:20:58 +0100 Subject: [PATCH 016/317] Use the patches as proposed in doctrine/dbal --- 3rdparty | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/3rdparty b/3rdparty index 3d42b540641..62402242330 160000 --- a/3rdparty +++ b/3rdparty @@ -1 +1 @@ -Subproject commit 3d42b540641cb3f9ce563d5a4ec6b385dbaba742 +Subproject commit 624022423304280dab2cf7ed2367aa7c99ff565c -- GitLab From 6f4ecd32b37cc668ee0d59721c2451f349bb9290 Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Fri, 21 Feb 2014 22:52:48 +0100 Subject: [PATCH 017/317] Add more caching in the group manager --- lib/private/group/manager.php | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/lib/private/group/manager.php b/lib/private/group/manager.php index 9b433b64fd4..451de0c0539 100644 --- a/lib/private/group/manager.php +++ b/lib/private/group/manager.php @@ -40,7 +40,12 @@ class Manager extends PublicEmitter { /** * @var \OC\Group\Group[] */ - private $cachedGroups; + private $cachedGroups = array(); + + /** + * @var \OC\Group\Group[] + */ + private $cachedUserGroups = array(); /** * @param \OC\User\Manager $userManager @@ -141,7 +146,7 @@ class Manager extends PublicEmitter { $offset -= count($groupIds); } foreach ($groupIds as $groupId) { - $groups[$groupId] = $this->getGroupObject($groupId); + $groups[$groupId] = $this->get($groupId); } if (!is_null($limit) and $limit <= 0) { return array_values($groups); @@ -155,13 +160,18 @@ class Manager extends PublicEmitter { * @return \OC\Group\Group[] */ public function getUserGroups($user) { + $uid = $user->getUID(); + if (isset($this->cachedUserGroups[$uid])) { + return $this->cachedUserGroups[$uid]; + } $groups = array(); foreach ($this->backends as $backend) { - $groupIds = $backend->getUserGroups($user->getUID()); + $groupIds = $backend->getUserGroups($uid); foreach ($groupIds as $groupId) { - $groups[$groupId] = $this->getGroupObject($groupId); + $groups[$groupId] = $this->get($groupId); } } - return array_values($groups); + $this->cachedUserGroups[$uid] = array_values($groups); + return $this->cachedUserGroups[$uid]; } } -- GitLab From f4f72e77d8bf312b6fc693d43ef5fc831130db3b Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Fri, 21 Feb 2014 22:53:31 +0100 Subject: [PATCH 018/317] Delay fetching the display name until it is requested --- lib/private/user/user.php | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/lib/private/user/user.php b/lib/private/user/user.php index ef5364cbf7b..710f9061b53 100644 --- a/lib/private/user/user.php +++ b/lib/private/user/user.php @@ -55,11 +55,6 @@ class User { */ public function __construct($uid, $backend, $emitter = null, $config = null) { $this->uid = $uid; - if ($backend and $backend->implementsActions(OC_USER_BACKEND_GET_DISPLAYNAME)) { - $this->displayName = $backend->getDisplayName($uid); - } else { - $this->displayName = $uid; - } $this->backend = $backend; $this->emitter = $emitter; $this->config = $config; @@ -86,6 +81,13 @@ class User { * @return string */ public function getDisplayName() { + if (!isset($this->displayName)) { + if ($this->backend and $this->backend->implementsActions(OC_USER_BACKEND_GET_DISPLAYNAME)) { + $this->displayName = $this->backend->getDisplayName($this->uid); + } else { + $this->displayName = $this->uid; + } + } return $this->displayName; } -- GitLab From 1d7564dc2f4ec9e06f9047846cd6bf023a1c26ed Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Fri, 21 Feb 2014 22:58:29 +0100 Subject: [PATCH 019/317] Only check for existence of shared files when doing shared storage setup The getItemsSharedWith function also retrieves related information, resulting in work that isn't used here. --- apps/files_sharing/lib/sharedstorage.php | 2 +- lib/public/share.php | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/apps/files_sharing/lib/sharedstorage.php b/apps/files_sharing/lib/sharedstorage.php index b922654e5ec..18c8a4f42a2 100644 --- a/apps/files_sharing/lib/sharedstorage.php +++ b/apps/files_sharing/lib/sharedstorage.php @@ -394,7 +394,7 @@ class Shared extends \OC\Files\Storage\Common { public static function setup($options) { if (!\OCP\User::isLoggedIn() || \OCP\User::getUser() != $options['user'] - || \OCP\Share::getItemsSharedWith('file') + || \OCP\Share::hasFilesSharedWith() ) { $user_dir = $options['user_dir']; \OC\Files\Filesystem::mount('\OC\Files\Storage\Shared', diff --git a/lib/public/share.php b/lib/public/share.php index ebc555dba5f..8cfe7417bee 100644 --- a/lib/public/share.php +++ b/lib/public/share.php @@ -243,6 +243,29 @@ class Share { return array("users" => array_unique($shares), "public" => $publicShare); } + public static function hasFilesSharedWith() { + if (!self::isEnabled()) { + return false; + } + $shareWith = \OC_User::getUser(); + $where = 'INNER JOIN `*PREFIX*filecache` ON `file_source` = `*PREFIX*filecache`.`fileid`'; + $where .= ' WHERE `file_target` IS NOT NULL'; + $queryArgs = array(); + $where .= ' AND `share_type` IN (?,?,?)'; + $queryArgs[] = self::SHARE_TYPE_USER; + $queryArgs[] = self::SHARE_TYPE_GROUP; + $queryArgs[] = self::$shareTypeGroupUserUnique; + $userAndGroups = array_merge(array($shareWith), \OC_Group::getUserGroups($shareWith)); + $placeholders = join(',', array_fill(0, count($userAndGroups), '?')); + $where .= ' AND `share_with` IN ('.$placeholders.')'; + $queryArgs = array_merge($queryArgs, $userAndGroups); + // Don't include own group shares + $where .= ' AND `uid_owner` != ?'; + $queryArgs[] = $shareWith; + $result = \OC_DB::executeAudited('SELECT COUNT(*) FROM `*PREFIX*share` '.$where, $queryArgs); + return $result->fetchOne() > 0; + } + /** * Get the items of item type shared with the current user * @param string Item type -- GitLab From 00e27d5343dab36380129dd8d30e2699e5121079 Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Thu, 27 Feb 2014 19:12:03 +0100 Subject: [PATCH 020/317] Clear the cached user groups when a group is deleted --- lib/private/group/manager.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/private/group/manager.php b/lib/private/group/manager.php index 451de0c0539..deceb8bb929 100644 --- a/lib/private/group/manager.php +++ b/lib/private/group/manager.php @@ -52,12 +52,14 @@ class Manager extends PublicEmitter { */ public function __construct($userManager) { $this->userManager = $userManager; - $cache = & $this->cachedGroups; - $this->listen('\OC\Group', 'postDelete', function ($group) use (&$cache) { + $cachedGroups = & $this->cachedGroups; + $cachedUserGroups = & $this->cachedUserGroups; + $this->listen('\OC\Group', 'postDelete', function ($group) use (&$cachedGroups, &$cachedUserGroups) { /** * @var \OC\Group\Group $group */ - unset($cache[$group->getGID()]); + unset($cachedGroups[$group->getGID()]); + $cachedUserGroups = array(); }); } -- GitLab From cb37a2716a75013dd79f8830a6d074e5afebb767 Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Thu, 27 Feb 2014 20:09:07 +0100 Subject: [PATCH 021/317] Also clear cached UserGroup when a user is added/removed --- lib/private/group/manager.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/lib/private/group/manager.php b/lib/private/group/manager.php index deceb8bb929..151b185dbf7 100644 --- a/lib/private/group/manager.php +++ b/lib/private/group/manager.php @@ -61,6 +61,18 @@ class Manager extends PublicEmitter { unset($cachedGroups[$group->getGID()]); $cachedUserGroups = array(); }); + $this->listen('\OC\Group', 'postAddUser', function ($group) use (&$cachedUserGroups) { + /** + * @var \OC\Group\Group $group + */ + $cachedUserGroups = array(); + }); + $this->listen('\OC\Group', 'postRemoveUser', function ($group) use (&$cachedUserGroups) { + /** + * @var \OC\Group\Group $group + */ + $cachedUserGroups = array(); + }); } /** -- GitLab From 3116bede68b07efc3a3bc6c991edf191c918565b Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Thu, 27 Feb 2014 21:04:44 +0100 Subject: [PATCH 022/317] Add unit tests for getUserGroups with addUser and removeUser --- tests/lib/group/manager.php | 94 +++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) diff --git a/tests/lib/group/manager.php b/tests/lib/group/manager.php index 90f0e1b35e2..c39a7d6f33a 100644 --- a/tests/lib/group/manager.php +++ b/tests/lib/group/manager.php @@ -343,4 +343,98 @@ class Manager extends \PHPUnit_Framework_TestCase { $this->assertEquals('group1', $group1->getGID()); $this->assertEquals('group2', $group2->getGID()); } + + public function testGetUserGroupsWithAddUser() { + /** + * @var \PHPUnit_Framework_MockObject_MockObject | \OC_Group_Backend $backend + */ + $backend = $this->getMock('\OC_Group_Database'); + $expectedGroups = array(); + $backend->expects($this->any()) + ->method('getUserGroups') + ->with('user1') + ->will($this->returnCallback(function () use (&$expectedGroups) { + return $expectedGroups; + })); + $backend->expects($this->any()) + ->method('groupExists') + ->with('group1') + ->will($this->returnValue(true)); + $backend->expects($this->once()) + ->method('implementsActions') + ->will($this->returnValue(true)); + + /** + * @var \OC\User\Manager $userManager + */ + $userManager = $this->getMock('\OC\User\Manager'); + $manager = new \OC\Group\Manager($userManager); + $manager->addBackend($backend); + + // prime cache + $user1 = new User('user1', null); + $groups = $manager->getUserGroups($user1); + $this->assertEquals(array(), $groups); + + // add user + $group = $manager->get('group1'); + $group->addUser($user1); + $expectedGroups = array('group1'); + + // check result + $groups = $manager->getUserGroups($user1); + $this->assertEquals(1, count($groups)); + $group1 = $groups[0]; + $this->assertEquals('group1', $group1->getGID()); + } + + public function testGetUserGroupsWithRemoveUser() { + /** + * @var \PHPUnit_Framework_MockObject_MockObject | \OC_Group_Backend $backend + */ + $backend = $this->getMock('\OC_Group_Database'); + $expectedGroups = array('group1'); + $backend->expects($this->any()) + ->method('getUserGroups') + ->with('user1') + ->will($this->returnCallback(function () use (&$expectedGroups) { + return $expectedGroups; + })); + $backend->expects($this->any()) + ->method('groupExists') + ->with('group1') + ->will($this->returnValue(true)); + $backend->expects($this->once()) + ->method('implementsActions') + ->will($this->returnValue(true)); + $backend->expects($this->once()) + ->method('inGroup') + ->will($this->returnValue(true)); + $backend->expects($this->once()) + ->method('removeFromGroup') + ->will($this->returnValue(true)); + + /** + * @var \OC\User\Manager $userManager + */ + $userManager = $this->getMock('\OC\User\Manager'); + $manager = new \OC\Group\Manager($userManager); + $manager->addBackend($backend); + + // prime cache + $user1 = new User('user1', null); + $groups = $manager->getUserGroups($user1); + $this->assertEquals(1, count($groups)); + $group1 = $groups[0]; + $this->assertEquals('group1', $group1->getGID()); + + // remove user + $group = $manager->get('group1'); + $group->removeUser($user1); + $expectedGroups = array(); + + // check result + $groups = $manager->getUserGroups($user1); + $this->assertEquals(array(), $groups); + } } -- GitLab From 47d70da2f5cb55ad47023b061b68062dd8b8d8e2 Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Fri, 28 Feb 2014 09:29:20 +0100 Subject: [PATCH 023/317] Use limit=1 so the db can stop searching on the first hit --- lib/public/share.php | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/lib/public/share.php b/lib/public/share.php index 8cfe7417bee..cc4bfb67bde 100644 --- a/lib/public/share.php +++ b/lib/public/share.php @@ -243,6 +243,10 @@ class Share { return array("users" => array_unique($shares), "public" => $publicShare); } + /** + * Check if the current user has files shared with + * @return boolean + */ public static function hasFilesSharedWith() { if (!self::isEnabled()) { return false; @@ -262,8 +266,11 @@ class Share { // Don't include own group shares $where .= ' AND `uid_owner` != ?'; $queryArgs[] = $shareWith; - $result = \OC_DB::executeAudited('SELECT COUNT(*) FROM `*PREFIX*share` '.$where, $queryArgs); - return $result->fetchOne() > 0; + $result = \OC_DB::executeAudited(array( + 'sql' => 'SELECT * FROM `*PREFIX*share` '.$where, + 'limit' => 1, + ), $queryArgs); + return (bool)$result->fetchOne(); } /** -- GitLab From 357fdb1a4df64864b2394d097b855fded1ce4756 Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Fri, 28 Feb 2014 11:59:30 +0100 Subject: [PATCH 024/317] Remove .htaccess creation code 1. We're maintaining the same code twice which leads inevitably to problems as this one. The createHtaccess routine is only used to use the correct paths to the 404 and 403 document. 2. Updating the ownCloud instance as described in our documentation (`Delete everything from your ownCloud installation directory, except data and config.`) will break the links to the ErrorDocuments anyways and show the default error handlers if ownCloud is not installed in the root directory. --- .htaccess | 2 -- lib/private/setup.php | 54 ++++++----------------------------------- lib/private/updater.php | 6 +++++ version.php | 2 +- 4 files changed, 15 insertions(+), 49 deletions(-) mode change 100755 => 100644 .htaccess diff --git a/.htaccess b/.htaccess old mode 100755 new mode 100644 index 4ba5095e144..e1ded52dcd9 --- a/.htaccess +++ b/.htaccess @@ -6,8 +6,6 @@ RequestHeader set XAuthorization %{XAUTHORIZATION}e env=XAUTHORIZATION -ErrorDocument 403 /core/templates/403.php -ErrorDocument 404 /core/templates/404.php php_value upload_max_filesize 513M php_value post_max_size 513M diff --git a/lib/private/setup.php b/lib/private/setup.php index 3906204bda3..25e536543f4 100644 --- a/lib/private/setup.php +++ b/lib/private/setup.php @@ -106,9 +106,10 @@ class OC_Setup { //guess what this does OC_Installer::installShippedApps(); - //create htaccess files for apache hosts + // Update htaccess files for apache hosts if (isset($_SERVER['SERVER_SOFTWARE']) && strstr($_SERVER['SERVER_SOFTWARE'], 'Apache')) { - self::createHtaccess(); + self::updateHtaccess(); + self::protectDataDirectory(); } //and we are done @@ -119,52 +120,13 @@ class OC_Setup { } /** - * create .htaccess files for apache hosts + * Append the correct ErrorDocument path for Apache hosts */ - private static function createHtaccess() { - $content = "\n"; - $content.= "\n"; - $content.= "\n"; - $content.= "SetEnvIfNoCase ^Authorization$ \"(.+)\" XAUTHORIZATION=$1\n"; - $content.= "RequestHeader set XAuthorization %{XAUTHORIZATION}e env=XAUTHORIZATION\n"; - $content.= "\n"; - $content.= "\n"; - $content.= "\n"; + public static function updateHtaccess() { + $content.= "\n"; $content.= "ErrorDocument 403 ".OC::$WEBROOT."/core/templates/403.php\n";//custom 403 error page - $content.= "ErrorDocument 404 ".OC::$WEBROOT."/core/templates/404.php\n";//custom 404 error page - $content.= "\n"; - $content.= "php_value upload_max_filesize 512M\n";//upload limit - $content.= "php_value post_max_size 512M\n"; - $content.= "php_value memory_limit 512M\n"; - $content.= "php_value mbstring.func_overload 0\n"; - $content.= "\n"; - $content.= " SetEnv htaccessWorking true\n"; - $content.= "\n"; - $content.= "\n"; - $content.= "\n"; - $content.= "RewriteEngine on\n"; - $content.= "RewriteRule .* - [env=HTTP_AUTHORIZATION:%{HTTP:Authorization}]\n"; - $content.= "RewriteRule ^.well-known/host-meta /public.php?service=host-meta [QSA,L]\n"; - $content.= "RewriteRule ^.well-known/carddav /remote.php/carddav/ [R]\n"; - $content.= "RewriteRule ^.well-known/caldav /remote.php/caldav/ [R]\n"; - $content.= "RewriteRule ^apps/([^/]*)/(.*\.(css|php))$ index.php?app=$1&getfile=$2 [QSA,L]\n"; - $content.= "RewriteRule ^remote/(.*) remote.php [QSA,L]\n"; - $content.= "\n"; - $content.= "\n"; - $content.= "AddType image/svg+xml svg svgz\n"; - $content.= "AddEncoding gzip svgz\n"; - $content.= "\n"; - $content.= "\n"; - $content.= "DirectoryIndex index.php index.html\n"; - $content.= "\n"; - $content.= "AddDefaultCharset utf-8\n"; - $content.= "Options -Indexes\n"; - $content.= "\n"; - $content.= "ModPagespeed Off\n"; - $content.= "\n"; - @file_put_contents(OC::$SERVERROOT.'/.htaccess', $content); //supress errors in case we don't have permissions for it - - self::protectDataDirectory(); + $content.= "ErrorDocument 404 ".OC::$WEBROOT."/core/templates/404.php";//custom 404 error page + @file_put_contents(OC::$SERVERROOT.'/.htaccess', $content, FILE_APPEND); //supress errors in case we don't have permissions for it } public static function protectDataDirectory() { diff --git a/lib/private/updater.php b/lib/private/updater.php index f05d5038b76..67764771fd0 100644 --- a/lib/private/updater.php +++ b/lib/private/updater.php @@ -92,6 +92,7 @@ class Updater extends BasicEmitter { /** * runs the update actions in maintenance mode, does not upgrade the source files + * except the main .htaccess file */ public function upgrade() { \OC_DB::enableCaching(false); @@ -103,6 +104,11 @@ class Updater extends BasicEmitter { } $this->emit('\OC\Updater', 'maintenanceStart'); + // Update htaccess files for apache hosts + if (isset($_SERVER['SERVER_SOFTWARE']) && strstr($_SERVER['SERVER_SOFTWARE'], 'Apache')) { + \OC_Setup::updateHtaccess(); + } + /* * START CONFIG CHANGES FOR OLDER VERSIONS */ diff --git a/version.php b/version.php index 470aa895072..5e5fa22cf8b 100644 --- a/version.php +++ b/version.php @@ -1,7 +1,7 @@ Date: Fri, 28 Feb 2014 13:32:09 +0100 Subject: [PATCH 025/317] Typo + use regular assignment --- lib/private/setup.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/private/setup.php b/lib/private/setup.php index 25e536543f4..65f295ee347 100644 --- a/lib/private/setup.php +++ b/lib/private/setup.php @@ -123,10 +123,10 @@ class OC_Setup { * Append the correct ErrorDocument path for Apache hosts */ public static function updateHtaccess() { - $content.= "\n"; + $content = "\n"; $content.= "ErrorDocument 403 ".OC::$WEBROOT."/core/templates/403.php\n";//custom 403 error page $content.= "ErrorDocument 404 ".OC::$WEBROOT."/core/templates/404.php";//custom 404 error page - @file_put_contents(OC::$SERVERROOT.'/.htaccess', $content, FILE_APPEND); //supress errors in case we don't have permissions for it + @file_put_contents(OC::$SERVERROOT.'/.htaccess', $content, FILE_APPEND); //suppress errors in case we don't have permissions for it } public static function protectDataDirectory() { -- GitLab From 229e3dcba86db3bd91bbddd78079bf340edff710 Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Fri, 28 Feb 2014 13:35:53 +0100 Subject: [PATCH 026/317] A version bump is not necessary here --- version.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.php b/version.php index 5e5fa22cf8b..470aa895072 100644 --- a/version.php +++ b/version.php @@ -1,7 +1,7 @@ Date: Wed, 5 Mar 2014 00:26:06 +0100 Subject: [PATCH 027/317] Yet another cleanup --- lib/private/tags.php | 53 ++++++++++++++++++++++++++------------------ tests/lib/tags.php | 2 +- 2 files changed, 33 insertions(+), 22 deletions(-) diff --git a/lib/private/tags.php b/lib/private/tags.php index 06550068f76..2e786e3fd7b 100644 --- a/lib/private/tags.php +++ b/lib/private/tags.php @@ -121,21 +121,7 @@ class Tags implements \OCP\ITags { * @return boolean. */ public function isEmpty() { - $sql = 'SELECT COUNT(*) FROM `' . self::TAG_TABLE . '` ' - . 'WHERE `uid` = ? AND `type` = ?'; - try { - $stmt = \OCP\DB::prepare($sql); - $result = $stmt->execute(array($this->user, $this->type)); - if (\OCP\DB::isError($result)) { - \OCP\Util::writeLog('core', __METHOD__. ', DB error: ' . \OCP\DB::getErrorMessage($result), \OCP\Util::ERROR); - return false; - } - return ((int)$result->fetchOne() === 0); - } catch(\Exception $e) { - \OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(), - \OCP\Util::ERROR); - return false; - } + return count($this->tags) === 0; } /** @@ -184,6 +170,10 @@ class Tags implements \OCP\ITags { $tagId = $tag; } elseif(is_string($tag)) { $tag = trim($tag); + if($tag === '') { + \OCP\Util::writeLog('core', __METHOD__.', Cannot use empty tag names', \OCP\Util::DEBUG); + return false; + } $tagId = $this->array_searchi($tag, $this->tags); } @@ -234,11 +224,15 @@ class Tags implements \OCP\ITags { * Add a new tag. * * @param string $name A string with a name of the tag - * @return false|string the id of the added tag or false if it already exists. + * @return false|string the id of the added tag or false on error. */ public function add($name) { $name = trim($name); + if($name === '') { + \OCP\Util::writeLog('core', __METHOD__.', Cannot add an empty tag', \OCP\Util::DEBUG); + return false; + } if($this->hasTag($name)) { \OCP\Util::writeLog('core', __METHOD__.', name: ' . $name. ' exists already', \OCP\Util::DEBUG); return false; @@ -280,6 +274,12 @@ class Tags implements \OCP\ITags { public function rename($from, $to) { $from = trim($from); $to = trim($to); + + if($to === '' || $from === '') { + \OCP\Util::writeLog('core', __METHOD__.', Cannot use empty tag names', \OCP\Util::DEBUG); + return false; + } + $id = $this->array_searchi($from, $this->tags); if($id === false) { \OCP\Util::writeLog('core', __METHOD__.', tag: ' . $from. ' does not exist', \OCP\Util::DEBUG); @@ -318,6 +318,8 @@ class Tags implements \OCP\ITags { $names = array($names); } $names = array_map('trim', $names); + array_filter($names); + $newones = array(); foreach($names as $name) { if(($this->in_arrayi( @@ -492,9 +494,9 @@ class Tags implements \OCP\ITags { */ public function addToFavorites($objid) { if(!$this->hasTag(self::TAG_FAVORITE)) { - $this->add(self::TAG_FAVORITE, true); + $this->add(self::TAG_FAVORITE); } - return $this->tagAs($objid, self::TAG_FAVORITE, $this->type); + return $this->tagAs($objid, self::TAG_FAVORITE); } /** @@ -504,7 +506,7 @@ class Tags implements \OCP\ITags { * @return boolean */ public function removeFromFavorites($objid) { - return $this->unTag($objid, self::TAG_FAVORITE, $this->type); + return $this->unTag($objid, self::TAG_FAVORITE); } /** @@ -512,13 +514,17 @@ class Tags implements \OCP\ITags { * * @param int $objid The id of the object * @param string $tag The id or name of the tag - * @return boolean Returns false on database error. + * @return boolean Returns false on error. */ public function tagAs($objid, $tag) { if(is_string($tag) && !is_numeric($tag)) { $tag = trim($tag); + if($tag === '') { + \OCP\Util::writeLog('core', __METHOD__.', Cannot add an empty tag', \OCP\Util::DEBUG); + return false; + } if(!$this->hasTag($tag)) { - $this->add($tag, true); + $this->add($tag); } $tagId = $this->array_searchi($tag, $this->tags); } else { @@ -549,6 +555,10 @@ class Tags implements \OCP\ITags { public function unTag($objid, $tag) { if(is_string($tag) && !is_numeric($tag)) { $tag = trim($tag); + if($tag === '') { + \OCP\Util::writeLog('core', __METHOD__.', Tag name is empty', \OCP\Util::DEBUG); + return false; + } $tagId = $this->array_searchi($tag, $this->tags); } else { $tagId = $tag; @@ -579,6 +589,7 @@ class Tags implements \OCP\ITags { } $names = array_map('trim', $names); + array_filter($names); \OCP\Util::writeLog('core', __METHOD__ . ', before: ' . print_r($this->tags, true), \OCP\Util::DEBUG); diff --git a/tests/lib/tags.php b/tests/lib/tags.php index 97e3734cfda..976b4b4fdc8 100644 --- a/tests/lib/tags.php +++ b/tests/lib/tags.php @@ -130,7 +130,7 @@ class Test_Tags extends PHPUnit_Framework_TestCase { $tagger = $this->tagMgr->load($this->objectType); foreach($objids as $id) { - $tagger->tagAs($id, 'Family'); + $this->assertTrue($tagger->tagAs($id, 'Family')); } $this->assertEquals(1, count($tagger->getTags())); -- GitLab From e768ead82096b4ad885dd15388691e39bb2c55fc Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Mon, 31 Mar 2014 17:06:02 +0200 Subject: [PATCH 028/317] Remove whitespace at end of lines. --- core/command/db/converttype.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/command/db/converttype.php b/core/command/db/converttype.php index fb45ab33113..1f3e296acc2 100644 --- a/core/command/db/converttype.php +++ b/core/command/db/converttype.php @@ -4,7 +4,7 @@ * This file is licensed under the Affero General Public License version 3 or * later. * See the COPYING-README file. - * + * */ namespace OC\Core\Command\Db; -- GitLab From b002f11771317d2098a9d93758ce7c442a76c203 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Mon, 31 Mar 2014 17:06:06 +0200 Subject: [PATCH 029/317] Use question color. --- core/command/db/converttype.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/command/db/converttype.php b/core/command/db/converttype.php index 1f3e296acc2..8b9c72d9039 100644 --- a/core/command/db/converttype.php +++ b/core/command/db/converttype.php @@ -35,7 +35,7 @@ class ConvertType extends Command { $dialog = $this->getHelperSet()->get('dialog'); $password = $dialog->askHiddenResponse( $output, - 'What is the database password?', + 'What is the database password?', false ); $input->setOption('password', $password); -- GitLab From 5dbbe6d08b6046777e20761057725f24f841e722 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Mon, 31 Mar 2014 18:20:04 +0200 Subject: [PATCH 030/317] Doc blocks for properties do not repeat the property name. --- core/command/db/converttype.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/command/db/converttype.php b/core/command/db/converttype.php index 8b9c72d9039..99f2807feee 100644 --- a/core/command/db/converttype.php +++ b/core/command/db/converttype.php @@ -17,7 +17,7 @@ use Symfony\Component\Console\Output\OutputInterface; class ConvertType extends Command { /** - * @var \OC\Config $config + * @var \OC\Config */ protected $config; -- GitLab From e67cf99cef596da7db5171730523e110a1a055d0 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Mon, 31 Mar 2014 18:20:24 +0200 Subject: [PATCH 031/317] \InvalidArgumentException is in root namespace. --- core/command/db/converttype.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/command/db/converttype.php b/core/command/db/converttype.php index 99f2807feee..b445378783a 100644 --- a/core/command/db/converttype.php +++ b/core/command/db/converttype.php @@ -153,7 +153,7 @@ class ConvertType extends Command { $password = $input->getOption('password'); if (!isset(self::$type2driver[$type])) { - throw new InvalidArgumentException('Unknown type: '.$type); + throw new \InvalidArgumentException('Unknown type: '.$type); } $connectionParams = array( 'driver' => self::$type2driver[$type], -- GitLab From a585cec5303a7b3d361559f73bba154fcbe0c978 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Mon, 31 Mar 2014 19:27:18 +0200 Subject: [PATCH 032/317] Remove unnecessary and incorrect comments. --- core/command/db/converttype.php | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/core/command/db/converttype.php b/core/command/db/converttype.php index b445378783a..387f873adb6 100644 --- a/core/command/db/converttype.php +++ b/core/command/db/converttype.php @@ -94,13 +94,9 @@ class ConvertType extends Command { 'mssql' => 'pdo_sqlsrv', ); protected function execute(InputInterface $input, OutputInterface $output) { - // connect 'from' database $fromDB = \OC_DB::getConnection(); - - // connect 'to' database $toDB = $this->getToDBConnection($input, $output); - // Clearing schema in new database if ($input->getOption('clear-schema')) { $schemaManager = $toDB->getSchemaManager(); $toTables = $schemaManager->listTableNames(); @@ -112,7 +108,6 @@ class ConvertType extends Command { } } - // create tables in new database $output->writeln('Creating schema in new database'); $schemaManager = new \OC\DB\MDB2SchemaManager($toDB); $schemaManager->createDbFromStructure(\OC::$SERVERROOT.'/db_structure.xml'); @@ -123,10 +118,9 @@ class ConvertType extends Command { } } - // get tables from 'to' database $toTables = $this->getTables($toDB); - // get tables from 'from' database $fromTables = $this->getTables($fromDB); + // warn/fail if there are more tables in 'from' database $tables = array_diff($fromTables, $toTables); if (!empty($tables)) { @@ -140,7 +134,6 @@ class ConvertType extends Command { return; } } - // enable maintenance mode to prevent changes $tables = array_intersect($toTables, $fromTables); $this->convertDB($fromDB, $toDB, $tables, $input, $output); } -- GitLab From f9853b253c6ecb9a77a9d1c9006c5f548cdfd04e Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Mon, 31 Mar 2014 20:00:44 +0200 Subject: [PATCH 033/317] Deduplicate connection handling code into \OC\DB\ConnectionFactory --- core/command/db/converttype.php | 45 +++------ core/register_command.php | 2 +- lib/private/db.php | 139 ++++++++------------------- lib/private/db/connectionfactory.php | 117 ++++++++++++++++++++++ 4 files changed, 173 insertions(+), 130 deletions(-) create mode 100644 lib/private/db/connectionfactory.php diff --git a/core/command/db/converttype.php b/core/command/db/converttype.php index 387f873adb6..2a4e6747e65 100644 --- a/core/command/db/converttype.php +++ b/core/command/db/converttype.php @@ -21,11 +21,18 @@ class ConvertType extends Command { */ protected $config; + /** + * @var \OC\DB\ConnectionFactory + */ + protected $connectionFactory; + /** * @param \OC\Config $config + * @param \OC\DB\ConnectionFactory $connectionFactory */ - public function __construct($config) { + public function __construct($config, $connectionFactory) { $this->config = $config; + $this->connectionFactory = $connectionFactory; parent::__construct(); } @@ -87,12 +94,6 @@ class ConvertType extends Command { ; } - private static $type2driver = array( - 'mysql' => 'pdo_mysql', - 'pgsql' => 'pdo_pgsql', - 'oci' => 'oci8', - 'mssql' => 'pdo_sqlsrv', - ); protected function execute(InputInterface $input, OutputInterface $output) { $fromDB = \OC_DB::getConnection(); $toDB = $this->getToDBConnection($input, $output); @@ -140,35 +141,17 @@ class ConvertType extends Command { private function getToDBConnection($input, $output) { $type = $input->getArgument('type'); - $username = $input->getArgument('username'); - $hostname = $input->getArgument('hostname'); - $dbname = $input->getArgument('database'); - $password = $input->getOption('password'); - - if (!isset(self::$type2driver[$type])) { - throw new \InvalidArgumentException('Unknown type: '.$type); - } $connectionParams = array( - 'driver' => self::$type2driver[$type], - 'user' => $username, - 'password' => $password, - 'host' => $hostname, - 'dbname' => $dbname, + 'host' => $input->getArgument('hostname'), + 'user' => $input->getArgument('username'), + 'password' => $input->getOption('password'), + 'dbname' => $input->getArgument('database'), + 'tablePrefix' => $this->config->getValue('dbtableprefix', 'oc_'), ); if ($input->getOption('port')) { $connectionParams['port'] = $input->getOption('port'); } - switch ($type) { - case 'mysql': - case 'mssql': - $connectionParams['charset'] = 'UTF8'; - break; - case 'oci': - $connectionParams['charset'] = 'AL32UTF8'; - break; - } - - return \Doctrine\DBAL\DriverManager::getConnection($connectionParams); + return $this->connectionFactory->getConnection($type, $connectionParams); } private function getTables($db) { diff --git a/core/register_command.php b/core/register_command.php index a3833214c21..f1361c859fc 100644 --- a/core/register_command.php +++ b/core/register_command.php @@ -9,7 +9,7 @@ /** @var $application Symfony\Component\Console\Application */ $application->add(new OC\Core\Command\Status); $application->add(new OC\Core\Command\Db\GenerateChangeScript()); -$application->add(new OC\Core\Command\Db\ConvertType(OC_Config::getObject())); +$application->add(new OC\Core\Command\Db\ConvertType(OC_Config::getObject(), new \OC\DB\ConnectionFactory())); $application->add(new OC\Core\Command\Upgrade()); $application->add(new OC\Core\Command\Maintenance\SingleUser()); $application->add(new OC\Core\Command\App\Disable()); diff --git a/lib/private/db.php b/lib/private/db.php index cfdac766bff..11532d9fa54 100644 --- a/lib/private/db.php +++ b/lib/private/db.php @@ -72,102 +72,45 @@ class OC_DB { $port=false; } - // do nothing if the connection already has been established - if (!self::$connection) { - $config = new \Doctrine\DBAL\Configuration(); - $eventManager = new \Doctrine\Common\EventManager(); - switch($type) { - case 'sqlite': - case 'sqlite3': - $datadir=OC_Config::getValue( "datadirectory", OC::$SERVERROOT.'/data' ); - $connectionParams = array( - 'user' => $user, - 'password' => $pass, - 'path' => $datadir.'/'.$name.'.db', - 'driver' => 'pdo_sqlite', - ); - $connectionParams['adapter'] = '\OC\DB\AdapterSqlite'; - $connectionParams['wrapperClass'] = 'OC\DB\Connection'; - break; - case 'mysql': - $connectionParams = array( - 'user' => $user, - 'password' => $pass, - 'host' => $host, - 'port' => $port, - 'dbname' => $name, - 'charset' => 'UTF8', - 'driver' => 'pdo_mysql', - ); - $connectionParams['adapter'] = '\OC\DB\Adapter'; - $connectionParams['wrapperClass'] = 'OC\DB\Connection'; - // Send "SET NAMES utf8". Only required on PHP 5.3 below 5.3.6. - // See http://stackoverflow.com/questions/4361459/php-pdo-charset-set-names#4361485 - $eventManager->addEventSubscriber(new \Doctrine\DBAL\Event\Listeners\MysqlSessionInit); - break; - case 'pgsql': - $connectionParams = array( - 'user' => $user, - 'password' => $pass, - 'host' => $host, - 'port' => $port, - 'dbname' => $name, - 'driver' => 'pdo_pgsql', - ); - $connectionParams['adapter'] = '\OC\DB\AdapterPgSql'; - $connectionParams['wrapperClass'] = 'OC\DB\Connection'; - break; - case 'oci': - $connectionParams = array( - 'user' => $user, - 'password' => $pass, - 'host' => $host, - 'dbname' => $name, - 'charset' => 'AL32UTF8', - 'driver' => 'oci8', - ); - if (!empty($port)) { - $connectionParams['port'] = $port; - } - $connectionParams['adapter'] = '\OC\DB\AdapterOCI8'; - $connectionParams['wrapperClass'] = 'OC\DB\OracleConnection'; - $eventManager->addEventSubscriber(new \Doctrine\DBAL\Event\Listeners\OracleSessionInit); - break; - case 'mssql': - $connectionParams = array( - 'user' => $user, - 'password' => $pass, - 'host' => $host, - 'port' => $port, - 'dbname' => $name, - 'charset' => 'UTF8', - 'driver' => 'pdo_sqlsrv', - ); - $connectionParams['adapter'] = '\OC\DB\AdapterSQLSrv'; - $connectionParams['wrapperClass'] = 'OC\DB\Connection'; - break; - default: - return false; - } - $connectionParams['tablePrefix'] = OC_Config::getValue('dbtableprefix', 'oc_' ); - try { - self::$connection = \Doctrine\DBAL\DriverManager::getConnection($connectionParams, $config, $eventManager); - if ($type === 'sqlite' || $type === 'sqlite3') { - // Sqlite doesn't handle query caching and schema changes - // TODO: find a better way to handle this - self::$connection->disableQueryStatementCaching(); - } - } catch(\Doctrine\DBAL\DBALException $e) { - OC_Log::write('core', $e->getMessage(), OC_Log::FATAL); - OC_User::setUserId(null); - - // send http status 503 - header('HTTP/1.1 503 Service Temporarily Unavailable'); - header('Status: 503 Service Temporarily Unavailable'); - OC_Template::printErrorPage('Failed to connect to database'); - die(); + $factory = new \OC\DB\ConnectionFactory(); + if (!$factory->isValidType($type)) { + return false; + } + + if ($factory->normalizeType($type) === 'sqlite3') { + $datadir = OC_Config::getValue("datadirectory", OC::$SERVERROOT.'/data'); + $connectionParams = array( + 'user' => $user, + 'password' => $pass, + 'path' => $datadir.'/'.$name.'.db', + ); + } else { + $connectionParams = array( + 'user' => $user, + 'password' => $pass, + 'host' => $host, + 'dbname' => $name, + ); + if (!empty($port)) { + $connectionParams['port'] = $port; } } + + $connectionParams['tablePrefix'] = OC_Config::getValue('dbtableprefix', 'oc_'); + + try { + self::$connection = $factory->getConnection($type, $connectionParams); + } catch(\Doctrine\DBAL\DBALException $e) { + OC_Log::write('core', $e->getMessage(), OC_Log::FATAL); + OC_User::setUserId(null); + + // send http status 503 + header('HTTP/1.1 503 Service Temporarily Unavailable'); + header('Status: 503 Service Temporarily Unavailable'); + OC_Template::printErrorPage('Failed to connect to database'); + die(); + } + return true; } @@ -202,12 +145,12 @@ class OC_DB { */ static public function prepare( $query , $limit = null, $offset = null, $isManipulation = null) { self::connect(); - + if ($isManipulation === null) { //try to guess, so we return the number of rows on manipulations $isManipulation = self::isManipulation($query); } - + // return the result try { $result = self::$connection->prepare($query, $limit, $offset); @@ -222,7 +165,7 @@ class OC_DB { /** * tries to guess the type of statement based on the first 10 characters * the current check allows some whitespace but does not work with IF EXISTS or other more complex statements - * + * * @param string $sql * @return bool */ @@ -245,7 +188,7 @@ class OC_DB { } return false; } - + /** * @brief execute a prepared statement, on error write log and throw exception * @param mixed $stmt OC_DB_StatementWrapper, diff --git a/lib/private/db/connectionfactory.php b/lib/private/db/connectionfactory.php new file mode 100644 index 00000000000..14ffe1a4a56 --- /dev/null +++ b/lib/private/db/connectionfactory.php @@ -0,0 +1,117 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OC\DB; + +/** +* Takes care of creating and configurating Doctrine connections. +*/ +class ConnectionFactory { + /** + * @var array + * + * Array mapping DBMS type to default connection parameters passed to + * \Doctrine\DBAL\DriverManager::getConnection(). + */ + protected $defaultConnectionParams = array( + 'mssql' => array( + 'adapter' => '\OC\DB\AdapterSQLSrv', + 'charset' => 'UTF8', + 'driver' => 'pdo_sqlsrv', + 'wrapperClass' => 'OC\DB\Connection', + ), + 'mysql' => array( + 'adapter' => '\OC\DB\Adapter', + 'charset' => 'UTF8', + 'driver' => 'pdo_mysql', + 'wrapperClass' => 'OC\DB\Connection', + ), + 'oci' => array( + 'adapter' => '\OC\DB\AdapterOCI8', + 'charset' => 'AL32UTF8', + 'driver' => 'oci8', + 'wrapperClass' => 'OC\DB\OracleConnection', + ), + 'pgsql' => array( + 'adapter' => '\OC\DB\AdapterPgSql', + 'driver' => 'pdo_pgsql', + 'wrapperClass' => 'OC\DB\Connection', + ), + 'sqlite3' => array( + 'adapter' => '\OC\DB\AdapterSqlite', + 'driver' => 'pdo_sqlite', + 'wrapperClass' => 'OC\DB\Connection', + ), + ); + + /** + * @brief Get default connection parameters for a given DBMS. + * @param string $type DBMS type + * @throws \InvalidArgumentException If $type is invalid + * @return array Default connection parameters. + */ + public function getDefaultConnectionParams($type) { + $normalizedType = $this->normalizeType($type); + if (!isset($this->defaultConnectionParams[$normalizedType])) { + throw new \InvalidArgumentException("Unsupported type: $type"); + } + return $this->defaultConnectionParams[$normalizedType]; + } + + /** + * @brief Get default connection parameters for a given DBMS. + * @param string $type DBMS type + * @param array $additionalConnectionParams Additional connection parameters + * @return \OC\DB\Connection + */ + public function getConnection($type, $additionalConnectionParams) { + $normalizedType = $this->normalizeType($type); + $eventManager = new \Doctrine\Common\EventManager(); + switch ($normalizedType) { + case 'mysql': + // Send "SET NAMES utf8". Only required on PHP 5.3 below 5.3.6. + // See http://stackoverflow.com/questions/4361459/php-pdo-charset-set-names#4361485 + $eventManager->addEventSubscriber(new \Doctrine\DBAL\Event\Listeners\MysqlSessionInit); + break; + case 'oci': + $eventManager->addEventSubscriber(new \Doctrine\DBAL\Event\Listeners\OracleSessionInit); + break; + } + $connection = \Doctrine\DBAL\DriverManager::getConnection( + array_merge($this->getDefaultConnectionParams($type), $additionalConnectionParams), + new \Doctrine\DBAL\Configuration(), + $eventManager + ); + switch ($normalizedType) { + case 'sqlite3': + // Sqlite doesn't handle query caching and schema changes + // TODO: find a better way to handle this + $connection->disableQueryStatementCaching(); + break; + } + return $connection; + } + + /** + * @brief Normalize DBMS type + * @param string $type DBMS type + * @return string Normalized DBMS type + */ + public function normalizeType($type) { + return $type === 'sqlite' ? 'sqlite3' : $type; + } + + /** + * @brief Checks whether the specififed DBMS type is valid. + * @return bool + */ + public function isValidType($type) { + $normalizedType = $this->normalizeType($type); + return isset($this->defaultConnectionParams[$normalizedType]); + } +} -- GitLab From b39a74ff6cc951e8334462ee08728b0d270d6f3a Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Mon, 31 Mar 2014 20:51:30 +0200 Subject: [PATCH 034/317] Some more colors. --- core/command/db/converttype.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/command/db/converttype.php b/core/command/db/converttype.php index 2a4e6747e65..464a5db3cdf 100644 --- a/core/command/db/converttype.php +++ b/core/command/db/converttype.php @@ -102,14 +102,14 @@ class ConvertType extends Command { $schemaManager = $toDB->getSchemaManager(); $toTables = $schemaManager->listTableNames(); if (!empty($toTables)) { - $output->writeln('Clearing schema in new database'); + $output->writeln('Clearing schema in new database'); } foreach($toTables as $table) { $schemaManager->dropTable($table); } } - $output->writeln('Creating schema in new database'); + $output->writeln('Creating schema in new database'); $schemaManager = new \OC\DB\MDB2SchemaManager($toDB); $schemaManager->createDbFromStructure(\OC::$SERVERROOT.'/db_structure.xml'); $apps = \OC_App::getEnabledApps(); -- GitLab From 01141e1520bb10c0fe915f1e86d5814004b57277 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Mon, 31 Mar 2014 21:07:48 +0200 Subject: [PATCH 035/317] Type hinting. --- core/command/db/converttype.php | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/core/command/db/converttype.php b/core/command/db/converttype.php index 464a5db3cdf..c38270d1536 100644 --- a/core/command/db/converttype.php +++ b/core/command/db/converttype.php @@ -9,6 +9,10 @@ namespace OC\Core\Command\Db; +use OC\Config; +use OC\DB\Connection; +use OC\DB\ConnectionFactory; + use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; @@ -30,7 +34,7 @@ class ConvertType extends Command { * @param \OC\Config $config * @param \OC\DB\ConnectionFactory $connectionFactory */ - public function __construct($config, $connectionFactory) { + public function __construct(Config $config, ConnectionFactory $connectionFactory) { $this->config = $config; $this->connectionFactory = $connectionFactory; parent::__construct(); @@ -139,7 +143,7 @@ class ConvertType extends Command { $this->convertDB($fromDB, $toDB, $tables, $input, $output); } - private function getToDBConnection($input, $output) { + private function getToDBConnection(InputInterface $input, OutputInterface $output) { $type = $input->getArgument('type'); $connectionParams = array( 'host' => $input->getArgument('hostname'), @@ -154,12 +158,12 @@ class ConvertType extends Command { return $this->connectionFactory->getConnection($type, $connectionParams); } - private function getTables($db) { + private function getTables(Connection $db) { $schemaManager = $db->getSchemaManager(); return $schemaManager->listTableNames(); } - private function copyTable($fromDB, $toDB, $table, $output) { + private function copyTable(Connection $fromDB, Connection $toDB, $table, OutputInterface $output) { $progress = $this->getHelperSet()->get('progress'); $query = 'SELECT COUNT(*) FROM '.$table; $count = $fromDB->fetchColumn($query); @@ -178,7 +182,7 @@ class ConvertType extends Command { $progress->finish(); } - private function convertDB($fromDB, $toDB, $tables, $input, $output) { + private function convertDB(Connection $fromDB, Connection $toDB, array $tables, InputInterface $input, OutputInterface $output) { $this->config->setValue('maintenance', true); $type = $input->getArgument('type'); try { @@ -209,7 +213,7 @@ class ConvertType extends Command { $this->config->setValue('maintenance', false); } - private function saveDBInfo($input) { + private function saveDBInfo(InputInterface $input) { $type = $input->getArgument('type'); $username = $input->getArgument('username'); $dbhost = $input->getArgument('hostname'); -- GitLab From 5b64a27df9c3f6c64db307753a70515b7123eb5b Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Mon, 31 Mar 2014 21:09:54 +0200 Subject: [PATCH 036/317] Undo 3rdparty update. --- 3rdparty | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/3rdparty b/3rdparty index 62402242330..da3c9f651a2 160000 --- a/3rdparty +++ b/3rdparty @@ -1 +1 @@ -Subproject commit 624022423304280dab2cf7ed2367aa7c99ff565c +Subproject commit da3c9f651a26cf076249ebf25c477e3791e69ca3 -- GitLab From 86ab1cf476ab03d3c3e64ab9603bc1b6a1f27be5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Tue, 1 Apr 2014 22:17:31 +0200 Subject: [PATCH 037/317] typos fixed PHPDoc comments added --- core/command/db/converttype.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/core/command/db/converttype.php b/core/command/db/converttype.php index c38270d1536..d419ca61a8b 100644 --- a/core/command/db/converttype.php +++ b/core/command/db/converttype.php @@ -43,6 +43,7 @@ class ConvertType extends Command { protected function interact(InputInterface $input, OutputInterface $output) { parent::interact($input, $output); if (!$input->getOption('password')) { + /** @var $dialog \Symfony\Component\Console\Helper\DialogHelper */ $dialog = $this->getHelperSet()->get('dialog'); $password = $dialog->askHiddenResponse( $output, @@ -56,7 +57,7 @@ class ConvertType extends Command { protected function configure() { $this ->setName('db:convert-type') - ->setDescription('Convert the owncloud database to the newly configured one') + ->setDescription('Convert the ownCloud database to the newly configured one') ->addArgument( 'type', InputArgument::REQUIRED, @@ -130,10 +131,11 @@ class ConvertType extends Command { $tables = array_diff($fromTables, $toTables); if (!empty($tables)) { $output->writeln('The following tables do NOT exist any more: '.join(', ', $tables).''); + /** @var $dialog \Symfony\Component\Console\Helper\DialogHelper */ $dialog = $this->getHelperSet()->get('dialog'); if (!$dialog->askConfirmation( $output, - 'Continue with the convertion?', + 'Continue with the conversion?', false )) { return; @@ -164,6 +166,7 @@ class ConvertType extends Command { } private function copyTable(Connection $fromDB, Connection $toDB, $table, OutputInterface $output) { + /** @var $progress \Symfony\Component\Console\Helper\ProgressHelper */ $progress = $this->getHelperSet()->get('progress'); $query = 'SELECT COUNT(*) FROM '.$table; $count = $fromDB->fetchColumn($query); -- GitLab From 7cdb16979a6c7e75b71dd8c7c5b39b6482041fb8 Mon Sep 17 00:00:00 2001 From: Fabian Henze Date: Thu, 3 Apr 2014 01:17:28 +0200 Subject: [PATCH 038/317] Fix setting the max-upload-size for really large values. php can only parse filesize units up to gigabytes, not terabytes or petabytes. --- lib/private/files.php | 4 +--- lib/private/helper.php | 26 ++++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/lib/private/files.php b/lib/private/files.php index bfe6d3c02da..46cb85a6302 100644 --- a/lib/private/files.php +++ b/lib/private/files.php @@ -280,9 +280,7 @@ class OC_Files { return false; $size -= 1; } else { - $size = OC_Helper::humanFileSize($size); - $size = substr($size, 0, -1); //strip the B - $size = str_replace(' ', '', $size); //remove the space between the size and the postfix + $size = OC_Helper::phpFileSize($size); } //don't allow user to break his config -- broken or malicious size input diff --git a/lib/private/helper.php b/lib/private/helper.php index d7ac0b5f4fa..5cd1fbacce7 100644 --- a/lib/private/helper.php +++ b/lib/private/helper.php @@ -305,6 +305,32 @@ class OC_Helper { return "$bytes PB"; } + /** + * @brief Make a php file size + * @param int $bytes file size in bytes + * @return string a php parseable file size + * + * Makes 2048 to 2k and 2^41 to 2048G + */ + public static function phpFileSize($bytes) { + if ($bytes < 0) { + return "?"; + } + if ($bytes < 1024) { + return $bytes . "B"; + } + $bytes = round($bytes / 1024, 1); + if ($bytes < 1024) { + return $bytes . "K"; + } + $bytes = round($bytes / 1024, 1); + if ($bytes < 1024) { + return $bytes . "M"; + } + $bytes = round($bytes / 1024, 1); + return $bytes . "G"; + } + /** * @brief Make a computer file size * @param string $str file size in human readable format -- GitLab From 9b4643f3865f5f14483b2e4618967f6cc91b0a22 Mon Sep 17 00:00:00 2001 From: josh4trunks Date: Thu, 3 Apr 2014 20:46:54 -0700 Subject: [PATCH 039/317] Send URI instead of filepath to NGINX for X-Accel --- lib/private/files.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/private/files.php b/lib/private/files.php index bfe6d3c02da..a377c196cdc 100644 --- a/lib/private/files.php +++ b/lib/private/files.php @@ -152,7 +152,7 @@ class OC_Files { /** @var $storage \OC\Files\Storage\Storage */ list($storage) = $view->resolvePath($filename); if ($storage->isLocal()) { - self::addSendfileHeader(\OC\Files\Filesystem::getLocalFile($filename)); + self::addSendfileHeader($filename); } else { \OC\Files\Filesystem::readfile($filename); } @@ -167,9 +167,11 @@ class OC_Files { */ private static function addSendfileHeader($filename) { if (isset($_SERVER['MOD_X_SENDFILE_ENABLED'])) { + $filename = \OC\Files\Filesystem::getLocalFile($filename); header("X-Sendfile: " . $filename); } if (isset($_SERVER['MOD_X_SENDFILE2_ENABLED'])) { + $filename = \OC\Files\Filesystem::getLocalFile($filename); if (isset($_SERVER['HTTP_RANGE']) && preg_match("/^bytes=([0-9]+)-([0-9]*)$/", $_SERVER['HTTP_RANGE'], $range)) { $filelength = filesize($filename); @@ -185,6 +187,7 @@ class OC_Files { } if (isset($_SERVER['MOD_X_ACCEL_REDIRECT_ENABLED'])) { + $filename = \OC::$WEBROOT . '/data' . \OC\Files\Filesystem::getRoot() . $filename; header("X-Accel-Redirect: " . $filename); } } -- GitLab From 4ddf5d92f24121f4fdc3af48cca17724f6f4aea6 Mon Sep 17 00:00:00 2001 From: josh4trunks Date: Sun, 23 Mar 2014 19:29:03 -0700 Subject: [PATCH 040/317] Fixes login / logout when HTTP Basic Headers are avilable. --- config/config.sample.php | 6 +++--- lib/base.php | 28 +++++++++++++++------------- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/config/config.sample.php b/config/config.sample.php index adcc175e2fa..8430b8d6539 100755 --- a/config/config.sample.php +++ b/config/config.sample.php @@ -178,12 +178,12 @@ $CONFIG = array( /* Enable or disable the logging of IP addresses in case of webform auth failures */ "log_authfailip" => false, +<<<<<<< HEAD /* Whether ownCloud should log the last successfull cron exec */ "cron_log" => true, -/* Whether http-basic username must equal username to login */ -"basic_auth" => true, - +======= +>>>>>>> Fixes login / logout when HTTP Basic Headers are avilable. /* * Configure the size in bytes log rotation should happen, 0 or false disables the rotation. * This rotates the current owncloud logfile to a new name, this way the total log usage diff --git a/lib/base.php b/lib/base.php index 15a3ec8bc8a..2141695a93d 100644 --- a/lib/base.php +++ b/lib/base.php @@ -538,17 +538,6 @@ class OC { OC_User::useBackend(new OC_User_Database()); OC_Group::useBackend(new OC_Group_Database()); - $basic_auth = OC_Config::getValue('basic_auth', true); - if ($basic_auth && isset($_SERVER['PHP_AUTH_USER']) && self::$session->exists('loginname') - && $_SERVER['PHP_AUTH_USER'] !== self::$session->get('loginname')) { - $sessionUser = self::$session->get('loginname'); - $serverUser = $_SERVER['PHP_AUTH_USER']; - OC_Log::write('core', - "Session loginname ($sessionUser) doesn't match SERVER[PHP_AUTH_USER] ($serverUser).", - OC_Log::WARN); - OC_User::logout(); - } - // Load minimum set of apps - which is filesystem, authentication and logging if (!self::checkUpgrade(false)) { OC_App::loadApps(array('authentication')); @@ -697,8 +686,10 @@ class OC { self::checkUpgrade(); } - // Test it the user is already authenticated using Apaches AuthType Basic... very usable in combination with LDAP - OC::tryBasicAuthLogin(); + if (!OC_User::isLoggedIn()) { + // Test it the user is already authenticated using Apaches AuthType Basic... very usable in combination with LDAP + OC::tryBasicAuthLogin(); + } if (!self::$CLI and (!isset($_GET["logout"]) or ($_GET["logout"] !== 'true'))) { try { @@ -749,6 +740,16 @@ class OC { if (isset($_COOKIE['oc_token'])) { OC_Preferences::deleteKey(OC_User::getUser(), 'login_token', $_COOKIE['oc_token']); } + if (isset($_SERVER['PHP_AUTH_USER'])) { + $cookie_path = OC::$WEBROOT ? : '/'; + if (isset($_COOKIE['oc_ignore_php_auth_user'])) { + // Ignore HTTP Authentication for 5 more mintues. + setcookie('oc_ignore_php_auth_user', '', time() + 300, $cookie_path); + } else { + // Ignore HTTP Aunthentication to allow a different user to log in. + setcookie('oc_ignore_php_auth_user', $_SERVER['PHP_AUTH_USER'], 0, $cookie_path); + } + } OC_User::logout(); // redirect to webroot and add slash if webroot is empty header("Location: " . OC::$WEBROOT.(empty(OC::$WEBROOT) ? '/' : '')); @@ -914,6 +915,7 @@ class OC { protected static function tryBasicAuthLogin() { if (!isset($_SERVER["PHP_AUTH_USER"]) || !isset($_SERVER["PHP_AUTH_PW"]) + || (isset($_COOKIE['oc_ignore_php_auth_user']) && $_COOKIE['oc_ignore_php_auth_user'] === $_SERVER['PHP_AUTH_USER']) ) { return false; } -- GitLab From 63df8354da7da5b7edc47432e84a9cb25de3f351 Mon Sep 17 00:00:00 2001 From: josh4trunks Date: Sun, 23 Mar 2014 20:05:06 -0700 Subject: [PATCH 041/317] Don't to set the cookie it wasn't needed. --- lib/base.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/base.php b/lib/base.php index 2141695a93d..28cc24f9287 100644 --- a/lib/base.php +++ b/lib/base.php @@ -745,7 +745,7 @@ class OC { if (isset($_COOKIE['oc_ignore_php_auth_user'])) { // Ignore HTTP Authentication for 5 more mintues. setcookie('oc_ignore_php_auth_user', '', time() + 300, $cookie_path); - } else { + } elseif ($_SERVER['PHP_AUTH_USER'] === self::$session->get('loginname')) { // Ignore HTTP Aunthentication to allow a different user to log in. setcookie('oc_ignore_php_auth_user', $_SERVER['PHP_AUTH_USER'], 0, $cookie_path); } -- GitLab From d1106f17491e3a0da623f9b325e2eaf3aa4af491 Mon Sep 17 00:00:00 2001 From: josh4trunks Date: Sun, 23 Mar 2014 21:39:29 -0700 Subject: [PATCH 042/317] cookie would be useless if value is not set --- lib/base.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/base.php b/lib/base.php index 28cc24f9287..e86894ef290 100644 --- a/lib/base.php +++ b/lib/base.php @@ -744,7 +744,7 @@ class OC { $cookie_path = OC::$WEBROOT ? : '/'; if (isset($_COOKIE['oc_ignore_php_auth_user'])) { // Ignore HTTP Authentication for 5 more mintues. - setcookie('oc_ignore_php_auth_user', '', time() + 300, $cookie_path); + setcookie('oc_ignore_php_auth_user', $_SERVER['PHP_AUTH_USER'], time() + 300, $cookie_path); } elseif ($_SERVER['PHP_AUTH_USER'] === self::$session->get('loginname')) { // Ignore HTTP Aunthentication to allow a different user to log in. setcookie('oc_ignore_php_auth_user', $_SERVER['PHP_AUTH_USER'], 0, $cookie_path); -- GitLab From a2661447504cbbf00d9f0b32159fa7311dcbc479 Mon Sep 17 00:00:00 2001 From: josh4trunks Date: Mon, 24 Mar 2014 18:46:42 -0700 Subject: [PATCH 043/317] Don't always $cookie_path, only set it when needed --- lib/base.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/base.php b/lib/base.php index e86894ef290..819e22d96fe 100644 --- a/lib/base.php +++ b/lib/base.php @@ -741,13 +741,12 @@ class OC { OC_Preferences::deleteKey(OC_User::getUser(), 'login_token', $_COOKIE['oc_token']); } if (isset($_SERVER['PHP_AUTH_USER'])) { - $cookie_path = OC::$WEBROOT ? : '/'; if (isset($_COOKIE['oc_ignore_php_auth_user'])) { // Ignore HTTP Authentication for 5 more mintues. - setcookie('oc_ignore_php_auth_user', $_SERVER['PHP_AUTH_USER'], time() + 300, $cookie_path); + setcookie('oc_ignore_php_auth_user', $_SERVER['PHP_AUTH_USER'], time() + 300, OC::$WEBROOT.(empty(OC::$WEBROOT) ? '/' : '')); } elseif ($_SERVER['PHP_AUTH_USER'] === self::$session->get('loginname')) { // Ignore HTTP Aunthentication to allow a different user to log in. - setcookie('oc_ignore_php_auth_user', $_SERVER['PHP_AUTH_USER'], 0, $cookie_path); + setcookie('oc_ignore_php_auth_user', $_SERVER['PHP_AUTH_USER'], 0, OC::$WEBROOT.(empty(OC::$WEBROOT) ? '/' : '')); } } OC_User::logout(); -- GitLab From 5b402aa846a5894bc7e290e193ab6160deec4133 Mon Sep 17 00:00:00 2001 From: josh4trunks Date: Thu, 3 Apr 2014 07:32:48 -0700 Subject: [PATCH 044/317] Fixed Typo --- lib/base.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/base.php b/lib/base.php index 819e22d96fe..b06cd3e986f 100644 --- a/lib/base.php +++ b/lib/base.php @@ -745,7 +745,7 @@ class OC { // Ignore HTTP Authentication for 5 more mintues. setcookie('oc_ignore_php_auth_user', $_SERVER['PHP_AUTH_USER'], time() + 300, OC::$WEBROOT.(empty(OC::$WEBROOT) ? '/' : '')); } elseif ($_SERVER['PHP_AUTH_USER'] === self::$session->get('loginname')) { - // Ignore HTTP Aunthentication to allow a different user to log in. + // Ignore HTTP Authentication to allow a different user to log in. setcookie('oc_ignore_php_auth_user', $_SERVER['PHP_AUTH_USER'], 0, OC::$WEBROOT.(empty(OC::$WEBROOT) ? '/' : '')); } } -- GitLab From 2d9b46e3b9dc2ceb8e21c23a905891aa9c33151e Mon Sep 17 00:00:00 2001 From: josh4trunks Date: Thu, 3 Apr 2014 22:17:31 -0700 Subject: [PATCH 045/317] Remove missed stuff from merge --- config/config.sample.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/config/config.sample.php b/config/config.sample.php index 8430b8d6539..92b534d43de 100755 --- a/config/config.sample.php +++ b/config/config.sample.php @@ -178,12 +178,9 @@ $CONFIG = array( /* Enable or disable the logging of IP addresses in case of webform auth failures */ "log_authfailip" => false, -<<<<<<< HEAD /* Whether ownCloud should log the last successfull cron exec */ "cron_log" => true, -======= ->>>>>>> Fixes login / logout when HTTP Basic Headers are avilable. /* * Configure the size in bytes log rotation should happen, 0 or false disables the rotation. * This rotates the current owncloud logfile to a new name, this way the total log usage -- GitLab From 1245ff8f318fafd66eed1ba8f9f2b3755aa537ca Mon Sep 17 00:00:00 2001 From: Fabian Henze Date: Mon, 7 Apr 2014 15:31:34 +0200 Subject: [PATCH 046/317] Add unit tests for OC_Helper::phpFileSize function --- tests/lib/helper.php | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/tests/lib/helper.php b/tests/lib/helper.php index 0943e6bc1b9..7177570d67f 100644 --- a/tests/lib/helper.php +++ b/tests/lib/helper.php @@ -30,6 +30,28 @@ class Test_Helper extends PHPUnit_Framework_TestCase { ); } + /** + * @dataProvider phpFileSizeProvider + */ + public function testPhpFileSize($expected, $input) + { + $result = OC_Helper::phpFileSize($input); + $this->assertEquals($expected, $result); + } + + public function phpFileSizeProvider() + { + return array( + array('0B', 0), + array('1K', 1024), + array('9.5M', 10000000), + array('1.3G', 1395864371), + array('465.7G', 500000000000), + array('465661.3G', 500000000000000), + array('465661287.3G', 500000000000000000), + ); + } + /** * @dataProvider computerFileSizeProvider */ -- GitLab From 3e0858e51f885badb58b4ea3a7666937b3158bff Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Wed, 9 Apr 2014 15:21:57 +0200 Subject: [PATCH 047/317] private -> protected --- core/command/db/converttype.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/core/command/db/converttype.php b/core/command/db/converttype.php index d419ca61a8b..81a89de97f8 100644 --- a/core/command/db/converttype.php +++ b/core/command/db/converttype.php @@ -145,7 +145,7 @@ class ConvertType extends Command { $this->convertDB($fromDB, $toDB, $tables, $input, $output); } - private function getToDBConnection(InputInterface $input, OutputInterface $output) { + protected function getToDBConnection(InputInterface $input, OutputInterface $output) { $type = $input->getArgument('type'); $connectionParams = array( 'host' => $input->getArgument('hostname'), @@ -160,12 +160,12 @@ class ConvertType extends Command { return $this->connectionFactory->getConnection($type, $connectionParams); } - private function getTables(Connection $db) { + protected function getTables(Connection $db) { $schemaManager = $db->getSchemaManager(); return $schemaManager->listTableNames(); } - private function copyTable(Connection $fromDB, Connection $toDB, $table, OutputInterface $output) { + protected function copyTable(Connection $fromDB, Connection $toDB, $table, OutputInterface $output) { /** @var $progress \Symfony\Component\Console\Helper\ProgressHelper */ $progress = $this->getHelperSet()->get('progress'); $query = 'SELECT COUNT(*) FROM '.$table; @@ -185,7 +185,7 @@ class ConvertType extends Command { $progress->finish(); } - private function convertDB(Connection $fromDB, Connection $toDB, array $tables, InputInterface $input, OutputInterface $output) { + protected function convertDB(Connection $fromDB, Connection $toDB, array $tables, InputInterface $input, OutputInterface $output) { $this->config->setValue('maintenance', true); $type = $input->getArgument('type'); try { @@ -216,7 +216,7 @@ class ConvertType extends Command { $this->config->setValue('maintenance', false); } - private function saveDBInfo(InputInterface $input) { + protected function saveDBInfo(InputInterface $input) { $type = $input->getArgument('type'); $username = $input->getArgument('username'); $dbhost = $input->getArgument('hostname'); -- GitLab From 03a3f668676486644a12261eba7e33f227ea960d Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Wed, 9 Apr 2014 15:45:30 +0200 Subject: [PATCH 048/317] Move schema clearing to extra method. --- core/command/db/converttype.php | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/core/command/db/converttype.php b/core/command/db/converttype.php index 81a89de97f8..7e65d1fb663 100644 --- a/core/command/db/converttype.php +++ b/core/command/db/converttype.php @@ -9,6 +9,8 @@ namespace OC\Core\Command\Db; +use Doctrine\DBAL\Schema\AbstractSchemaManager; + use OC\Config; use OC\DB\Connection; use OC\DB\ConnectionFactory; @@ -104,14 +106,7 @@ class ConvertType extends Command { $toDB = $this->getToDBConnection($input, $output); if ($input->getOption('clear-schema')) { - $schemaManager = $toDB->getSchemaManager(); - $toTables = $schemaManager->listTableNames(); - if (!empty($toTables)) { - $output->writeln('Clearing schema in new database'); - } - foreach($toTables as $table) { - $schemaManager->dropTable($table); - } + $this->clearSchema($toDB->getSchemaManager(), $input, $output); } $output->writeln('Creating schema in new database'); @@ -160,6 +155,16 @@ class ConvertType extends Command { return $this->connectionFactory->getConnection($type, $connectionParams); } + protected function clearSchema(AbstractSchemaManager $schemaManager, InputInterface $input, OutputInterface $output) { + $toTables = $schemaManager->listTableNames(); + if (!empty($toTables)) { + $output->writeln('Clearing schema in new database'); + } + foreach($toTables as $table) { + $schemaManager->dropTable($table); + } + } + protected function getTables(Connection $db) { $schemaManager = $db->getSchemaManager(); return $schemaManager->listTableNames(); -- GitLab From 5ef7d69d418ef4323cc3dc93f5ec6d24315eef96 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Wed, 9 Apr 2014 15:57:33 +0200 Subject: [PATCH 049/317] Do not attempt to covert to the same DBMS. --- core/command/db/converttype.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/core/command/db/converttype.php b/core/command/db/converttype.php index 7e65d1fb663..7e0a41b1b15 100644 --- a/core/command/db/converttype.php +++ b/core/command/db/converttype.php @@ -102,6 +102,14 @@ class ConvertType extends Command { } protected function execute(InputInterface $input, OutputInterface $output) { + if ($input->getArgument('type') === $this->config->getValue('dbtype', '')) { + $output->writeln(sprintf( + 'Can not convert from %1$s to %1$s.', + $input->getArgument('type') + )); + return 1; + } + $fromDB = \OC_DB::getConnection(); $toDB = $this->getToDBConnection($input, $output); -- GitLab From 370593361b89063d7bd65c018ccd537d0ea1c0ab Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Wed, 9 Apr 2014 16:42:22 +0200 Subject: [PATCH 050/317] Add option to create all app schemas instead of just installed app. --- core/command/db/converttype.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/core/command/db/converttype.php b/core/command/db/converttype.php index 7e0a41b1b15..f406148ebd5 100644 --- a/core/command/db/converttype.php +++ b/core/command/db/converttype.php @@ -98,6 +98,12 @@ class ConvertType extends Command { InputOption::VALUE_NONE, 'remove all tables from the destination database' ) + ->addOption( + 'all-apps', + null, + InputOption::VALUE_NONE, + 'whether to create schema for all apps instead of only installed apps' + ) ; } @@ -120,7 +126,7 @@ class ConvertType extends Command { $output->writeln('Creating schema in new database'); $schemaManager = new \OC\DB\MDB2SchemaManager($toDB); $schemaManager->createDbFromStructure(\OC::$SERVERROOT.'/db_structure.xml'); - $apps = \OC_App::getEnabledApps(); + $apps = $input->getOption('all-apps') ? \OC_App::getAllApps() : \OC_App::getEnabledApps(); foreach($apps as $app) { if(file_exists(\OC_App::getAppPath($app).'/appinfo/database.xml')) { $schemaManager->createDbFromStructure(\OC_App::getAppPath($app).'/appinfo/database.xml'); -- GitLab From 56b6504d59be62da618ad654e37faedb88f32242 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Wed, 9 Apr 2014 16:46:21 +0200 Subject: [PATCH 051/317] Extract schema creation code into its own method. --- core/command/db/converttype.php | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/core/command/db/converttype.php b/core/command/db/converttype.php index f406148ebd5..170145940d3 100644 --- a/core/command/db/converttype.php +++ b/core/command/db/converttype.php @@ -123,15 +123,7 @@ class ConvertType extends Command { $this->clearSchema($toDB->getSchemaManager(), $input, $output); } - $output->writeln('Creating schema in new database'); - $schemaManager = new \OC\DB\MDB2SchemaManager($toDB); - $schemaManager->createDbFromStructure(\OC::$SERVERROOT.'/db_structure.xml'); - $apps = $input->getOption('all-apps') ? \OC_App::getAllApps() : \OC_App::getEnabledApps(); - foreach($apps as $app) { - if(file_exists(\OC_App::getAppPath($app).'/appinfo/database.xml')) { - $schemaManager->createDbFromStructure(\OC_App::getAppPath($app).'/appinfo/database.xml'); - } - } + $this->createSchema($toDB, $input, $output); $toTables = $this->getTables($toDB); $fromTables = $this->getTables($fromDB); @@ -154,6 +146,18 @@ class ConvertType extends Command { $this->convertDB($fromDB, $toDB, $tables, $input, $output); } + protected function createSchema(Connection $toDB, InputInterface $input, OutputInterface $output) { + $output->writeln('Creating schema in new database'); + $schemaManager = new \OC\DB\MDB2SchemaManager($toDB); + $schemaManager->createDbFromStructure(\OC::$SERVERROOT.'/db_structure.xml'); + $apps = $input->getOption('all-apps') ? \OC_App::getAllApps() : \OC_App::getEnabledApps(); + foreach($apps as $app) { + if (file_exists(\OC_App::getAppPath($app).'/appinfo/database.xml')) { + $schemaManager->createDbFromStructure(\OC_App::getAppPath($app).'/appinfo/database.xml'); + } + } + } + protected function getToDBConnection(InputInterface $input, OutputInterface $output) { $type = $input->getArgument('type'); $connectionParams = array( -- GitLab From b10bf72999984d1f6c775fbeb0119c66c0fc38f7 Mon Sep 17 00:00:00 2001 From: jbtbnl Date: Thu, 10 Apr 2014 00:33:55 +0200 Subject: [PATCH 052/317] Vertically align public layout to better fit small mobile screens --- core/css/styles.css | 17 ++++++++++++++++- core/templates/layout.guest.php | 13 +++++++------ 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/core/css/styles.css b/core/css/styles.css index 57e2c4479a1..2f67fa07c8c 100644 --- a/core/css/styles.css +++ b/core/css/styles.css @@ -327,7 +327,7 @@ input[type="submit"].enabled { /* Some whitespace to the top */ #body-login #header { - padding-top: 100px; + padding-top: 10px; } /* Fix background gradient */ #body-login { @@ -637,6 +637,21 @@ label.infield { cursor:text !important; top:1.05em; left:.85em; } min-height: 100%; margin: 0 auto -70px; width: 300px; + + display: -webkit-box; + -webkit-box-orient: horizontal; + -webkit-box-pack: center; + -webkit-box-align: center; + + display: -moz-box; + -moz-box-orient: horizontal; + -moz-box-pack: center; + -moz-box-align: center; + + display: box; + box-orient: horizontal; + box-pack: center; + box-align: center; } #body-login footer, #body-login .push { height: 70px; diff --git a/core/templates/layout.guest.php b/core/templates/layout.guest.php index 5788d1d5bd3..a6d8d93533a 100644 --- a/core/templates/layout.guest.php +++ b/core/templates/layout.guest.php @@ -35,14 +35,15 @@
-
- - +
+
+
+