diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/base.php | 4 | ||||
-rw-r--r-- | lib/l10n/fr.php | 1 | ||||
-rw-r--r-- | lib/private/appframework/core/api.php | 7 | ||||
-rw-r--r-- | lib/private/appframework/routing/routeconfig.php | 6 | ||||
-rw-r--r-- | lib/private/db/adapter.php | 11 | ||||
-rw-r--r-- | lib/private/db/adaptersqlite.php | 14 | ||||
-rw-r--r-- | lib/private/eventsource.php | 93 | ||||
-rw-r--r-- | lib/private/files.php | 2 | ||||
-rw-r--r-- | lib/private/files/cache/scanner.php | 23 | ||||
-rw-r--r-- | lib/private/files/objectstore/objectstorestorage.php | 38 | ||||
-rw-r--r-- | lib/private/files/utils/scanner.php | 12 | ||||
-rw-r--r-- | lib/private/helper.php | 12 | ||||
-rw-r--r-- | lib/private/preview/office-cl.php | 2 | ||||
-rw-r--r-- | lib/private/server.php | 9 | ||||
-rw-r--r-- | lib/private/share/constants.php | 2 | ||||
-rw-r--r-- | lib/private/share/mailnotifications.php | 2 | ||||
-rw-r--r-- | lib/private/share/share.php | 5 | ||||
-rw-r--r-- | lib/private/template/functions.php | 50 | ||||
-rwxr-xr-x | lib/private/util.php | 4 | ||||
-rw-r--r-- | lib/public/ieventsource.php | 34 | ||||
-rw-r--r-- | lib/public/iservercontainer.php | 7 |
21 files changed, 235 insertions, 103 deletions
diff --git a/lib/base.php b/lib/base.php index fb445124011..5d52db68cb7 100644 --- a/lib/base.php +++ b/lib/base.php @@ -554,7 +554,9 @@ class OC { OC_Group::useBackend(new OC_Group_Database()); //setup extra user backends - OC_User::setupBackends(); + if (!self::checkUpgrade(false)) { + OC_User::setupBackends(); + } self::registerCacheHooks(); self::registerFilesystemHooks(); diff --git a/lib/l10n/fr.php b/lib/l10n/fr.php index ae49d583336..3f1fe6a9925 100644 --- a/lib/l10n/fr.php +++ b/lib/l10n/fr.php @@ -97,6 +97,7 @@ $TRANSLATIONS = array( "Cannot create \"data\" directory (%s)" => "Impossible de créer le répertoire \"data\" (%s)", "This can usually be fixed by <a href=\"%s\" target=\"_blank\">giving the webserver write access to the root directory</a>." => "Ce problème est généralement résolu <a href=\"%s\" target=\"_blank\">en donnant au serveur web un accès en écriture au répertoire racine</a>.", "Setting locale to %s failed" => "Le choix de la langue pour %s a échoué", +"Please install one of these locales on your system and restart your webserver." => "Veuillez installer l'une de ces langues sur votre système et redémarrer votre serveur web.", "Please ask your server administrator to install the module." => "Veuillez demander à votre administrateur d’installer le module.", "PHP module %s not installed." => "Le module PHP %s n’est pas installé.", "PHP %s or higher is required." => "PHP %s ou supérieur est requis.", diff --git a/lib/private/appframework/core/api.php b/lib/private/appframework/core/api.php index ba6b9f95cb2..279f4bf97f7 100644 --- a/lib/private/appframework/core/api.php +++ b/lib/private/appframework/core/api.php @@ -110,12 +110,11 @@ class API implements IApi{ /** - * used to return and open a new eventsource - * @return \OC_EventSource a new open EventSource class + * used to return and open a new event source + * @return \OCP\IEventSource a new open EventSource class */ public function openEventSource(){ - # TODO: use public api - return new \OC_EventSource(); + return \OC::$server->createEventSource(); } /** diff --git a/lib/private/appframework/routing/routeconfig.php b/lib/private/appframework/routing/routeconfig.php index 5b4d411a355..91687b9c83c 100644 --- a/lib/private/appframework/routing/routeconfig.php +++ b/lib/private/appframework/routing/routeconfig.php @@ -93,6 +93,12 @@ class RouteConfig { if(array_key_exists('requirements', $simpleRoute)) { $router->requirements($simpleRoute['requirements']); } + + // optionally register defaults for route. This is used to + // tell the route parser how url parameters should be default valued + if(array_key_exists('defaults', $simpleRoute)) { + $router->defaults($simpleRoute['defaults']); + } } } diff --git a/lib/private/db/adapter.php b/lib/private/db/adapter.php index 975b9432286..6742ccdbb45 100644 --- a/lib/private/db/adapter.php +++ b/lib/private/db/adapter.php @@ -51,13 +51,18 @@ class Adapter { . str_repeat('?,', count($input)-1).'? ' // Is there a prettier alternative? . 'FROM `' . $table . '` WHERE '; + $inserts = array_values($input); foreach($input as $key => $value) { - $query .= '`' . $key . '` = ? AND '; + $query .= '`' . $key . '`'; + if (is_null($value)) { + $query .= ' IS NULL AND '; + } else { + $inserts[] = $value; + $query .= ' = ? AND '; + } } $query = substr($query, 0, strlen($query) - 5); $query .= ' HAVING COUNT(*) = 0'; - $inserts = array_values($input); - $inserts = array_merge($inserts, $inserts); try { return $this->conn->executeUpdate($query, $inserts); diff --git a/lib/private/db/adaptersqlite.php b/lib/private/db/adaptersqlite.php index fa6d308ae32..5b9c5a437da 100644 --- a/lib/private/db/adaptersqlite.php +++ b/lib/private/db/adaptersqlite.php @@ -21,13 +21,21 @@ class AdapterSqlite extends Adapter { // NOTE: For SQLite we have to use this clumsy approach // otherwise all fieldnames used must have a unique key. $query = 'SELECT COUNT(*) FROM `' . $table . '` WHERE '; - foreach($input as $key => $value) { - $query .= '`' . $key . '` = ? AND '; + $inserts = array(); + foreach ($input as $key => $value) { + $query .= '`' . $key . '`'; + if (is_null($value)) { + $query .= ' IS NULL AND '; + } else { + $inserts[] = $value; + $query .= ' = ? AND '; + } } $query = substr($query, 0, strlen($query) - 5); + try { $stmt = $this->conn->prepare($query); - $result = $stmt->execute(array_values($input)); + $result = $stmt->execute($inserts); } catch(\Doctrine\DBAL\DBALException $e) { $entry = 'DB Error: "'.$e->getMessage() . '"<br />'; $entry .= 'Offending command was: ' . $query . '<br />'; diff --git a/lib/private/eventsource.php b/lib/private/eventsource.php index 192c1446b5a..53947f3a2f2 100644 --- a/lib/private/eventsource.php +++ b/lib/private/eventsource.php @@ -1,25 +1,10 @@ <?php - /** -* ownCloud -* -* @author Robin Appelman -* @copyright 2012 Robin Appelman icewind1991@gmail.com -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the License, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU AFFERO GENERAL PUBLIC LICENSE for more details. -* -* You should have received a copy of the GNU Affero General Public -* License along with this library. If not, see <http://www.gnu.org/licenses/>. -* -*/ + * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com> + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ /** * wrapper for server side events (http://en.wikipedia.org/wiki/Server-sent_events) @@ -27,51 +12,73 @@ * * use server side events with caution, to many open requests can hang the server */ -class OC_EventSource{ +class OC_EventSource implements \OCP\IEventSource { + /** + * @var bool + */ private $fallback; - private $fallBackId=0; - public function __construct() { + /** + * @var int + */ + private $fallBackId = 0; + + /** + * @var bool + */ + private $started = false; + + protected function init() { + if ($this->started) { + return; + } + $this->started = true; + + // prevent php output buffering, caching and nginx buffering OC_Util::obEnd(); header('Cache-Control: no-cache'); header('X-Accel-Buffering: no'); - $this->fallback=isset($_GET['fallback']) and $_GET['fallback']=='true'; - if($this->fallback) { - $this->fallBackId=$_GET['fallback_id']; + $this->fallback = isset($_GET['fallback']) and $_GET['fallback'] == 'true'; + if ($this->fallback) { + $this->fallBackId = (int)$_GET['fallback_id']; header("Content-Type: text/html"); - echo str_repeat('<span></span>'.PHP_EOL, 10); //dummy data to keep IE happy - }else{ + echo str_repeat('<span></span>' . PHP_EOL, 10); //dummy data to keep IE happy + } else { header("Content-Type: text/event-stream"); } - if( !OC_Util::isCallRegistered()) { + if (!OC_Util::isCallRegistered()) { $this->send('error', 'Possible CSRF attack. Connection will be closed.'); $this->close(); exit(); } flush(); - } /** * send a message to the client + * * @param string $type * @param mixed $data * + * @throws \BadMethodCallException * if only one parameter is given, a typeless message will be send with that parameter as data */ - public function send($type, $data=null) { - if(is_null($data)) { - $data=$type; - $type=null; + public function send($type, $data = null) { + if ($data and !preg_match('/^[A-Za-z0-9_]+$/', $type)) { + throw new BadMethodCallException('Type needs to be alphanumeric ('. $type .')'); + } + $this->init(); + if (is_null($data)) { + $data = $type; + $type = null; } - if($this->fallback) { - $fallBackId = OC_Util::sanitizeHTML($this->fallBackId); - $response='<script type="text/javascript">window.parent.OC.EventSource.fallBackCallBack(' - .$fallBackId.',"' . $type . '",' . OCP\JSON::encode($data) . ')</script>' . PHP_EOL; + if ($this->fallback) { + $response = '<script type="text/javascript">window.parent.OC.EventSource.fallBackCallBack(' + . $this->fallBackId . ',"' . $type . '",' . OCP\JSON::encode($data) . ')</script>' . PHP_EOL; echo $response; - }else{ - if($type) { - echo 'event: ' . $type.PHP_EOL; + } else { + if ($type) { + echo 'event: ' . $type . PHP_EOL; } echo 'data: ' . OCP\JSON::encode($data) . PHP_EOL; } @@ -80,9 +87,9 @@ class OC_EventSource{ } /** - * close the connection of the even source + * close the connection of the event source */ public function close() { - $this->send('__internal__', 'close');//server side closing can be an issue, let the client do it + $this->send('__internal__', 'close'); //server side closing can be an issue, let the client do it } } diff --git a/lib/private/files.php b/lib/private/files.php index 739dae64180..06fc2dc9109 100644 --- a/lib/private/files.php +++ b/lib/private/files.php @@ -49,7 +49,7 @@ class OC_Files { header('Content-Type: application/zip'); } else { $filesize = \OC\Files\Filesystem::filesize($filename); - header('Content-Type: '.\OC\Files\Filesystem::getMimeType($filename)); + header('Content-Type: '.\OC_Helper::getSecureMimeType(\OC\Files\Filesystem::getMimeType($filename))); if ($filesize > -1) { header("Content-Length: ".$filesize); } diff --git a/lib/private/files/cache/scanner.php b/lib/private/files/cache/scanner.php index 2d87871fd89..dfba2d920a0 100644 --- a/lib/private/files/cache/scanner.php +++ b/lib/private/files/cache/scanner.php @@ -44,6 +44,11 @@ class Scanner extends BasicEmitter { */ protected $cacheActive; + /** + * @var bool $useTransactions whether to use transactions + */ + protected $useTransactions = true; + const SCAN_RECURSIVE = true; const SCAN_SHALLOW = false; @@ -58,6 +63,16 @@ class Scanner extends BasicEmitter { } /** + * Whether to wrap the scanning of a folder in a database transaction + * On default transactions are used + * + * @param bool $useTransactions + */ + public function setUseTransactions($useTransactions) { + $this->useTransactions = $useTransactions; + } + + /** * get all the metadata of a file or folder * * * @@ -234,7 +249,9 @@ class Scanner extends BasicEmitter { $newChildren = array(); if ($this->storage->is_dir($path) && ($dh = $this->storage->opendir($path))) { $exceptionOccurred = false; - \OC_DB::beginTransaction(); + if ($this->useTransactions) { + \OC_DB::beginTransaction(); + } if (is_resource($dh)) { while (($file = readdir($dh)) !== false) { $child = ($path) ? $path . '/' . $file : $file; @@ -266,7 +283,9 @@ class Scanner extends BasicEmitter { $child = ($path) ? $path . '/' . $childName : $childName; $this->removeFromCache($child); } - \OC_DB::commit(); + if ($this->useTransactions) { + \OC_DB::commit(); + } if ($exceptionOccurred) { // It might happen that the parallel scan process has already // inserted mimetypes but those weren't available yet inside the transaction diff --git a/lib/private/files/objectstore/objectstorestorage.php b/lib/private/files/objectstore/objectstorestorage.php index 0292d777064..241864bcccd 100644 --- a/lib/private/files/objectstore/objectstorestorage.php +++ b/lib/private/files/objectstore/objectstorestorage.php @@ -82,7 +82,7 @@ class ObjectStoreStorage extends \OC\Files\Storage\Common { $parentExists = true; // we are done when the root folder was meant to be created - if ($dirName === $path) { + if ($dirName === $path) { return true; } } @@ -290,38 +290,10 @@ class ObjectStoreStorage extends \OC\Files\Storage\Common { public function rename($source, $target) { $source = $this->normalizePath($source); $target = $this->normalizePath($target); - $stat1 = $this->stat($source); - if (isset($stat1['mimetype']) && $stat1['mimetype'] === 'httpd/unix-directory') { - $this->remove($target); - $dir = $this->opendir($source); - $this->mkdir($target); - while ($file = readdir($dir)) { - if (!Filesystem::isIgnoredDir($file)) { - if (!$this->rename($source . '/' . $file, $target . '/' . $file)) { - return false; - } - } - } - closedir($dir); - $this->remove($source); - return true; - } else { - if (is_array($stat1)) { - $parent = $this->stat(dirname($target)); - if (is_array($parent)) { - $this->remove($target); - $stat1['parent'] = $parent['fileid']; - $stat1['path'] = $target; - $stat1['path_hash'] = md5($target); - $stat1['name'] = \OC_Util::basename($target); - $stat1['mtime'] = time(); - $stat1['etag'] = $this->getETag($target); - $this->getCache()->update($stat1['fileid'], $stat1); - return true; - } - } - } - return false; + $this->remove($target); + $this->getCache()->move($source, $target); + $this->touch(dirname($target)); + return true; } public function getMimeType($path) { diff --git a/lib/private/files/utils/scanner.php b/lib/private/files/utils/scanner.php index c2fabf51946..c7da4505af5 100644 --- a/lib/private/files/utils/scanner.php +++ b/lib/private/files/utils/scanner.php @@ -35,11 +35,18 @@ class Scanner extends PublicEmitter { protected $propagator; /** + * @var \OCP\IDBConnection + */ + protected $db; + + /** * @param string $user + * @param \OCP\IDBConnection $db */ - public function __construct($user) { + public function __construct($user, $db) { $this->user = $user; $this->propagator = new ChangePropagator(new View('')); + $this->db = $db; } /** @@ -121,8 +128,11 @@ class Scanner extends PublicEmitter { throw new ForbiddenException(); } $scanner = $storage->getScanner(); + $scanner->useTransactions(false); $this->attachListener($mount); + $this->db->beginTransaction(); $scanner->scan('', \OC\Files\Cache\Scanner::SCAN_RECURSIVE, \OC\Files\Cache\Scanner::REUSE_ETAG | \OC\Files\Cache\Scanner::REUSE_SIZE); + $this->db->commit(); } $this->propagator->propagateChanges(time()); } diff --git a/lib/private/helper.php b/lib/private/helper.php index 7c1edd1b058..f696b5a8900 100644 --- a/lib/private/helper.php +++ b/lib/private/helper.php @@ -129,12 +129,12 @@ class OC_Helper { * Returns a absolute url to the given service. */ public static function linkToPublic($service, $add_slash = false) { - return OC::$server->getURLGenerator()->getAbsoluteURL( - self::linkTo( - '', 'public.php') . '?service=' . $service - . (($add_slash && $service[strlen($service) - 1] != '/') ? '/' : '' - ) - ); + if ($service === 'files') { + $url = OC::$server->getURLGenerator()->getAbsoluteURL('/s'); + } else { + $url = OC::$server->getURLGenerator()->getAbsoluteURL(self::linkTo('', 'public.php').'?service='.$service); + } + return $url . (($add_slash && $service[strlen($service) - 1] != '/') ? '/' : ''); } /** diff --git a/lib/private/preview/office-cl.php b/lib/private/preview/office-cl.php index 81e0cf4b6ae..42d2cbf34fc 100644 --- a/lib/private/preview/office-cl.php +++ b/lib/private/preview/office-cl.php @@ -29,7 +29,7 @@ if (!\OC_Util::runningOnWindows()) { $tmpDir = get_temp_dir(); - $defaultParameters = ' -env:UserInstallation=file://' . escapeshellarg($tmpDir) . ' --headless --nologo --nofirststartwizard --invisible --norestore -convert-to pdf -outdir '; + $defaultParameters = ' -env:UserInstallation=file://' . escapeshellarg($tmpDir . '/owncloud-' . \OC_Util::getInstanceId().'/') . ' --headless --nologo --nofirststartwizard --invisible --norestore -convert-to pdf -outdir '; $clParameters = \OCP\Config::getSystemValue('preview_office_cl_parameters', $defaultParameters); $exec = $this->cmd . $clParameters . escapeshellarg($tmpDir) . ' ' . escapeshellarg($absPath); diff --git a/lib/private/server.php b/lib/private/server.php index 71a098f9074..912d5c4f635 100644 --- a/lib/private/server.php +++ b/lib/private/server.php @@ -518,4 +518,13 @@ class Server extends SimpleContainer implements IServerContainer { } return new CertificateManager($user); } + + /** + * Create a new event source + * + * @return \OCP\IEventSource + */ + function createEventSource() { + return new \OC_EventSource(); + } } diff --git a/lib/private/share/constants.php b/lib/private/share/constants.php index 4c398c43c2d..798327cc154 100644 --- a/lib/private/share/constants.php +++ b/lib/private/share/constants.php @@ -34,7 +34,7 @@ class Constants { const FORMAT_STATUSES = -2; const FORMAT_SOURCES = -3; // ToDo Check if it is still in use otherwise remove it - const TOKEN_LENGTH = 32; // see db_structure.xml + const TOKEN_LENGTH = 15; // old (oc7) length is 32, keep token length in db at least that for compatibility protected static $shareTypeUserAndGroups = -1; protected static $shareTypeGroupUserUnique = 2; diff --git a/lib/private/share/mailnotifications.php b/lib/private/share/mailnotifications.php index 4a92503bdd3..2f704fb2b3c 100644 --- a/lib/private/share/mailnotifications.php +++ b/lib/private/share/mailnotifications.php @@ -52,7 +52,7 @@ class MailNotifications { * @param string $sender user id (if nothing is set we use the currently logged-in user) */ public function __construct($sender = null) { - $this->l = \OC::$server->getL10N('core'); + $this->l = \OC::$server->getL10N('lib'); $this->senderId = $sender; diff --git a/lib/private/share/share.php b/lib/private/share/share.php index e2e9b94125e..8441e6a94c4 100644 --- a/lib/private/share/share.php +++ b/lib/private/share/share.php @@ -640,7 +640,10 @@ class Share extends \OC\Share\Constants { if (isset($oldToken)) { $token = $oldToken; } else { - $token = \OC_Util::generateRandomBytes(self::TOKEN_LENGTH); + $token = \OC::$server->getSecureRandom()->getMediumStrengthGenerator()->generate(self::TOKEN_LENGTH, + \OCP\Security\ISecureRandom::CHAR_LOWER.\OCP\Security\ISecureRandom::CHAR_UPPER. + \OCP\Security\ISecureRandom::CHAR_DIGITS + ); } $result = self::put($itemType, $itemSource, $shareType, $shareWith, $uidOwner, $permissions, null, $token, $itemSourceName, $expirationDate); diff --git a/lib/private/template/functions.php b/lib/private/template/functions.php index 3cbf0d9748f..cbe751e59b5 100644 --- a/lib/private/template/functions.php +++ b/lib/private/template/functions.php @@ -24,6 +24,56 @@ function print_unescaped($string) { } /** + * Shortcut for adding scripts to a page + * @param string $app the appname + * @param string|string[] $file the filename, + * if an array is given it will add all scripts + */ +function script($app, $file) { + if(is_array($file)) { + foreach($file as $f) { + OC_Util::addScript($app, $f); + } + } else { + OC_Util::addScript($app, $file); + } +} + +/** + * Shortcut for adding styles to a page + * @param string $app the appname + * @param string|string[] $file the filename, + * if an array is given it will add all styles + */ +function style($app, $file) { + if(is_array($file)) { + foreach($file as $f) { + OC_Util::addStyle($app, $f); + } + } else { + OC_Util::addStyle($app, $file); + } +} + +/** + * Shortcut for HTML imports + * @param string $app the appname + * @param string|string[] $file the path relative to the app's component folder, + * if an array is given it will add all components + */ +function component($app, $file) { + if(is_array($file)) { + foreach($file as $f) { + $url = link_to($app, 'component/' . $f . '.html'); + OC_Util::addHeader('link', array('rel' => 'import', 'href' => $url)); + } + } else { + $url = link_to($app, 'component/' . $file . '.html'); + OC_Util::addHeader('link', array('rel' => 'import', 'href' => $url)); + } +} + +/** * make OC_Helper::linkTo available as a simple function * @param string $app app * @param string $file file diff --git a/lib/private/util.php b/lib/private/util.php index 6f45e00215d..a130d997ca3 100755 --- a/lib/private/util.php +++ b/lib/private/util.php @@ -760,8 +760,8 @@ class OC_Util { foreach ($errors as $value) { $parameters[$value] = true; } - if (!empty($_POST['user'])) { - $parameters["username"] = $_POST['user']; + if (!empty($_REQUEST['user'])) { + $parameters["username"] = $_REQUEST['user']; $parameters['user_autofocus'] = false; } else { $parameters["username"] = ''; diff --git a/lib/public/ieventsource.php b/lib/public/ieventsource.php new file mode 100644 index 00000000000..eb7853c5e90 --- /dev/null +++ b/lib/public/ieventsource.php @@ -0,0 +1,34 @@ +<?php +/** + * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com> + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OCP; + +/** + * wrapper for server side events (http://en.wikipedia.org/wiki/Server-sent_events) + * includes a fallback for older browsers and IE + * + * use server side events with caution, to many open requests can hang the server + * + * The event source will initialize the connection to the client when the first data is sent + */ +interface IEventSource { + /** + * send a message to the client + * + * @param string $type + * @param mixed $data + * + * if only one parameter is given, a typeless message will be send with that parameter as data + */ + public function send($type, $data = null); + + /** + * close the connection of the event source + */ + public function close(); +} diff --git a/lib/public/iservercontainer.php b/lib/public/iservercontainer.php index 60b0b497c54..1abf0d9938d 100644 --- a/lib/public/iservercontainer.php +++ b/lib/public/iservercontainer.php @@ -235,4 +235,11 @@ interface IServerContainer { * @return \OCP\ICertificateManager */ function getCertificateManager($user = null); + + /** + * Create a new event source + * + * @return \OCP\IEventSource + */ + function createEventSource(); } |